← 返回文章列表
使用指南 4 分钟阅读 炬鲸团队

应用接入 OpenTelemetry SDK:自动埋点与手动 Span 怎么选

自动埋点省事但覆盖不到业务语义,手动埋点精准但费工。本文给出 Java/Python 的自动埋点启动方式、手动 Span 写法、属性命名规范,以及验证链路是否真正打通的步骤。

自动埋点能做什么、不能做什么

OpenTelemetry 的自动埋点靠注入 Agent 在运行时改写字节码或挂解释器钩子,不改代码就能拿到 HTTP 请求、数据库调用、消息队列这些通用信息。它覆盖的是「框架层面」的 span:入站请求、出站调用、SQL 执行。

但它覆盖不到业务语义。自动埋点知道你调了 POST /orders,却不知道这笔订单的金额、用户 ID、用了哪张优惠券。排查线上问题,缺的往往正是这些业务维度——自动埋点能告诉你「哪条调用链慢了」,却说不清「哪类订单慢了」。

启动自动埋点

Java 服务只需在启动命令加一行,就能拿到完整的链路:

java -javaagent:opentelemetry-javaagent.jar \
  -Dotel.service.name=order-service \
  -Dotel.exporter.otlp.endpoint=http://collector:4317 \
  -Dotel.traces.exporter=otlp \
  -jar order-service.jar

Python 用 opentelemetry-instrument 包裹启动命令,配合 opentelemetry-bootstrap 自动装好各库对应的 instrumentor:

opentelemetry-bootstrap -a install
opentelemetry-instrument \
  --traces_exporter otlp \
  --exporter_otlp_endpoint http://collector:4317 \
  python app.py

跑起来后,先发一条请求,回到控制台看是否出现完整的调用链。链路没打通之前,先别急着做手动埋点——问题大概率在采集端或网络,而不是代码里。

什么时候手动埋点、怎么写

手动埋点不是把所有逻辑都包一层 span,只在三处动手:

  1. 业务边界:把一笔订单从下单到回调包成一个 span,用 transaction_id 贯穿。
  2. 关键慢点:第三方外部调用、大循环、批量任务,这些自动埋点拿不到耗时细节。
  3. 业务属性:给现有 span 补充 user.idorder.amount 这类维度,排查时能按业务条件过滤。

Java 里给 span 补属性:

Span span = tracer.spanBuilder("process-order").startSpan();
span.setAttribute("order.amount", 99.5);
span.setAttribute("user.id", uid);
try (Scope scope = span.makeCurrent()) {
    // 业务逻辑
} catch (Exception e) {
    span.recordException(e);
    span.setStatus(StatusCode.ERROR);
    throw e;
} finally {
    span.end();
}

recordExceptionsetStatus(ERROR) 别省:告警和采样策略都依赖 span 的状态码。出错了不标记,尾采样可能把关键链路采没,出问题时你会发现自己最需要的那条 trace 不见了。

属性命名与验证

属性名统一用点分小写(order.amount 而不是 orderAmount),团队先约定一份属性清单,避免各服务各写一套。接入后按 trace id 在控制台验证:span 树是否完整、业务属性是否带上、错误 span 是否标记。抽一条出错请求,确认能从告警一路下钻到异常栈,才算真正接好。