|
|
@@ -0,0 +1,76 @@
|
|
|
+package middlewares
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "io"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "github.com/runningwater/gohub/pkg/helpers"
|
|
|
+ "github.com/runningwater/gohub/pkg/logger"
|
|
|
+ "github.com/spf13/cast"
|
|
|
+ "go.uber.org/zap"
|
|
|
+)
|
|
|
+
|
|
|
+type responseBodyWriter struct {
|
|
|
+ gin.ResponseWriter
|
|
|
+ body *bytes.Buffer
|
|
|
+}
|
|
|
+
|
|
|
+func (r responseBodyWriter) Write(b []byte) (int, error) {
|
|
|
+ r.body.Write(b)
|
|
|
+ return r.ResponseWriter.Write(b)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Logger 记录请求日志
|
|
|
+func Logger() gin.HandlerFunc {
|
|
|
+ return func(c *gin.Context) {
|
|
|
+
|
|
|
+ // 获取 response 内容
|
|
|
+ w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
|
|
|
+ c.Writer = w
|
|
|
+
|
|
|
+ // 获取请求数据
|
|
|
+ var requestBody []byte
|
|
|
+ if c.Request.Body != nil {
|
|
|
+ // 读取 c.Request.Body 内容
|
|
|
+ requestBody, _ = io.ReadAll(c.Request.Body)
|
|
|
+ // 重新赋值 c.Request.Body ,以供后续的其他方法读取
|
|
|
+ c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置开始时间
|
|
|
+ start := time.Now()
|
|
|
+ c.Next()
|
|
|
+
|
|
|
+ // 开始记录日志的逻辑
|
|
|
+ cost := time.Since(start)
|
|
|
+ responStatus := c.Writer.Status()
|
|
|
+
|
|
|
+ logFields := []zap.Field{
|
|
|
+ zap.Int("status", responStatus),
|
|
|
+ zap.String("request", c.Request.Method+c.Request.URL.String()),
|
|
|
+ zap.String("query", c.Request.URL.RawQuery),
|
|
|
+ zap.String("ip", c.ClientIP()),
|
|
|
+ zap.String("user-agent", c.Request.UserAgent()),
|
|
|
+ zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
|
|
|
+ zap.String("time", helpers.MicrosecondsStr(cost)),
|
|
|
+ }
|
|
|
+
|
|
|
+ // Body 内容
|
|
|
+ if c.Request.Method == "POST" || c.Request.Method == "PUT" || c.Request.Method == "DELETE" {
|
|
|
+ logFields = append(logFields, zap.String("RequestBody", string(requestBody)))
|
|
|
+ logFields = append(logFields, zap.String("ResponseBody", w.body.String()))
|
|
|
+ }
|
|
|
+
|
|
|
+ if responStatus > 400 && responStatus < 500 {
|
|
|
+ // 403 404 等客户端错误,使用 Warn 级别
|
|
|
+ logger.Warn("HTTP Warning "+ cast.ToString(responStatus), logFields...)
|
|
|
+ } else if responStatus >= 500 && responStatus < 600 {
|
|
|
+ logger.Error("HTTP Error "+ cast.ToString(responStatus), logFields...)
|
|
|
+ } else {
|
|
|
+ logger.Debug("HTTP Access Log", logFields...)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|