opentelemetry 是当前 go 微服务链路追踪唯一推荐方案,因 go 生态已弃用 opentracing/opencensus;必须在 main() 开头同步初始化 tracerprovider 和 meterprovider,配置统一资源标签与 traceidratiobased(0.01) 采样率,并通过 otelhttp/otelgrpc 拦截器及 propagator 注入 context 实现跨服务、跨 goroutine 的完整链路透传。

OpenTelemetry 是当前 Golang 微服务中唯一能兼顾云厂商兼容性、长期维护性与语义标准统一的多维遥测(Traces/Metrics/Logs)采集方案。别用已归档的 opentracing-go,也别自己拼 traceparent 头——链路会在第一个 HTTP 跳就断掉。
初始化 TracerProvider 和 MeterProvider 必须同步完成
只配 trace 不配 metrics,等于只装了摄像头没装电表;两者必须在应用启动早期一并初始化,且共享同一套资源(如 service.name、env、version),否则数据对不上。
-
TracerProvider和MeterProvider都需传入sdkresource.NewSchema1Resource()构建统一资源标签,例如:service.name、service.version、deployment.environment - 采样器不能只设
sdktrace.AlwaysSample():QPS 过千时 OTLP exporter 会积压、重试风暴、拖垮 CPU;生产推荐sdktrace.TraceIDRatioBased(0.01)(按 trace ID 哈希取 1%,非固定频率) -
MeterProvider的导出器要和TracerProvider对齐:比如都走otlptracegrpc+otlpmetricgrpc,或都走stdout调试
Gin/gRPC 中间件必须显式传递 context,不能依赖默认 Request.Context()
c.Request.Context() 是干净的,不带任何 span 或 metric scope。如果你没在中间件里用 propagator 恢复 parent,后续所有自动埋点(包括 otelhttp、otelgin、otelgrpc)都会生成孤立 root span。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 手动 Extract 示例:
ctx := propagation.TraceContext{}.Extract(r.Context(), r.Header),再通过c.Request = c.Request.WithContext(ctx)注入 Gin 上下文 - 若已用
otelgin.Middleware,它内部已做 Extract + 创建 root span,此时你再调tracer.Start()会嵌套出无效 span - gRPC server 端同理:必须用
otelgrpc.UnaryServerInterceptor(),且确保 client 端用了otelgrpc.UnaryClientInterceptor(),否则跨服务链路断裂
HTTP 出站请求必须用 otelhttp.Transport,且 context 里已有有效 span
otelhttp.Transport 只负责 outbound 注入,它不会创建新 span,也不会重复 Inject。前提是你的 context 里已有上游传入或本服务创建的有效 span —— 否则 header 为空,下游收不到 traceparent。
- 正确用法:
&http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)},然后确保所有Do()调用都传入带 span 的ctx - 错误做法:先
propagator.Inject()手动写 header,再用otelhttp.Transport—— 导致traceparent写两次,W3C 校验失败,Jaeger/Zapkin 直接丢弃整条 trace - 异步任务(如 goroutine)中发起 HTTP 请求时,必须显式
context.WithValue()或context.WithCancel()传递 span context,否则链路在 goroutine 启动瞬间就丢失
自定义 Span 和 Metric 必须绑定业务语义,避免空泛命名
一个叫 "process" 的 span 或 "request_count" 的 counter 几乎没有诊断价值。OpenTelemetry 的威力在于把遥测数据和业务逻辑锚定。
- Span 名称应反映具体行为:
"user.create"、"order.submit"、"payment.verify",而非框架层抽象名如"http.handler" - Metric key 要带维度:
api_latency_seconds_bucket{endpoint="/v1/user",method="POST",status_code="200"},而不是单个latency_seconds - 关键错误必须
span.RecordError(err)+span.SetStatus(codes.Error, err.Error()),否则 Prometheus 的traces_error_total不会统计
TracerProvider、propagator、otelgin、otelhttp.Transport 四者之间有严格的依赖时序,错一步,整条链路就碎成孤岛。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










