tempo 是后端追踪存储服务,非 go sdk;go 项目需配置 opentelemetry sdk,通过 otlp exporter(如 otlphttp 或 otlpgrpc)将 trace 发至 tempo-distributor 或 otel-collector,而非直连 tempo 查询接口。

Tempo 不是 Go SDK,而是后端服务,Go 项目只需对接 OpenTelemetry
Tempo 本身不提供 Go 语言的原生 Trace 库,它是一个后端分布式追踪存储与查询系统(类似 Jaeger backend 或 Zipkin server)。你在 Go 项目里要做的,不是“配置 Tempo”,而是配置 OpenTelemetry SDK,让它把 trace 数据以 OTLP 协议发给 Tempo 的 collector(通常是 tempo-distributor 或 otel-collector 配合 tempo exporter)。
Go 项目中必须引入 opentelemetry-go 并设置 OTLP Exporter
核心是初始化 TracerProvider,并用 otlphttp.NewExporter 或 otlpgrpc.NewExporter 指向你的 Tempo collector 地址。常见错误是直接往 Tempo 的 query 接口(如 http://tempo:3200)发 trace——那只是 UI 查询端,不接收数据。
- 确保安装正确依赖:
go.opentelemetry.io/otel、go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp(HTTP)或go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc(gRPC) - Exporter endpoint 应为 collector 的
/v1/traces路径(HTTP)或 gRPC 端口(如tempo-distributor:4317),不是 Tempo query 服务端口 - 若用 HTTP,记得设置
WithEndpoint("tempo-distributor:4318")+WithURLPath("/v1/traces");gRPC 则只需WithEndpoint("tempo-distributor:4317") - 务必调用
tracerProvider.Register()(或otel.SetTracerProvider())让全局 tracer 生效,否则otel.Tracer(...).Start()返回的是 noop tracer
Tempo 本身不接收 trace,必须前置部署 collector(tempo-distributor 或 otel-collector)
直接从 Go 进程发 trace 到 Tempo 是行不通的。Tempo 只暴露 /api/traces(接收 push)接口,但该接口已弃用且默认关闭;官方推荐路径是:Go → OTLP Exporter → tempo-distributor(官方轻量 distributor)或 otel-collector(带更多处理能力)→ Tempo ingester。
-
tempo-distributor是最简选择,Docker 启动示例:docker run -p 4317:4317 -p 4318:4318 grafana/tempo-distributor:latest - 若用
otel-collector,需在 config.yaml 中启用tempoexporter,并确保 receiver 是otlp,exporter 是tempo(指向tempo:3200的endpoint) - Go 项目中的 Exporter 地址,应与 collector 的 receiver 地址一致(如 collector 监听
0.0.0.0:4317,Go 就连localhost:4317) - 别忽略健康检查:curl
http://localhost:4318/metrics或grpcurl -plaintext localhost:4317 list确认 collector 已就绪
采样率、ServiceName、TraceID 生成等关键配置容易被忽略
即使数据能发出去,没设对 service.name 或采样策略,也会导致 trace 在 Tempo UI 里不可见或爆炸式增长。
- 必须通过
resource.WithAttributes(semconv.ServiceNameKey.String("your-service-name"))设置 service name,否则 Tempo 默认归为unknown_service,搜索困难 - 默认采样是
ParentBased(AlwaysSample),开发环境可以,生产务必换成ParentBased(TraceIDRatioBased(0.01))控制流量 - Go 的
otelhttp中间件需显式传入otelhttp.WithSpanNameFormatter,否则 HTTP span 名称全是HTTP GET,无法区分路由 - TraceID 和 SpanID 由 SDK 自动生成(基于随机数),无需手动干预,但要注意:若用了自定义 ID 生成器,必须满足 16 字节(TraceID)和 8 字节(SpanID)要求,否则 Tempo 拒收
Tempo 的链路检索强依赖 service name 和 trace ID 格式,这两点配错,基本等于埋了数据却找不到入口。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











