Skip to main content
Context propagation allows trace information to flow across service boundaries and through async operations, maintaining the parent-child relationships between spans.

Context Basics

The Context type stores the currently active span and other contextual information. The TraceContextExt trait provides methods for working with spans in a context.

TraceContextExt Trait

From opentelemetry/src/trace/context.rs:223-299:

Managing Active Spans

Creating Context with Spans

Accessing the Active Span

Using get_active_span

The get_active_span function provides access to the current thread’s active span:

Propagating Context

Thread-Local Context Storage

OpenTelemetry uses thread-local storage to manage the active context:

Manual Context Attachment

For explicit control over context lifetime:

Using mark_span_as_active

From opentelemetry/src/trace/context.rs:327-361:

Async Context Propagation

The Problem with Async

Standard context guards don’t work correctly with async code:
From opentelemetry/src/trace/tracer.rs:79-95:
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.

Using FutureExt

The correct way to propagate context in async code:

Complete Async Example

Remote Context Propagation

Extracting Context for Propagation

When making HTTP requests or RPC calls, inject context into headers:

Real-world gRPC Example

From examples/tracing-grpc/src/client.rs:23-34:

Extracting Context from Incoming Requests

W3C Trace Context Propagator

Configure the global text map propagator:

Remote Span Context

When you receive a span context from another service:

Context in Span Processors

Do not rely on Context::current() in SpanProcessor::on_end. The context at cleanup time is unrelated to the span being ended.
From opentelemetry-sdk/src/trace/span_processor.rs:87-118:

Best Practices

Never use context guards directly in async blocks. Use .with_context() to attach context to futures.
When making network calls, inject the current context into request metadata so downstream services can continue the trace.
For server-side code, extract the parent span context from incoming request headers to maintain trace continuity.
Configure a single text map propagator (like W3C Trace Context) globally to ensure consistent propagation across your application.
In span processors, extract needed information during on_start and store it as span attributes.

Complete Example

Here’s a complete HTTP client/server example:

Next Steps

Sampling

Learn how to control which traces are recorded

Span Processors

Configure how spans are processed and exported