dcontext-tracing
Automatic dcontext scope management via tracing spans.
When you enter a tracing span, this crate automatically creates a dcontext scope. When the span exits, the scope is reverted. This means your context values follow the natural span lifecycle — no manual scope management needed.
Quick Start
[]
= "0.8"
= "0.8"
= "0.1"
= "0.3"
use *;
registry
.with
.init;
Two Recommended Integration Modes
Sync / Thread-Local Code
Use SyncDcontextLayer with dcontext::sync_ctx:
set_context;
// Scope reverted — "request_id" is gone, "user" remains
Async / Task-Local Code
Use AsyncDcontextLayer with dcontext::async_ctx:
use async_ctx;
use AsyncDcontextLayer;
use Instrument;
use *;
registry
.with
.init;
async
with_context
.await;
Field-to-Context Mapping
Map tracing span fields directly to dcontext values. When a span with the configured field is entered, the value is extracted and set in context:
use sync_ctx;
use ;
;
let layer = builder
.
.build;
registry.with.init;
let _span = info_span!.entered;
let id = .unwrap;
assert_eq!;
You can also map a field to a different context key name:
let layer = builder
.
.build;
Span Info
Expose span metadata (name, target, level) as a context value:
use sync_ctx;
use ;
let layer = builder
.include_span_info
.build;
registry.with.init;
Full Example
See samples/src/bin/tracing_scopes.rs
for a complete working example.
API Reference
| Type | Purpose |
|---|---|
SyncDcontextLayer<S> |
Tracing layer for thread-local dcontext::sync_ctx |
AsyncDcontextLayer<S> |
Tracing layer for task-local dcontext::async_ctx |
DcontextLayer<S> |
Legacy alias retained for compatibility |
FromFieldValue |
Trait for converting tracing fields to context types |
SpanInfo |
Span metadata (name, target, level) |
SPAN_INFO_KEY |
Context key for SpanInfo ("dcontext.span") |
How It Works
SyncDcontextLayer (and the legacy DcontextLayer alias) use a
thread-local stack to store dcontext ScopeGuards (which are !Send and
cannot be stored in tracing's span extensions). On span enter, a new scope is
pushed; on span exit, the scope is popped and the guard dropped, reverting
context changes.
AsyncDcontextLayer writes to dcontext::async_ctx task-local storage instead
and keeps per-span lifecycle state in span extensions so scopes survive
Tokio yield points and task migration.
Scope Chain Integration
Span names automatically become named scopes in the dcontext scope chain. Each time a span is entered, the layer pushes the span name into the active store, so scope-chain queries reflect the tracing span hierarchy:
let _outer = info_span!.entered;
// After _inner exits: chain == ["api_handler"]
With AsyncDcontextLayer, use dcontext::async_ctx::scope_chain() instead so
the chain follows the Tokio task across .await points.
Related
- dcontext — Core context propagation library
- dcontext-dactor — dactor actor framework integration
- Usage Guide
License
MIT