operation.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package middleware
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "sync"
  11. "time"
  12. "github.com/flipped-aurora/gin-vue-admin/server/utils"
  13. "github.com/flipped-aurora/gin-vue-admin/server/global"
  14. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  15. "github.com/gin-gonic/gin"
  16. "go.uber.org/zap"
  17. )
  18. var respPool sync.Pool
  19. var bufferSize = 1024
  20. func init() {
  21. respPool.New = func() interface{} {
  22. return make([]byte, bufferSize)
  23. }
  24. }
  25. func OperationRecord() gin.HandlerFunc {
  26. return func(c *gin.Context) {
  27. var body []byte
  28. var userId int
  29. if c.Request.Method != http.MethodGet {
  30. var err error
  31. body, err = io.ReadAll(c.Request.Body)
  32. if err != nil {
  33. global.GVA_LOG.Error("read body from request error:", zap.Error(err))
  34. } else {
  35. c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
  36. }
  37. } else {
  38. query := c.Request.URL.RawQuery
  39. query, _ = url.QueryUnescape(query)
  40. split := strings.Split(query, "&")
  41. m := make(map[string]string)
  42. for _, v := range split {
  43. kv := strings.Split(v, "=")
  44. if len(kv) == 2 {
  45. m[kv[0]] = kv[1]
  46. }
  47. }
  48. body, _ = json.Marshal(&m)
  49. }
  50. claims, _ := utils.GetClaims(c)
  51. if claims != nil && claims.BaseClaims.ID != 0 {
  52. userId = int(claims.BaseClaims.ID)
  53. } else {
  54. id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
  55. if err != nil {
  56. userId = 0
  57. }
  58. userId = id
  59. }
  60. record := system.SysOperationRecord{
  61. Ip: c.ClientIP(),
  62. Method: c.Request.Method,
  63. Path: c.Request.URL.Path,
  64. Agent: c.Request.UserAgent(),
  65. Body: "",
  66. UserID: userId,
  67. }
  68. // 上传文件时候 中间件日志进行裁断操作
  69. if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
  70. record.Body = "[文件]"
  71. } else {
  72. if len(body) > bufferSize {
  73. record.Body = "[超出记录长度]"
  74. } else {
  75. record.Body = string(body)
  76. }
  77. }
  78. writer := responseBodyWriter{
  79. ResponseWriter: c.Writer,
  80. body: &bytes.Buffer{},
  81. }
  82. c.Writer = writer
  83. now := time.Now()
  84. c.Next()
  85. latency := time.Since(now)
  86. record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
  87. record.Status = c.Writer.Status()
  88. record.Latency = latency
  89. record.Resp = writer.body.String()
  90. if strings.Contains(c.Writer.Header().Get("Pragma"), "public") ||
  91. strings.Contains(c.Writer.Header().Get("Expires"), "0") ||
  92. strings.Contains(c.Writer.Header().Get("Cache-Control"), "must-revalidate, post-check=0, pre-check=0") ||
  93. strings.Contains(c.Writer.Header().Get("Content-Type"), "application/force-download") ||
  94. strings.Contains(c.Writer.Header().Get("Content-Type"), "application/octet-stream") ||
  95. strings.Contains(c.Writer.Header().Get("Content-Type"), "application/vnd.ms-excel") ||
  96. strings.Contains(c.Writer.Header().Get("Content-Type"), "application/download") ||
  97. strings.Contains(c.Writer.Header().Get("Content-Disposition"), "attachment") ||
  98. strings.Contains(c.Writer.Header().Get("Content-Transfer-Encoding"), "binary") {
  99. if len(record.Resp) > bufferSize {
  100. // 截断
  101. record.Body = "超出记录长度"
  102. }
  103. }
  104. if err := global.GVA_DB.Create(&record).Error; err != nil {
  105. global.GVA_LOG.Error("create operation record error:", zap.Error(err))
  106. }
  107. }
  108. }
  109. type responseBodyWriter struct {
  110. gin.ResponseWriter
  111. body *bytes.Buffer
  112. }
  113. func (r responseBodyWriter) Write(b []byte) (int, error) {
  114. r.body.Write(b)
  115. return r.ResponseWriter.Write(b)
  116. }