You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.1 KiB

3 years ago
3 years ago
3 years ago
  1. package middleware
  2. import (
  3. "bytes"
  4. "github.com/flipped-aurora/gin-vue-admin/server/utils"
  5. "io/ioutil"
  6. "net/http"
  7. "strconv"
  8. "time"
  9. "github.com/flipped-aurora/gin-vue-admin/server/global"
  10. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  11. "github.com/flipped-aurora/gin-vue-admin/server/service"
  12. "github.com/gin-gonic/gin"
  13. "go.uber.org/zap"
  14. )
  15. var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
  16. func OperationRecord() gin.HandlerFunc {
  17. return func(c *gin.Context) {
  18. var body []byte
  19. var userId int
  20. if c.Request.Method != http.MethodGet {
  21. var err error
  22. body, err = ioutil.ReadAll(c.Request.Body)
  23. if err != nil {
  24. global.GVA_LOG.Error("read body from request error:", zap.Error(err))
  25. } else {
  26. c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
  27. }
  28. }
  29. claims, _ := utils.GetClaims(c)
  30. if claims.ID != 0 {
  31. userId = int(claims.ID)
  32. } else {
  33. id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
  34. if err != nil {
  35. userId = 0
  36. }
  37. userId = id
  38. }
  39. record := system.SysOperationRecord{
  40. Ip: c.ClientIP(),
  41. Method: c.Request.Method,
  42. Path: c.Request.URL.Path,
  43. Agent: c.Request.UserAgent(),
  44. Body: string(body),
  45. UserID: userId,
  46. }
  47. // 存在某些未知错误 TODO
  48. //values := c.Request.Header.Values("content-type")
  49. //if len(values) >0 && strings.Contains(values[0], "boundary") {
  50. // record.Body = "file"
  51. //}
  52. writer := responseBodyWriter{
  53. ResponseWriter: c.Writer,
  54. body: &bytes.Buffer{},
  55. }
  56. c.Writer = writer
  57. now := time.Now()
  58. c.Next()
  59. latency := time.Since(now)
  60. record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
  61. record.Status = c.Writer.Status()
  62. record.Latency = latency
  63. record.Resp = writer.body.String()
  64. if err := operationRecordService.CreateSysOperationRecord(record); err != nil {
  65. global.GVA_LOG.Error("create operation record error:", zap.Error(err))
  66. }
  67. }
  68. }
  69. type responseBodyWriter struct {
  70. gin.ResponseWriter
  71. body *bytes.Buffer
  72. }
  73. func (r responseBodyWriter) Write(b []byte) (int, error) {
  74. r.body.Write(b)
  75. return r.ResponseWriter.Write(b)
  76. }