fiber框架需通过ctx.locals+中间件+zerolog等日志库实现traceid链路追踪,核心是请求绑定、跨goroutine传递、日志显式注入三步;traceid须首中间件生成并复用请求头x-trace-id,异步场景必须手动传参而非依赖ctx。

直接上结论:Fiber 框架本身不内置 MDC 类机制,但可以通过 ctx.Locals + 中间件 + 日志库(如 zerolog 或 logrus)实现等效的 TraceId 链路追踪,关键在于「请求生命周期内绑定、跨 goroutine 传递、日志格式显式注入」三步缺一不可。
中间件里怎么生成和存 TraceId
TraceId 必须在第一个中间件中生成并写入 ctx.Locals,不能延迟到 handler 里。否则下游中间件或 handler 可能拿不到。
- 用
uuid.NewString()最稳妥,避免时间戳+随机数拼接导致重复(尤其高并发短时密集请求) - 优先检查请求头
X-Trace-Id,存在则复用,不存在才新生成——这是跨服务链路连续性的前提 - 调用
ctx.Locals("traceId", traceId),不是ctx.Set或自定义 map,因为只有Locals是 Fiber 官方推荐的请求级上下文载体
日志怎么自动带上 TraceId
原生 log 包不行,必须用支持字段注入的日志库。以 zerolog 为例,不能只靠全局 logger,得为每个请求构造带 traceId 的子 logger。
- 在中间件里拿到
traceId := ctx.Locals("traceId").(string)后,调用logger.With().Str("traceId", traceId).Logger() - 把这个子 logger 存回
ctx.Locals("logger"),后续 handler 和其他中间件通过ctx.Locals("logger").(*zerolog.Logger)获取 - 日志配置里不要依赖
%X{traceId}这类 Logback 风格占位符——Fiber 没有 MDC,必须显式传字段
异步 goroutine 怎么传递 TraceId
Fiber 的 ctx 不会自动跨 goroutine 传播,ctx.Locals 在新 goroutine 里是空的。这是最容易漏掉的一环。
- 启动 goroutine 前,手动把
traceId提出来,作为参数传进去,而不是传整个ctx - 如果用了
zerolog,就在 goroutine 内部重新logger.With().Str("traceId", traceId).Logger()构造一次 - 绝对不要在 goroutine 里直接调用
ctx.Locals("traceId")——它一定返回 nil - 数据库查询、HTTP 调用等异步操作,也需手动把
X-Trace-Idheader 加到下游请求头里
最常被忽略的是 goroutine 场景:比如你用 go func() { ... }() 处理 MQ 消息或定时任务,这时候根本没有 Fiber ctx,TraceId 必须从消息体或上游透传字段里解析,不能假设“它应该有”。











