[−][src]Module opentelemetry::api::trace::tracer
OpenTelemetry Tracer interface
The OpenTelemetry library achieves in-process context propagation of Spans
by way of the Tracer.
The Tracer is responsible for tracking the currently active Span, and
exposes methods for creating and activating new Spans. The Tracer is
configured with Propagators which support transferring span context across
process boundaries.
Tracers are generally expected to be used as singletons. Implementations
SHOULD provide a single global default Tracer.
Some applications may require multiple Tracer instances, e.g. to create
Spans on behalf of other applications. Implementations MAY provide a
global registry of Tracers for such applications.
The Tracer SHOULD allow end users to configure other tracing components
that control how Spans are passed across process boundaries, including the
binary and text format Propagators used to serialize Spans created by
the Tracer.
In Synchronous Code
Spans can be created and nested manually:
use opentelemetry::{global, api::{Span, Tracer}}; let tracer = global::tracer("my-component"); let parent = tracer.start("foo"); let child = tracer.span_builder("bar") .with_parent(parent.span_context()) .start(&tracer); // ... child.end(); parent.end();
Spans can also use the current thread's Context to track which span is active:
use opentelemetry::{global, api::{Tracer, SpanKind}}; let tracer = global::tracer("my-component"); // Create simple spans with `in_span` tracer.in_span("foo", |_foo_cx| { // parent span is active tracer.in_span("bar", |_bar_cx| { // child span is now the active span and associated with the parent span }); // child has ended, parent now the active span again }); // parent has ended, no active spans // -- OR -- // create complex spans with span builder and `with_span` let parent_span = tracer.span_builder("foo").with_kind(SpanKind::Server).start(&tracer); tracer.with_span(parent_span, |_foo_cx| { // parent span is active let child_span = tracer.span_builder("bar").with_kind(SpanKind::Client).start(&tracer); tracer.with_span(child_span, |_bar_cx| { // child span is now the active span and associated with the parent span }); // child has ended, parent now the active span again }); // parent has ended, no active spans
Spans can also be marked as active, and the resulting guard allows for greater control over when the span is no longer considered active.
use opentelemetry::{global, api::{Span, Tracer}}; let tracer = global::tracer("my-component"); let parent_span = tracer.start("foo"); let parent_active = tracer.mark_span_as_active(parent_span); { let child = tracer.start("bar"); let _child_active = tracer.mark_span_as_active(child); // do work in the context of the child span... // exiting the scope drops the guard, child is no longer active } // Parent is active span again // Parent can be dropped manually, or allowed to go out of scope as well. drop(parent_active); // no active span
In Asynchronous Code
If you are instrumenting code that make use of std::future::Future or
async/await, be sure to use the FutureExt trait. This is needed because
the following example will not work:
async { // Does not work let _g = tracer.mark_span_as_active(span); // ... };
The context guard _g will not exit until the future generated by the
async block is complete. Since futures can be entered and exited
multiple times without them completing, the span remains active for as
long as the future exists, rather than only when it is polled, leading to
very confusing and incorrect output.
In order to trace asynchronous code, the Future::with_context combinator
can be used:
use opentelemetry::api::{Context, FutureExt}; let cx = Context::current(); let my_future = async { // ... }; my_future .with_context(cx) .await;
Future::with_context attaches a context to the future, ensuring that the
context's lifetime is as long as the future's.
Structs
| SpanBuilder |
|
Traits
| Tracer | Interface for constructing |