log.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package middleware
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "net/http"
  6. "runtime/debug"
  7. "time"
  8. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  9. "github.com/gin-gonic/gin"
  10. "go.uber.org/zap"
  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. // GinLogger 接管gin框架默认的日志
  21. func GinLogger() gin.HandlerFunc {
  22. return func(c *gin.Context) {
  23. // 获取 response 内容
  24. w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
  25. c.Writer = w
  26. var requestBody []byte
  27. if c.Request.Body != nil {
  28. requestBody, _ = ioutil.ReadAll(c.Request.Body)
  29. c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody))
  30. }
  31. start := time.Now()
  32. c.Next()
  33. cost := time.Since(start)
  34. logFields := []zap.Field{
  35. zap.Int("status", c.Writer.Status()),
  36. zap.String("request", c.Request.Method+" "+c.Request.URL.String()),
  37. zap.String("query", c.Request.URL.RawQuery),
  38. zap.String("ip", c.ClientIP()),
  39. zap.String("user-agent", c.Request.UserAgent()),
  40. zap.String("time", cost.String()),
  41. zap.String("Request body", string(requestBody)),
  42. zap.String("Response body", w.body.String()),
  43. zap.String("x-request-id", c.GetHeader("X-Request-ID")),
  44. }
  45. if len(c.Errors) > 0 {
  46. logFields = append(logFields, zap.Any("stack", string(debug.Stack())))
  47. zaplog.Error("Http-Access-Error", logFields...)
  48. c.Abort()
  49. } else {
  50. zaplog.Info("Http-Access-Log", logFields...)
  51. }
  52. }
  53. }
  54. // GinRecovery recover掉我的项目可能呈现的panic
  55. func GinRecovery(stack bool) gin.HandlerFunc {
  56. return func(c *gin.Context) {
  57. defer func() {
  58. if err := recover(); err != nil {
  59. body, _ := ioutil.ReadAll(c.Request.Body)
  60. // 获取 panic 发生的位置
  61. var stackTrace []byte
  62. if stack {
  63. // 获取调用栈
  64. stackTrace = debug.Stack()
  65. }
  66. zaplog.Error("panic",
  67. zap.Any("recover", err),
  68. zap.Any("url", c.Request.URL),
  69. zap.Any("stackTrace", string(stackTrace)),
  70. zap.Any("request", string(body)),
  71. zap.String("x-request-id", c.GetHeader("X-Request-ID")),
  72. )
  73. c.AbortWithStatus(http.StatusInternalServerError)
  74. c.Abort()
  75. return
  76. }
  77. }()
  78. c.Next()
  79. }
  80. }