uptrace服务端可通过docker compose一键启动:确保2gb内存和20gb磁盘后,执行docker-compose up -d,访问http://localhost:14318进入控制台,其使用http协议的otlp exporter,默认端口14318而非4317。

Uptrace 是开箱即用的 OpenTelemetry 原生 APM,不用自己搭 Jaeger + Prometheus + Grafana 三件套,直接跑一个容器就能收 trace、metrics、logs。
Uptrace 服务端怎么起:Docker Compose 一行命令
Uptrace 官方提供现成的 docker-compose.yml,不需要手写配置。关键点就两个:
- 确保宿主机有至少 2GB 内存和 20GB 磁盘空间(ClickHouse 占内存)
- 执行
docker-compose up -d后,访问http://localhost:14318就能进控制台 - 别用
localhost:4317这个默认 OTLP gRPC 端口——Uptrace 用的是 HTTP 协议的 OTLP exporter,端口是14318 - 如果服务跑在 Docker 容器里,Go 应用里连 Uptrace 要写
host.docker.internal:14318(Mac/Windows),Linux 则填宿主机真实 IP
Go SDK 怎么配:只改 endpoint 和 DSN,不碰 propagator
Uptrace 的 Go 接入极简,核心就是把 OTLP HTTP exporter 的 endpoint 和 headers 设对。它自动处理 W3C traceparent 透传,不用手动配 propagation.NewCompositeTextMapPropagator。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 初始化时用
otlptracehttp.New(),不是otlptracegrpc.New() -
WithEndpoint("localhost:14318")必须显式指定,否则默认连localhost:4317会静默失败 -
WithHeaders里塞"uptrace-dsn",值是从控制台项目设置里复制的完整 DSN 字符串,形如http://xxx@localhost:14318/123 - 不用调
otel.SetTextMapPropagator()——Uptrace 默认兼容 W3C,且会自动 fallback 到 B3;但如果你的旧服务还在发uber-trace-id,就得手动加propagation.B3{}到 composite propagator
HTTP/gRPC 自动埋点怎么开:中间件顺序不能错
Uptrace 不提供专属中间件,但完全兼容标准 otelhttp 和 otelgrpc。坑全在加载时机和包裹范围上。
-
otelhttp.NewHandler()必须包住整个http.ServeMux或 Gin/Echo 的 root handler,不能只包某个子路由 - Gin 用户直接用
otelgin.Middleware(),但它依赖otel.GetTextMapPropagator().Extract(),所以得确保全局 propagator 已设(见上一条) - gRPC 服务端必须注册
otelgrpc.UnaryServerInterceptor(),客户端用otelgrpc.UnaryClientInterceptor();只在业务层tracer.Start()会导致父子 span 断裂 - 所有异步任务(
go func() { ... }())必须显式传req.Context(),否则 span 关闭后 context 被 cancel,子 goroutine 拿不到 parent
为什么 trace 看不到 DB 或下游 HTTP:exporter 初始化失败是静默的
最常见现象:Uptrace 控制台能看到服务名、span 数量上涨,但点进去全是空壳,没 SQL、没下游 URL、没状态码。根本原因不是埋点漏了,而是 tracer provider 没真正生效。
- 检查
otel.Tracer("my-service")返回的 tracer 是否为nil——99% 是因为没调otel.SetTracerProvider(tp) - 别在
init()函数里初始化 SDK,Go 的init执行顺序不可控,HTTP server 可能比 tracer provider 先启动 - 本地调试时,先用
stdoutexporter替代 OTLP,把 span JSON 打到终端,确认结构体里有attributes["db.statement"]或attributes["http.url"]再切回 Uptrace - 数据库埋点要 wrap
*sql.DB:MySQL 用otelmysql.Wrap(),PostgreSQL 用otelpostgresql.Wrap(),原生database/sql不带任何 span
Uptrace 最容易被忽略的点:它不帮你做采样率动态调整或 span 属性过滤。所有 span 都上报,生产环境务必在 trace.NewTracerProvider() 里配 trace.WithSampler(trace.ParentBased(trace.TraceIDRatioBased(0.01))),不然流量一大,Uptrace 自己先 OOM。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










