log.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package middleware
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "fmt"
  7. "github.com/gin-gonic/gin"
  8. "github.com/go-nunu/nunu-layout/pkg/log"
  9. "github.com/go-nunu/nunu-layout/pkg/md5"
  10. "github.com/go-nunu/nunu-layout/pkg/uuid"
  11. "go.uber.org/zap"
  12. "io"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. func GinContextToContextMiddleware() gin.HandlerFunc {
  18. return func(c *gin.Context) {
  19. ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
  20. c.Request = c.Request.WithContext(ctx)
  21. c.Next()
  22. }
  23. }
  24. func RequestLogMiddleware(log *log.Logger) gin.HandlerFunc {
  25. return func(ctx *gin.Context) {
  26. // 每次请求都初始化一次配置
  27. trace := md5.Md5(uuid.GenUUID())
  28. log.NewGinContext(ctx, zap.String("trace", trace))
  29. log.NewGinContext(ctx, zap.String("request_method", ctx.Request.Method))
  30. headers, _ := json.Marshal(ctx.Request.Header)
  31. log.NewGinContext(ctx, zap.String("request_headers", string(headers)))
  32. log.NewGinContext(ctx, zap.String("request_url", ctx.Request.URL.String()))
  33. if ctx.Request.Body != nil {
  34. bodyBytes, _ := ctx.GetRawData()
  35. ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 关键点
  36. log.NewGinContext(ctx, zap.String("request_params", string(bodyBytes)))
  37. }
  38. ctx.Next()
  39. }
  40. }
  41. func ResponseLogMiddleware(log *log.Logger) gin.HandlerFunc {
  42. return func(ctx *gin.Context) {
  43. blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
  44. ctx.Writer = blw
  45. startTime := time.Now()
  46. ctx.Next()
  47. duration := int(time.Since(startTime).Milliseconds())
  48. ctx.Header("X-Response-Time", strconv.Itoa(duration))
  49. if ctx.Request.URL.Path == "/cos/object" && ctx.Request.Method == "POST" {
  50. return
  51. }
  52. if strings.Contains(ctx.Request.URL.Path, "storage") {
  53. return
  54. }
  55. log.WithGinContext(ctx).Info("响应返回", zap.Any("response_body", blw.body.String()), zap.Any("time", fmt.Sprintf("%sms", strconv.Itoa(duration))))
  56. statusCode := ctx.Writer.Status()
  57. fmt.Println(statusCode)
  58. //if statusCode >= 400 {
  59. //ok this is an request with error, let's make a record for it
  60. // now print body (or log in your preferred way)
  61. //fmt.Println("Response body: " + blw.body.String())
  62. //}
  63. }
  64. }
  65. type bodyLogWriter struct {
  66. gin.ResponseWriter
  67. body *bytes.Buffer
  68. }
  69. func (w bodyLogWriter) Write(b []byte) (int, error) {
  70. w.body.Write(b)
  71. return w.ResponseWriter.Write(b)
  72. }