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.

69 lines
1.6 KiB

  1. package middleware
  2. import (
  3. "bytes"
  4. "gin-vue-admin/global"
  5. "gin-vue-admin/model"
  6. "gin-vue-admin/service"
  7. "github.com/gin-gonic/gin"
  8. "go.uber.org/zap"
  9. "io/ioutil"
  10. "net/http"
  11. "strconv"
  12. "time"
  13. )
  14. func OperationRecord() gin.HandlerFunc {
  15. return func(c *gin.Context) {
  16. var body []byte
  17. if c.Request.Method != http.MethodGet {
  18. var err error
  19. body, err = ioutil.ReadAll(c.Request.Body)
  20. if err != nil {
  21. global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
  22. } else {
  23. c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
  24. }
  25. }
  26. userId, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
  27. if err != nil {
  28. userId = 0
  29. }
  30. record := model.SysOperationRecord{
  31. Ip: c.ClientIP(),
  32. Method: c.Request.Method,
  33. Path: c.Request.URL.Path,
  34. Agent: c.Request.UserAgent(),
  35. Body: string(body),
  36. UserID: userId,
  37. }
  38. writer := responseBodyWriter{
  39. ResponseWriter: c.Writer,
  40. body: &bytes.Buffer{},
  41. }
  42. c.Writer = writer
  43. now := time.Now()
  44. c.Next()
  45. latency := time.Now().Sub(now)
  46. record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
  47. record.Status = c.Writer.Status()
  48. record.Latency = latency
  49. record.Resp = writer.body.String()
  50. if err := service.CreateSysOperationRecord(record); err != nil {
  51. global.GVA_LOG.Error("create operation record error:", zap.Any("err", err))
  52. }
  53. }
  54. }
  55. type responseBodyWriter struct {
  56. gin.ResponseWriter
  57. body *bytes.Buffer
  58. }
  59. func (r responseBodyWriter) Write(b []byte) (int, error) {
  60. r.body.Write(b)
  61. return r.ResponseWriter.Write(b)
  62. }