Skip to main content

Tracer

Trait Tracer 

pub trait Tracer {
    type Span: Span;

    // Required method
    fn build_with_context(
        &self,
        builder: SpanBuilder,
        parent_cx: &Context,
    ) -> Self::Span;

    // Provided methods
    fn start<T>(&self, name: T) -> Self::Span
       where T: Into<Cow<'static, str>> { ... }
    fn start_with_context<T>(&self, name: T, parent_cx: &Context) -> Self::Span
       where T: Into<Cow<'static, str>> { ... }
    fn span_builder<T>(&self, name: T) -> SpanBuilder
       where T: Into<Cow<'static, str>> { ... }
    fn build(&self, builder: SpanBuilder) -> Self::Span { ... }
    fn in_span<T, F, N>(&self, name: N, f: F) -> T
       where F: FnOnce(Context) -> T,
             N: Into<Cow<'static, str>>,
             Self::Span: Send + Sync + 'static { ... }
    fn in_span_with_context<T, F, N>(
        &self,
        name: N,
        parent_cx: &Context,
        f: F,
    ) -> T
       where F: FnOnce(Context) -> T,
             N: Into<Cow<'static, str>>,
             Self::Span: Send + Sync + 'static { ... }
    fn in_span_with_builder<T, F>(&self, builder: SpanBuilder, f: F) -> T
       where F: FnOnce(Context) -> T,
             Self::Span: Send + Sync + 'static { ... }
    fn in_span_with_builder_and_context<T, F>(
        &self,
        builder: SpanBuilder,
        parent_cx: &Context,
        f: F,
    ) -> T
       where F: FnOnce(Context) -> T,
             Self::Span: Send + Sync + 'static { ... }
}
Available on crate features opentelemetry and trace only.
Expand description

The interface for constructing Spans.

§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 mut child = tracer.start_with_context("bar", &parent_cx);

// ...

child.end(); // explicitly end
drop(parent_cx) // or implicitly end on drop

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

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

Pass a Context explicitly to Tracer::start_with_context when you want to choose a span’s parent. To make a context current within async code, use FutureExt::with_context. Do not hold a Context::attach guard or a mark_span_as_active guard across an .await: while the task is suspended, unrelated code on the same thread could see that context as current.

use opentelemetry::{trace::FutureExt, Context};
let cx = Context::current();

let my_future = async {
    // ...
};

my_future
    .with_context(cx)
    .await;

The wrapper makes the context current for each poll and restores the previous context when that poll returns. Creating a span, making it current, and ending it are separate operations. See Async context propagation for an example that creates a child span inside a future.

Required Associated Types§

type Span: Span

The Span type used by this tracer.

Required Methods§

fn build_with_context( &self, builder: SpanBuilder, parent_cx: &Context, ) -> Self::Span

Start a span from a SpanBuilder with a parent context.

Provided Methods§

fn start<T>(&self, name: T) -> Self::Span
where T: Into<Cow<'static, str>>,

Starts a new Span.

By default the currently active Span is set as the new Span’s parent.

Each span has zero or one parent span 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 start_with_context<T>(&self, name: T, parent_cx: &Context) -> Self::Span
where T: Into<Cow<'static, str>>,

Starts a new Span with a given context.

If this context contains a span, the newly created span will be a child of that span.

Each span has zero or one parent span 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<T>(&self, name: T) -> SpanBuilder
where T: Into<Cow<'static, str>>,

Creates a span builder.

SpanBuilders allow you to specify all attributes of a Span before the span is started.

fn build(&self, builder: SpanBuilder) -> Self::Span

Start a Span from a SpanBuilder.

fn in_span<T, F, N>(&self, name: N, f: F) -> T
where F: FnOnce(Context) -> T, N: Into<Cow<'static, str>>, Self::Span: Send + Sync + 'static,

Start a new span and execute the given closure with reference to the context in which the span is active.

This method starts a new span and sets it as the active span for the given function. It then executes the body. It ends 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 in_span_with_context<T, F, N>(&self, name: N, parent_cx: &Context, f: F) -> T
where F: FnOnce(Context) -> T, N: Into<Cow<'static, str>>, Self::Span: Send + Sync + 'static,

Start a new span with a given parent context and execute the given closure with reference to the context in which the span is active.

This method starts a new span as a child of the provided parent context and sets it as the active span for the given function. It then executes the body. It ends the span before returning the execution result.

§Examples
use opentelemetry::{global, trace::{Span, Tracer, TraceContextExt}, Context, KeyValue};

fn my_function() {
    let tracer = global::tracer("my-component");

    // Create a parent context
    let parent = tracer.start("parent-span");
    let parent_cx = Context::current_with_span(parent);

    // start an active span with explicit parent context
    tracer.in_span_with_context("child-span", &parent_cx, |_cx| {
        // child span is active here
    })
}

fn in_span_with_builder<T, F>(&self, builder: SpanBuilder, f: F) -> T
where F: FnOnce(Context) -> T, Self::Span: Send + Sync + 'static,

Start a new span from a SpanBuilder and execute the given closure with reference to the context in which the span is active.

This method builds and starts a new span from a SpanBuilder using the current context and sets it as the active span for the given function. It then executes the body. It ends the span before returning the execution result.

§Examples
use opentelemetry::{global, trace::{Span, SpanKind, Tracer}, KeyValue};

fn my_function() {
    let tracer = global::tracer("my-component");

    // start an active span with span configuration
    tracer.in_span_with_builder(
        tracer.span_builder("span-name")
            .with_kind(SpanKind::Client)
            .with_attributes(vec![KeyValue::new("key", "value")]),
        |_cx| {
            // span is active here with configured attributes
        }
    )
}

fn in_span_with_builder_and_context<T, F>( &self, builder: SpanBuilder, parent_cx: &Context, f: F, ) -> T
where F: FnOnce(Context) -> T, Self::Span: Send + Sync + 'static,

Start a new span from a SpanBuilder with a given parent context and execute the given closure with reference to the context in which the span is active.

This method builds and starts a new span from a SpanBuilder as a child of the provided parent context and sets it as the active span for the given function. It then executes the body. It ends the span before returning the execution result.

§Examples
use opentelemetry::{global, trace::{Span, SpanKind, Tracer, TraceContextExt}, Context, KeyValue};

fn my_function() {
    let tracer = global::tracer("my-component");

    // Create a parent context
    let parent = tracer.start("parent-span");
    let parent_cx = Context::current_with_span(parent);

    // start an active span with explicit parent context and span configuration
    tracer.in_span_with_builder_and_context(
        tracer.span_builder("child-span")
            .with_kind(SpanKind::Client)
            .with_attributes(vec![KeyValue::new("key", "value")]),
        &parent_cx,
        |_cx| {
            // child span is active here with configured attributes
        }
    )
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§