From 09e98bfc299db6d5adba58042fc5822d2fdc7d57 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sat, 17 Oct 2020 17:48:43 +0800 Subject: [PATCH] add recovery/request log middleware file --- pkg/middlewares/recovery.go | 97 ++++++++++++++++++++++++++++++++++ pkg/middlewares/request_log.go | 44 +++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 pkg/middlewares/recovery.go create mode 100644 pkg/middlewares/request_log.go diff --git a/pkg/middlewares/recovery.go b/pkg/middlewares/recovery.go new file mode 100644 index 00000000..af091f88 --- /dev/null +++ b/pkg/middlewares/recovery.go @@ -0,0 +1,97 @@ +package middlewares + +import ( + "bytes" + "fmt" + "io/ioutil" + "runtime" + + "github.com/mayswind/lab/pkg/core" + "github.com/mayswind/lab/pkg/errs" + "github.com/mayswind/lab/pkg/log" + "github.com/mayswind/lab/pkg/utils" +) + +var ( + dunno = []byte("???") + centerDot = []byte("ยท") + dot = []byte(".") + slash = []byte("/") +) + +func Recovery(c *core.Context) { + defer func() { + if err := recover(); err != nil { + stack := stack(3) + + log.ErrorfWithRequestIdAndExtra(c, string(stack), "System Error! because %s", err) + utils.PrintErrorResult(c, errs.ErrSystemError) + } + }() + + c.Next() +} + +// The following code is from recovery.go of gin + +func stack(skip int) []byte { + buf := new(bytes.Buffer) + var lines [][]byte + var lastFile string + + for i := skip; ; i++ { + pc, file, line, ok := runtime.Caller(i) + if !ok { + break + } + + fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc) + + if file != lastFile { + data, err := ioutil.ReadFile(file) + + if err != nil { + continue + } + + lines = bytes.Split(data, []byte{'\n'}) + lastFile = file + } + + fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line)) + } + + return buf.Bytes() +} + +func source(lines [][]byte, n int) []byte { + n-- + + if n < 0 || n >= len(lines) { + return dunno + } + + return bytes.TrimSpace(lines[n]) +} + +func function(pc uintptr) []byte { + fn := runtime.FuncForPC(pc) + + if fn == nil { + return dunno + } + + name := []byte(fn.Name()) + + if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 { + name = name[lastslash+1:] + } + + if period := bytes.Index(name, dot); period >= 0 { + name = name[period+1:] + } + + name = bytes.Replace(name, centerDot, dot, -1) + + return name +} diff --git a/pkg/middlewares/request_log.go b/pkg/middlewares/request_log.go new file mode 100644 index 00000000..40654cb9 --- /dev/null +++ b/pkg/middlewares/request_log.go @@ -0,0 +1,44 @@ +package middlewares + +import ( + "time" + + "github.com/mayswind/lab/pkg/core" + "github.com/mayswind/lab/pkg/log" +) + +func RequestLog(c *core.Context) { + start := time.Now() + path := c.Request.URL.Path + query := c.Request.URL.RawQuery + + c.Next() + + now := time.Now() + + statusCode := c.Writer.Status() + errorCode := 0 + + userId := "-" + claims := c.GetTokenClaims() + err := c.GetResponseError() + + clientIP := c.ClientIP() + method := c.Request.Method + + if claims != nil { + userId = claims.Id + } + + if err != nil { + errorCode = err.Code() + } + + if query != "" { + path = path + "?" + query + } + + cost := now.Sub(start).Nanoseconds() / 1e6 + + log.Requestf(c, "%d %d %s %s %s %s %dms", statusCode, errorCode, userId, clientIP, method, path, cost) +}