user_logger.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package middleware
  2. import (
  3. "app/commons/core"
  4. "app/commons/model/entity"
  5. "bytes"
  6. "fmt"
  7. "github.com/gin-gonic/gin"
  8. "io"
  9. "strings"
  10. "time"
  11. )
  12. func UserLogger() gin.HandlerFunc {
  13. return func(c *gin.Context) {
  14. // 开始时间
  15. start := time.Now()
  16. // 记录请求信息
  17. clientIP := c.ClientIP()
  18. method := c.Request.Method
  19. path := c.Request.URL.Path
  20. query := c.Request.URL.RawQuery
  21. // 读取请求体
  22. var requestBody []byte
  23. var requestBodyStr string
  24. contentType := c.Request.Header.Get("Content-Type")
  25. // 检查是否为文件上传请求(multipart/form-data)
  26. isFileUpload := strings.Contains(contentType, "multipart/form-data")
  27. if c.Request.Body != nil {
  28. requestBody, _ = io.ReadAll(c.Request.Body)
  29. // 读取后重新赋值,因为读取后body会被清空
  30. c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
  31. }
  32. // 文件上传请求不记录请求体(避免二进制数据存储问题)
  33. if isFileUpload {
  34. requestBodyStr = "[file upload]"
  35. } else {
  36. requestBodyStr = string(requestBody)
  37. }
  38. // 创建一个自定义的 ResponseWriter 来捕获响应
  39. blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
  40. c.Writer = blw
  41. c.Next()
  42. // 在请求结束时记录日志
  43. elapsed := time.Since(start)
  44. core.Log.Infof("GIN|%d|%s|IP:%s|%s|URI:%s|",
  45. c.Writer.Status(),
  46. elapsed.Round(time.Millisecond),
  47. c.ClientIP(),
  48. c.Request.Method,
  49. c.Request.URL.Path)
  50. userId := c.GetInt64("userId")
  51. userLog := &entity.UserLogs{
  52. UserId: userId,
  53. UserAgent: c.Request.UserAgent(),
  54. Ip: clientIP,
  55. Action: method,
  56. Path: path,
  57. Query: query,
  58. Status: c.Writer.Status(),
  59. Request: requestBodyStr,
  60. Response: blw.body.String(),
  61. Elapsed: fmt.Sprintf("%s", elapsed.Round(time.Millisecond)),
  62. }
  63. err := core.MainDb().Create(&userLog).Error
  64. if err != nil {
  65. core.Log.Error(err)
  66. }
  67. }
  68. }
  69. // bodyLogWriter 自定义ResponseWriter用于捕获响应体
  70. type bodyLogWriter struct {
  71. gin.ResponseWriter
  72. body *bytes.Buffer
  73. }
  74. func (w bodyLogWriter) Write(b []byte) (int, error) {
  75. w.body.Write(b)
  76. return w.ResponseWriter.Write(b)
  77. }