uptrace 是基于 opentelemetry 的托管可观测平台,提供 trace/metrics/logs 一体化查询;go 接入需用其 otlp endpoint 和 token 上报数据,推荐使用官方 sdk 自动解析 dsn 并初始化追踪器,日志关联依赖 trace_id 字段正确注入与外部日志系统对接。

Uptrace 是基于 OpenTelemetry 的托管式可观测平台,它省去了自建 Jaeger/Zipkin + Prometheus + Loki 的运维成本,直接提供 Trace、Metrics、Logs 三位一体的查询界面。在 Go 微服务中接入 Uptrace,本质是配置 OpenTelemetry SDK 使用其 OTLP HTTP/GRPC 导出器,并正确设置认证 token 和 endpoint —— 不是“对接 Uptrace”,而是“用 Uptrace 提供的 OTLP 地址上报数据”。
Uptrace 的 OTLP endpoint 和 token 怎么填
Uptrace 控制台(https://uptrace.dev)创建项目后,会明确给出两个关键值:
-
UPTRACE_DSN:形如https://<project_id>:<secret_key>@uptrace.dev/<project_id></project_id></secret_key></project_id>,这是最简方式,SDK 可自动解析 - 或手动拆解为:
OTEL_EXPORTER_OTLP_ENDPOINT(如https://otlp.uptrace.dev:4318) +UPTRACE_SECRET_KEY(用于 HTTP Basic Auth 或 gRPC metadata)
⚠️ 容易踩的坑:误把 DSN 当成普通 URL 直接拼进 otlptracehttp.NewClient;正确做法是用 Uptrace 官方 SDK(go.uptrace.dev/otel)自动处理 DSN 解析,或手动构造带 Authorization: Basic <base64></base64> 的 HTTP client。
Go 服务里怎么初始化 Uptrace 追踪器
推荐直接使用 Uptrace 官方封装的初始化函数,它已内置采样、资源、传播器等最佳实践:
import (
"go.uptrace.dev/otel"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
)
<p>func initTracing() error {
return otel.ConfigureOpentelemetry(
otel.WithServiceName("user-service"),
otel.WithServiceVersion("1.2.0"),
otel.WithDSN("<a href="https://www.php.cn/link/cd92cbe966fd3498c1adc65f44aa3656">https://www.php.cn/link/cd92cbe966fd3498c1adc65f44aa3656</a>"),
otel.WithResource(resource.WithAttributes(
semconv.DeploymentEnvironmentKey.String("production"),
)),
)
}</p>
说明:
- 不用自己写
sdktrace.NewTracerProvider,otel.ConfigureOpentelemetry已封装完整链路 -
WithDSN是核心,传入控制台生成的完整 DSN 字符串即可 - 若需自定义采样率,加
otel.WithSampler(sdktrace.TraceIDRatioBased(0.1)) - 不调用该函数时,
otel.Tracer会 fallback 到 noop 实现,不会 panic
HTTP 中间件里如何自动创建 Span 并注入 trace_id 到日志
Uptrace 本身不提供中间件,但你得确保每个请求都有 Span,并把 trace_id 注入结构化日志字段(如 zap 的 zap.String("trace_id", ...)):
- 用
otelhttp.NewHandler包裹你的http.ServeMux或 Gin 路由,它会自动从traceparent头提取上下文、创建 Span、注入响应头 - 在中间件中获取当前 Span:
span := trace.SpanFromContext(r.Context()),再调用span.SpanContext().TraceID().String() - 别用
fmt.Sprintf("%x", span.SpanContext().TraceID())——String()才是标准 32 位小写 hex 格式,和 Uptrace UI 显示一致 - 如果用 zap,建议封装一个
WithContext日志字段提取器,避免每个 handler 都重复取
为什么本地开发能看到 Trace 却查不到 Logs 关联
Uptrace 默认只接收 OTLP traces/metrics,**不接收 logs** —— 这是常见误解。Logs 必须单独配置:
- Uptrace 不提供日志存储,它的 Logs tab 是「关联视图」:只显示已通过 OTLP Log Exporter 上报、且含
trace_id字段的日志 - Go 侧需用
go.opentelemetry.io/otel/log(v1.22+)或第三方库(如uber-go/zap+go.opentelemetry.io/contrib/bridges/zap)将 log 写入 OTLP - 更现实的做法:用 Promtail/Loki 收集 JSON 日志,确保每条日志含
"trace_id": "..."字段,再在 Uptrace UI 的 Trace 详情页点击「View logs」跳转到 Loki 查询 - 检查日志字段名是否为
trace_id(不是TraceID、traceId),Uptrace 关联逻辑严格匹配此 key
Uptrace 的价值不在「全托管日志」,而在用统一 UI 把你已有的 OTLP traces 和外部日志系统(Loki/Elasticsearch)按 trace_id 拼接起来。漏掉 trace_id 字段注入,或者没配好日志系统的 trace_id 解析规则,关联就断了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











