logger.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package middleware
  2. import (
  3. "time"
  4. "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey"
  5. "github.com/Wei-Shaw/sub2api/internal/pkg/ip"
  6. "github.com/Wei-Shaw/sub2api/internal/pkg/logger"
  7. "github.com/gin-gonic/gin"
  8. "go.uber.org/zap"
  9. )
  10. // Logger 请求日志中间件
  11. func Logger() gin.HandlerFunc {
  12. return func(c *gin.Context) {
  13. // 开始时间
  14. startTime := time.Now()
  15. // 请求路径
  16. path := c.Request.URL.Path
  17. // 处理请求
  18. c.Next()
  19. // 跳过健康检查等高频探针路径的日志
  20. if path == "/health" || path == "/setup/status" {
  21. return
  22. }
  23. endTime := time.Now()
  24. latency := endTime.Sub(startTime)
  25. method := c.Request.Method
  26. statusCode := c.Writer.Status()
  27. clientIP := ip.GetClientIP(c)
  28. protocol := c.Request.Proto
  29. accountID, hasAccountID := c.Request.Context().Value(ctxkey.AccountID).(int64)
  30. platform, _ := c.Request.Context().Value(ctxkey.Platform).(string)
  31. model, _ := c.Request.Context().Value(ctxkey.Model).(string)
  32. reason, rejected := GetIngressRejectReason(c)
  33. if rejected {
  34. recordIngressReject(c, reason)
  35. allowed, droppedSummary := globalIngressRejectAccessSampler.allow(endTime)
  36. if droppedSummary > 0 {
  37. logger.FromContext(c.Request.Context()).Info("ingress rejection access logs dropped",
  38. zap.String("component", "http.access"),
  39. zap.Uint64("dropped_count", droppedSummary),
  40. zap.Bool(logger.OpsSystemLogSkipField, true),
  41. )
  42. }
  43. if !allowed {
  44. return
  45. }
  46. }
  47. fields := []zap.Field{
  48. zap.String("component", "http.access"),
  49. zap.Int("status_code", statusCode),
  50. zap.Int64("latency_ms", latency.Milliseconds()),
  51. zap.String("client_ip", clientIP),
  52. zap.String("protocol", protocol),
  53. zap.String("method", method),
  54. zap.String("path", path),
  55. }
  56. if rejected {
  57. fields = append(fields,
  58. zap.String("ingress_reject_reason", string(reason)),
  59. zap.Bool(logger.OpsSystemLogSkipField, true),
  60. )
  61. }
  62. if hasAccountID && accountID > 0 {
  63. fields = append(fields, zap.Int64("account_id", accountID))
  64. }
  65. if platform != "" {
  66. fields = append(fields, zap.String("platform", platform))
  67. }
  68. if model != "" {
  69. fields = append(fields, zap.String("model", model))
  70. }
  71. l := logger.FromContext(c.Request.Context()).With(fields...)
  72. l.Info("http request completed", zap.Time("completed_at", endTime))
  73. if len(c.Errors) > 0 {
  74. l.Warn("http request contains gin errors", zap.String("errors", c.Errors.String()))
  75. }
  76. }
  77. }