logger.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package middlewares
  2. import (
  3. "bytes"
  4. "io"
  5. "time"
  6. "github.com/gin-gonic/gin"
  7. "github.com/spf13/cast"
  8. "go.uber.org/zap"
  9. "github.com/runningwater/gohub/pkg/helpers"
  10. "github.com/runningwater/gohub/pkg/logger"
  11. )
  12. type responseBodyWriter struct {
  13. gin.ResponseWriter
  14. body *bytes.Buffer
  15. }
  16. func (r responseBodyWriter) Write(b []byte) (int, error) {
  17. r.body.Write(b)
  18. return r.ResponseWriter.Write(b)
  19. }
  20. // Logger 记录请求日志
  21. func Logger() gin.HandlerFunc {
  22. return func(c *gin.Context) {
  23. // 获取 response 内容
  24. w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
  25. c.Writer = w
  26. // 获取请求数据
  27. var requestBody []byte
  28. if c.Request.Body != nil {
  29. // 读取 c.Request.Body 内容
  30. requestBody, _ = io.ReadAll(c.Request.Body)
  31. // 重新赋值 c.Request.Body ,以供后续的其他方法读取
  32. c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
  33. }
  34. // 设置开始时间
  35. start := time.Now()
  36. c.Next()
  37. // 开始记录日志的逻辑
  38. cost := time.Since(start)
  39. responseStatus := c.Writer.Status()
  40. logFields := []zap.Field{
  41. zap.Int("status", responseStatus),
  42. zap.String("request", c.Request.Method+c.Request.URL.String()),
  43. zap.String("query", c.Request.URL.RawQuery),
  44. zap.String("ip", c.ClientIP()),
  45. zap.String("user-agent", c.Request.UserAgent()),
  46. zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
  47. zap.String("time", helpers.MicrosecondsStr(cost)),
  48. }
  49. // Body 内容
  50. if c.Request.Method == "POST" || c.Request.Method == "PUT" || c.Request.Method == "DELETE" {
  51. logFields = append(logFields, zap.String("RequestBody", string(requestBody)))
  52. logFields = append(logFields, zap.String("ResponseBody", w.body.String()))
  53. }
  54. if responseStatus > 400 && responseStatus < 500 {
  55. // 403 404 等客户端错误,使用 Warn 级别
  56. logger.Warn("HTTP Warning "+cast.ToString(responseStatus), logFields...)
  57. } else if responseStatus >= 500 && responseStatus < 600 {
  58. logger.Error("HTTP Error "+cast.ToString(responseStatus), logFields...)
  59. } else {
  60. logger.Debug("HTTP Access Log", logFields...)
  61. }
  62. }
  63. }