如果想要对每个请求的调用进行跟踪,需要充分利用 context 包,通过 context 来传递一个唯一标识 trace id,从而能够追踪请求的调用链。
自定义 Logger 对 *zap.SugaredLogger 进行包装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package loggerimport ( "context" "github.com/gin-gonic/gin" "go.uber.org/zap" )type Logger struct { logger *zap.SugaredLogger }func NewLogger (logger *zap.SugaredLogger) *Logger { return &Logger{logger: logger} }const TraceIdKey = "trace_id" func (l *Logger) WithTraceId(c *gin.Context, traceId string ) { if c == nil { return } c.Set(TraceIdKey, traceId) }func (l *Logger) WithContext(c context.Context) *zap.SugaredLogger { if c == nil { return l.logger } if traceId, ok := c.Value(TraceIdKey).(string ); ok { return l.logger.With(TraceIdKey, traceId) } return l.logger }
Gin 中间件写入 trace id 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package middlewareimport ( "github.com/gin-gonic/gin" "github.com/google/uuid" "gitlab.turingstar.com.cn/xinyou/e-commerce/pkg/logger" )type Tracer struct { logger *logger.Logger }func NewTracer (logger *logger.Logger) *Tracer { return &Tracer{ logger: logger, } }func (t *Tracer) Trace(c *gin.Context) { traceId := c.GetHeader("traceId" ) if traceId == "" { traceId = uuid.New().String() } t.logger.WithTraceId(c, traceId) c.Next() }
逻辑代码中的使用示例: 1 s.logger.WithContext(c).With("request" , req).Error("用户获取历史订单列表失败:" , err)