不改业务代码,用 Java Agent 自动埋点把 Spring Boot 应用接入 OBSERVE 链路追踪,含启动参数、Logback 日志关联 trace_id 的完整配置和常见坑。
otel.example.com:4317)全程不需要改业务代码,通过 Java Agent 自动埋点完成。Agent 会在类加载时自动织入埋点,覆盖 HTTP 客户端、数据库驱动、消息队列、Spring MVC 等常见组件。
从 OpenTelemetry 官方 Release 页下载 opentelemetry-javaagent.jar,放到应用机器的固定目录,比如 /opt/otel/。建议锁定版本,生产环境不要追最新版;升级前先在测试环境跑一轮,确认传播格式与下游兼容。
在 JVM 启动参数里加上:
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -Dotel.service.name=order-service -Dotel.exporter.otlp.endpoint=http://otel.example.com:4317 -Dotel.traces.exporter=otlp -Dotel.metrics.exporter=otlp -Dotel.logs.exporter=otlp -Dotel.propagators=tracecontext,baggage -jar app.jar
几个参数说清楚:
otel.service.name:服务名,决定你在 OBSERVE 里看到的名字,务必全局唯一,建议和注册中心里的服务名一致;otel.exporter.otlp.endpoint:OBSERVE 采集网关地址;otel.propagators:传播协议,默认 tracecontext 即可,跨服务透传靠它。生产环境建议把这些参数收敛到统一的启动脚本或 K8s Deployment 的 env 里,避免每个服务各自为政、名字和采样率不一致。
链路和日志打通的关键在日志。以 Logback 为例,在 logback.xml 的 pattern 里注入 MDC:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%X{trace_id}] [%X{span_id}] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
Agent 会自动把 trace_id、span_id 注入 MDC,日志里就会带上这两个字段,OBSERVE 采集后即可与 Trace 关联。如果日志已经用 JSON 格式输出,记得把这两个字段加到 JSON 里,否则关联会断。
发一个请求,然后在 OBSERVE 的链路查询页按 service.name = order-service 检索。能看到 Span 就说明通了。点开任意 Span,应该能看到它对应的日志;反过来,在日志里点 trace_id 也能回到整条链路。
建议再压一轮流量,观察 Span 数量、采样比例、错误率是否和预期一致,避免"看起来通了、实际大量数据被丢"。
-Dotel.traces.sampler=parentbased_traceidratio 配合 -Dotel.traces.sampler.arg=0.1,先采 10%,别把存储打爆;traceparent 头;OTEL_BSP_* 批量参数,别让导出队列无限堆积。只给一个服务接链路追踪,手动集成 SDK 也不难。但当你有一批 Java 服务、还想统一采样率和服务命名时,Agent 的优势就出来了:配置集中在启动参数里,升级 Agent 就是换个 jar,不用重新发布业务代码。缺点是 Agent 拿不到业务语义,比如订单号、用户 ID。所以建议是:框架层面的埋点用 Agent 自动搞定,业务维度再手动加少量 Span 属性,两者互补。