从零接入 OpenTelemetry 的完整教程:确认采集链路三节点、Go 与 Java 服务端 SDK 配置示例、三步验证链路与日志对齐,附常见问题排查清单。
本文走一遍从零接入的完整流程:装好采集器、把服务端 SDK 打开、验证链路和日志能不能对上。目标读者是第一次接 OTel 的后端工程师。
接入 OTel 到 OBSERVE 需要三样东西:服务里的 SDK(生成 span 和日志)、一个 OTel Collector(做聚合与采样)、OBSERVE 的 OTLP 接收端点。小规模部署可以把 Collector 省掉,让 SDK 直连 OTLP 端点;生产环境建议保留 Collector,统一做采样、脱敏和网络出口,改采样率不用逐个改服务。
引入 OTel SDK,在 main 里初始化 tracer provider:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)
func initTracer(ctx context.Context) (*sdktrace.TracerProvider, error) {
exp, _ := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint("collector:4318"),
otlptracehttp.WithInsecure(),
)
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceName("order-svc"),
)),
)
otel.SetTracerProvider(tp)
return tp, nil
}
三个必须做的点:ServiceName 要全局统一(它决定 OBSERVE 里的 service 维度);用 Batcher 批量导出而不是每次请求直发;生产环境走 Collector 而非 SDK 直连,方便统一改采样率与做脱敏。
pom 里引入 BOM 统一版本:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.40.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
配合 javaagent 方式最省事,启动参数加 -javaagent:opentelemetry-javaagent.jar,再用环境变量指定端点:
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
OTEL_SERVICE_NAME=order-svc
OTEL_METRICS_EXPORTER=otlp
自动埋点能拿到 HTTP、JDBC、Redis 等常见调用的 span,不必手写埋点代码;需要业务级 span 时再用 @WithSpan 注解补,避免全局过度埋点导致 span 爆炸。
要让日志能跟着 trace_id 查出来,关键是日志行里带上 trace_id。用 OTel 的日志桥接把 trace context 写进结构化日志字段(字段名统一叫 trace_id),OBSERVE 按这个字段把日志和链路串起来。不要在日志里只打印一行裸文本——没有 trace_id 的日志,链路详情里点不出来。
trace_id 能查出对应日志;对不上时按顺序查三处:端点和端口、ServiceName 是否处处一致、采样率是否把请求漏掉。默认尾部采样会保留 error,但正常请求可能被采样掉,排查时先临时把采样率调到 100%。