OpenTelemetry 范围与 spanBuilder.startSpan() 和 span.end()

Joe*_*ner 5 java open-telemetry

使用 OTel Java API 时,手动检测的代码通常如下所示:

@Inject
Tracer tracer;

public String instrumentedMethod() {
  // ...
  Span span = tracer.spanBuilder("interesting operation").startSpan();
  span.setAttribute("custom.info", "some info");
  try (Scope scope = span.makeCurrent()) {
    // logic
  }
  finally {
    span.end();
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

从我的角度来看, 的寿命span被定义了两次:

  • tracer.spanBuilder("...").startSpan()span.end()标定跨度的起点和终点,
  • 而且还以某种方式做到这span.makeCurrent()一点scope.end()

startSpan()/与/span.end()相比的目的是什么?可以省略吗?用的时候是多余的吗?span.makeCurrent()scope.end()scopespan.end()scope

Jam*_*sis 2

开始和结束跨度并不会让应用程序的其余部分知道当前的情况Context- 即当前哪个跨度是“活动的”。

如果您没有打开Scope,您所在部分中的任何代码//logic都将无法知道Context,因此它无法知道父跨度是什么。您最终会得到一堆单独的跨度,这些跨度没有通过公共跟踪链接在一起。

当您打开 a 时Scope,OpenTelemetry 会设置 a ThreadLocal,因此在该范围(try块)内启动的任何新范围都将能够知道其父范围是什么。

在某些情况下,您可能有一个Context但不是整个Span,因此这些概念因此而被分开(我假设还有其他一些原因)。