opentelemetry go sdk已内置trace id生成、context注入、跨goroutine传递及http header编解码,直接使用otelhttp.newhandler包裹handler可自动完成w3c tracecontext提取、span创建与注入;下游调用须用otelhttp.newclient,goroutine启动必须显式传入ctx,数据库操作需用querycontext等ctx版本方法,避免context.background()导致链路断裂。

OpenTelemetry Go SDK 就够了,不用自己实现 trace ID 生成、context 注入、跨 goroutine 传递或 HTTP header 编解码——这些全是已知高危区,自己写大概率踩 context 丢失、span 泄漏、W3C 标准不兼容的坑。
HTTP handler 怎么自动透传 trace context
最常见错误是手动读写 r.Header.Get("traceparent") 或在中间件里重复调用 tracer.Start(),结果出现双 root span 或链路断裂。
- 直接用
otelhttp.NewHandler(myHandler, "api")包裹 handler,它自动完成 W3C TraceContext 的提取、span 创建、注入和生命周期管理 - 别把原始 handler 注册进去——
http.Handle("/api", myHandler)是错的,必须是http.Handle("/api", otelhttp.NewHandler(myHandler, "api")) - 用 Gin/Chi 等框架时,别传裸
http.Handler:Gin 要用gin.WrapH(otelhttp.NewHandler(...)),Chi 要用chi.WrapHandler - span name 别为空字符串,部分 exporter(如 Jaeger)会直接丢弃
HTTP client 请求怎么带上 trace 上下文
下游服务收不到 traceparent,基本都是 client 端没走 OTel 封装。
- 必须用
otelhttp.NewClient(http.DefaultClient)实例发请求,不是给原 client 加个 header 就完事 - 如果要用自定义 transport,得确保它支持
otelhttp.Transport,否则 context 不会自动注入 - 手动注入只在极少数场景需要:先用
otel.GetTextMapPropagator().Inject(ctx, carrier),再把 carrier 写进 request header - 注意 carrier 的 key 必须小写:
"traceparent"✅,"TraceParent"❌
goroutine 和数据库调用为什么 trace 断了
Go 的 context.Context 不会自动跨 goroutine 传播,这是生产环境 trace 断裂的头号原因。
- 启动新 goroutine 时,必须显式传入带 span 的 ctx:
go doWork(ctx),而不是go doWork() - 数据库操作必须用
ctx版本方法:比如db.QueryContext(ctx, sql),ORM 如 GORM 要链式调用.WithContext(ctx) - 别用
context.Background()或context.TODO()——它们彻底切断链路 - time.AfterFunc、sync.WaitGroup 启动的异步逻辑,同样要传 ctx 并考虑用
context.WithTimeout控制生命周期
导出器选 OTLP 还是 Jaeger 或 Zipkin
本地开发图省事可以用 Jaeger agent,但上线前务必切到 OTLP;Zipkin 表面兼容,实则精度丢失严重。
- 开发阶段:用
jaeger.NewExporter+jaeger-agent容器,header 是uber-trace-id(非 W3C 标准) - 生产环境:直连 OTLP endpoint(如 Tempo、Lightstep),用
otlptracegrpc或otlphttp,endpoint 必须带完整路径:http://collector:4318/v1/traces - Zipkin 导出器会把纳秒级时间截成毫秒,跨度信息失真;Jaeger Thrift 协议已弃用,新版只认 OTLP
- 初始化
TracerProvider时,resource.WithAttributes()必须早于 provider 创建,否则service.name等关键字段全丢
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











