You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Golang slog包中添加Trace ID/Correlation ID实现请求链路追踪

给Go slog日志添加Trace/Correlation ID的实现方法

核心逻辑

slog默认不会主动读取context中的值并注入日志,需要通过自定义Handler包装JSONHandler,实现从context提取Trace ID并添加到日志字段的功能。

完整实现代码

1. 自定义TraceHandler

package main

import (
	"context"
	"log/slog"
	"os"
)

// 自定义Handler,包装原生JSONHandler
type TraceHandler struct {
	slog.Handler
}

// 重写Handle方法,注入Trace ID
func (h *TraceHandler) Handle(ctx context.Context, r slog.Record) error {
	// 从context中提取trace_id(建议用常量代替字符串key避免拼写错误)
	if traceID, ok := ctx.Value("trace_id").(string); ok {
		r.AddAttrs(slog.String("trace_id", traceID))
	}
	return h.Handler.Handle(ctx, r)
}

// 实现WithAttrs,保持日志器链式调用能力
func (h *TraceHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return &TraceHandler{Handler: h.Handler.WithAttrs(attrs)}
}

// 实现WithGroup,保持日志器分组能力
func (h *TraceHandler) WithGroup(name string) slog.Handler {
	return &TraceHandler{Handler: h.Handler.WithGroup(name)}
}

2. 初始化日志器并使用

func main() {
	// 创建原生JSONHandler
	jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
		AddSource: true,
	})
	// 用自定义TraceHandler包装,设置为默认日志器
	logger := slog.New(&TraceHandler{Handler: jsonHandler})
	slog.SetDefault(logger)

	// 模拟请求上下文,注入trace_id
	ctx := context.Background()
	ctx = context.WithValue(ctx, "trace_id", "abc-123-xyz-789")

	// 业务代码中记录日志,trace_id会自动加入输出
	slog.InfoContext(ctx, "请求进入", "path", "/api/v1/user")
	slog.InfoContext(ctx, "用户信息查询完成", "user_id", 456)
	slog.ErrorContext(ctx, "操作失败", "err_msg", "数据库连接超时")
}

补充说明

  • 建议定义常量作为context的key,避免硬编码字符串出错:const TraceIDKey = "trace_id"
  • 如果使用OpenTelemetry等链路追踪框架,可直接从context中提取官方标准的trace ID,无需自定义key

内容的提问来源于stack exchange,提问作者Manzurul Hoque Rumi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:54:56