从零接入 OpenTelemetry 的最小路径:部署 Collector、配置 OTLP 导出到炬鲸 OBSERVE、给 Java/Go 应用埋点,并附验证方法与常见报错排查,15 分钟内看到第一条完整调用链。
OpenTelemetry(OTel)已经是可观测性数据采集的事实标准。它统一了 Trace、Metrics、Logs 三类信号的上报格式,应用侧埋点一次,后端随便换。本文用最小配置,15 分钟内把一条完整调用链送进炬鲸 OBSERVE。
流程分三段:应用通过 SDK 埋点 → 数据以 OTLP 协议发给 OpenTelemetry Collector → Collector 转发到炬鲸 OBSERVE 的 OTLP 接入端点。
为什么不直接让应用上报到后端?Collector 负责统一接收、脱敏、采样和重试,应用只需要知道 Collector 的地址,后端切换时不用改应用代码。这个中间层是 OTel 架构里最值钱的部分。
用 Docker 起一个 Collector,配置文件如下:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
exporters:
otlphttp:
endpoint: https://ob.jjhub.cn/otel/v1/traces
headers:
Authorization: "Bearer <你的接入令牌>"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
接入令牌在炬鲸 OBSERVE 控制台的「数据接入」页面生成,注意生产/测试环境各用一个令牌,方便后续按来源过滤和统计用量。
docker run -d --name otel-collector -v $PWD/otel-collector.yaml:/etc/otelcol/config.yaml -p 4317:4317 -p 4318:4318 otel/opentelemetry-collector-contrib:latest
以 Java 为例,加一个 Java Agent 就够了。它通过字节码注入自动埋点,不用改业务代码:
java -javaagent:opentelemetry-javaagent.jar -Dotel.exporter.otlp.endpoint=http://localhost:4317 -Dotel.service.name=order-service -jar app.jar
Go 的话在 main 里初始化 Tracer:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/trace"
)
exp, _ := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure())
tp := trace.NewTracerProvider(trace.WithBatcher(exp))
otel.SetTracerProvider(tp)
关键是 service.name 要设成有业务含义的名字,它是链路里区分服务的唯一标识。HTTP 框架的自动埋点(Java 的 Servlet、Go 的 net/http)会替你生成 span,跨服务调用时 trace 上下文会自动传播,不需要手动透传 header。
发一个真实请求,到炬鲸 OBSERVE 的「链路追踪」页面,按 service.name 过滤,应该能看到完整调用链,各服务的耗时和依赖关系一目了然。
常见三个坑:
timeout 调小(如 1s),否则要干等。验证通过后把 batch.timeout 调回 5s。生产环境建议在 Collector 前再加 probabilistic_sampler 控制采样率,避免高流量下上报量失控。