log.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package middleware
  2. import (
  3. "bytes"
  4. "github.com/duke-git/lancet/v2/cryptor"
  5. "github.com/duke-git/lancet/v2/random"
  6. "github.com/gin-gonic/gin"
  7. "github.com/go-nunu/nunu-layout-advanced/pkg/log"
  8. "go.uber.org/zap"
  9. "io"
  10. "time"
  11. )
  12. func RequestLogMiddleware(logger *log.Logger) gin.HandlerFunc {
  13. return func(ctx *gin.Context) {
  14. // The configuration is initialized once per request
  15. uuid, err := random.UUIdV4()
  16. if err != nil {
  17. return
  18. }
  19. trace := cryptor.Md5String(uuid)
  20. logger.WithValue(ctx, zap.String("trace", trace))
  21. logger.WithValue(ctx, zap.String("request_method", ctx.Request.Method))
  22. logger.WithValue(ctx, zap.Any("request_headers", ctx.Request.Header))
  23. logger.WithValue(ctx, zap.String("request_url", ctx.Request.URL.String()))
  24. if ctx.Request.Body != nil {
  25. bodyBytes, _ := ctx.GetRawData()
  26. ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 关键点
  27. logger.WithValue(ctx, zap.String("request_params", string(bodyBytes)))
  28. }
  29. logger.WithContext(ctx).Info("Request")
  30. ctx.Next()
  31. }
  32. }
  33. func ResponseLogMiddleware(logger *log.Logger) gin.HandlerFunc {
  34. return func(ctx *gin.Context) {
  35. blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
  36. ctx.Writer = blw
  37. startTime := time.Now()
  38. ctx.Next()
  39. duration := time.Since(startTime).String()
  40. ctx.Header("X-Response-Time", duration)
  41. logger.WithContext(ctx).Info("Response", zap.Any("response_body", blw.body.String()), zap.Any("time", duration))
  42. }
  43. }
  44. type bodyLogWriter struct {
  45. gin.ResponseWriter
  46. body *bytes.Buffer
  47. }
  48. func (w bodyLogWriter) Write(b []byte) (int, error) {
  49. w.body.Write(b)
  50. return w.ResponseWriter.Write(b)
  51. }