[−][src]Trait opentelemetry::trace::Tracer
Interface for constructing Span
s.
The OpenTelemetry library achieves in-process context propagation of Span
s
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.
Tracer
s 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
Span
s 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 Span
s are passed across process boundaries, including the
binary and text format Propagator
s used to serialize Span
s created by
the Tracer
.
In Synchronous Code
Spans can be created and nested manually:
use opentelemetry::{global, trace::{Span, Tracer, TraceContextExt}, Context}; let tracer = global::tracer("my-component"); let parent = tracer.start("foo"); let parent_cx = Context::current_with_span(parent); let child = tracer.span_builder("bar") .with_parent_context(parent_cx.clone()) .start(&tracer); // ... child.end(); drop(parent_cx) // end parent
Spans can also use the current thread's Context
to track which span is active:
use opentelemetry::{global, trace::{SpanKind, Tracer}}; 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, trace::{Span, Tracer, mark_span_as_active}}; let tracer = global::tracer("my-component"); let parent_span = tracer.start("foo"); let parent_active = mark_span_as_active(parent_span); { let child = tracer.start("bar"); let _child_active = 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 = 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::{trace::FutureExt, Context}; 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.
Associated Types
Loading content...Required methods
fn invalid(&self) -> Self::Span
Returns a span with an invalid SpanContext
. Used by functions that
need to return a default span like get_active_span
if no span is present.
fn start_with_context(&self, name: &str, context: Context) -> Self::Span
Starts a new Span
with a given context
By default the currently active Span
is set as the new Span
's
parent. The Tracer
MAY provide other default options for newly
created Span
s.
Span
creation MUST NOT set the newly created Span
as the currently
active Span
by default, but this functionality MAY be offered additionally
as a separate operation.
Each span has zero or one parent spans and zero or more child spans, which
represent causally related operations. A tree of related spans comprises a
trace. A span is said to be a root span if it does not have a parent. Each
trace includes a single root span, which is the shared ancestor of all other
spans in the trace. Implementations MUST provide an option to create a Span
as
a root span, and MUST generate a new TraceId
for each root span created.
For a Span with a parent, the TraceId
MUST be the same as the parent.
Also, the child span MUST inherit all TraceState
values of its parent by default.
A Span
is said to have a remote parent if it is the child of a Span
created in another process. Each propagators' deserialization must set
is_remote
to true on a parent SpanContext
so Span
creation knows if the
parent is remote.
fn span_builder(&self, name: &str) -> SpanBuilder
Creates a span builder
An ergonomic way for attributes to be configured before the Span
is started.
fn build(&self, builder: SpanBuilder) -> Self::Span
Create a span from a SpanBuilder
Provided methods
fn start(&self, name: &str) -> Self::Span
Starts a new Span
.
By default the currently active Span
is set as the new Span
's
parent. The Tracer
MAY provide other default options for newly
created Span
s.
Span
creation MUST NOT set the newly created Span
as the currently
active Span
by default, but this functionality MAY be offered additionally
as a separate operation.
Each span has zero or one parent spans and zero or more child spans, which
represent causally related operations. A tree of related spans comprises a
trace. A span is said to be a root span if it does not have a parent. Each
trace includes a single root span, which is the shared ancestor of all other
spans in the trace. Implementations MUST provide an option to create a Span
as
a root span, and MUST generate a new TraceId
for each root span created.
For a Span with a parent, the TraceId
MUST be the same as the parent.
Also, the child span MUST inherit all TraceState
values of its parent by default.
A Span
is said to have a remote parent if it is the child of a Span
created in another process. Each propagators' deserialization must set
is_remote
to true on a parent SpanContext
so Span
creation knows if the
parent is remote.
fn in_span<T, F>(&self, name: &'static str, f: F) -> T where
F: FnOnce(Context) -> T,
Self::Span: Send + Sync,
F: FnOnce(Context) -> T,
Self::Span: Send + Sync,
Start a new span and execute the given closure with reference to the span's context.
This method starts a new span and sets it as the active span for the given function. It then executes the body. It closes the span before returning the execution result.
Examples
use opentelemetry::{global, trace::{Span, Tracer, get_active_span}, KeyValue}; fn my_function() { // start an active span in one function global::tracer("my-component").in_span("span-name", |_cx| { // anything happening in functions we call can still access the active span... my_other_function(); }) } fn my_other_function() { // call methods on the current span from get_active_span(|span| { span.add_event("An event!".to_string(), vec![KeyValue::new("happened", true)]); }) }
fn with_span<T, F>(&self, span: Self::Span, f: F) -> T where
F: FnOnce(Context) -> T,
Self::Span: Send + Sync,
F: FnOnce(Context) -> T,
Self::Span: Send + Sync,
Start a new span and execute the given closure with reference to the span's context.
This method starts a new span and sets it as the active span for the given function. It then executes the body. It closes the span before returning the execution result.
Examples
use opentelemetry::{global, trace::{Span, SpanKind, Tracer, get_active_span}, KeyValue}; fn my_function() { let tracer = global::tracer("my-component"); // start a span with custom attributes via span bulder let span = tracer.span_builder("span-name").with_kind(SpanKind::Server).start(&tracer); // Mark the span as active for the duration of the closure global::tracer("my-component").with_span(span, |_cx| { // anything happening in functions we call can still access the active span... my_other_function(); }) } fn my_other_function() { // call methods on the current span from get_active_span(|span| { span.add_event("An event!".to_string(), vec![KeyValue::new("happened", true)]); }) }
Implementors
impl Tracer for BoxedTracer
[src]
type Span = BoxedSpan
Global tracer uses BoxedSpan
s so that it can be a global singleton,
which is not possible if it takes generic type parameters.
fn invalid(&self) -> Self::Span
[src]
Returns a span with an inactive SpanContext
. Used by functions that
need to return a default span like get_active_span
if no span is present.
fn start_with_context(&self, name: &str, cx: Context) -> Self::Span
[src]
Starts a new Span
.
Each span has zero or one parent spans and zero or more child spans, which represent causally related operations. A tree of related spans comprises a trace. A span is said to be a root span if it does not have a parent. Each trace includes a single root span, which is the shared ancestor of all other spans in the trace.
fn span_builder(&self, name: &str) -> SpanBuilder
[src]
Creates a span builder
An ergonomic way for attributes to be configured before the Span
is started.
fn build(&self, builder: SpanBuilder) -> Self::Span
[src]
Create a span from a SpanBuilder
impl Tracer for Tracer
[src]
type Span = Span
This implementation of Tracer
produces sdk::Span
instances.
fn invalid(&self) -> Self::Span
[src]
Returns a span with an inactive SpanContext
. Used by functions that
need to return a default span like get_active_span
if no span is present.
fn start_with_context(&self, name: &str, cx: Context) -> Self::Span
[src]
Starts a new Span
with a given context.
Each span has zero or one parent spans and zero or more child spans, which represent causally related operations. A tree of related spans comprises a trace. A span is said to be a root span if it does not have a parent. Each trace includes a single root span, which is the shared ancestor of all other spans in the trace.
fn span_builder(&self, name: &str) -> SpanBuilder
[src]
Creates a span builder
An ergonomic way for attributes to be configured before the Span
is started.
fn build(&self, builder: SpanBuilder) -> Self::Span
[src]
Starts a span from a SpanBuilder
.
Each span has zero or one parent spans and zero or more child spans, which represent causally related operations. A tree of related spans comprises a trace. A span is said to be a root span if it does not have a parent. Each trace includes a single root span, which is the shared ancestor of all other spans in the trace.
impl Tracer for NoopTracer
[src]
type Span = NoopSpan
fn invalid(&self) -> Self::Span
[src]
Returns a NoopSpan
as they are always invalid.
fn start_with_context(&self, name: &str, cx: Context) -> Self::Span
[src]
Starts a new NoopSpan
with a given context.
If the context contains a valid span context, it is propagated.
fn span_builder(&self, name: &str) -> SpanBuilder
[src]
Starts a SpanBuilder
.
fn build(&self, builder: SpanBuilder) -> Self::Span
[src]
Builds a NoopSpan
from a SpanBuilder
.
If the span builder or context contains a valid span context, it is propagated.