Skip to main content

Crate dcontext_tracing

Crate dcontext_tracing 

Source
Expand description

§dcontext-tracing

Automatic dcontext scope management via tracing spans.

This crate provides a tracing_subscriber::Layer that automatically creates and manages dcontext scopes when tracing spans are entered and exited. This means your context values follow the natural span lifecycle without any manual scope management.

§Quick Start

use tracing_subscriber::prelude::*;

// Zero-config: every span creates a dcontext scope
tracing_subscriber::registry()
    .with(dcontext_tracing::DcontextLayer::new())
    .init();

§Features

§Level 1: Automatic Scoping

With zero configuration, DcontextLayer creates a new dcontext scope every time a span is entered. Values set inside a span are automatically cleaned up when the span exits, just like tracing’s own span lifecycle.

// Register context keys, then inside a span:
// dcontext::sync_ctx::set_context("user", "alice".to_string());
// {
//     let _span = tracing::info_span!("request").entered();
//     // New scope created — inherits parent values
//     dcontext::sync_ctx::set_context("request_id", "abc-123".to_string());
// }
// Scope reverted — "request_id" gone, "user" remains

§Level 2: Field-to-Context Extraction

Extract tracing span fields directly into dcontext values using TracingField metadata:

use dcontext_tracing::{DcontextLayer, TracingField};

#[derive(Clone, Default, Debug, serde::Serialize, serde::Deserialize)]
struct RequestId(String);

impl std::fmt::Display for RequestId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

let mut builder = dcontext::RegistryBuilder::new();
builder.register_with::<RequestId>("request_id", |opts| {
    opts.with_metadata(
        TracingField::builder("request_id")
            .extract_from_str(|s| Some(RequestId(s.to_string())))
            .enrich_display::<RequestId>()  // enables both log + span enrichment
            .build(),
    )
});

// DcontextLayer discovers TracingField metadata automatically.
// On span enter:
//   - Extracts span fields into context (extract direction)
//   - Records context values into pre-declared Empty span fields (span record direction)
// let layer = DcontextLayer::new();

§Level 3: Span Info

Expose span metadata as a context value:

use dcontext_tracing::{DcontextLayer, SpanInfo};
use tracing_subscriber::Registry;

let layer: DcontextLayer<Registry> = DcontextLayer::builder()
    .include_span_info()
    .build();

// Inside a span:
// let info: SpanInfo = dcontext::sync_ctx::get_context("dcontext.span").unwrap_or_default();
// info.name, info.target, info.level

§How It Works

The layer uses 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 made in that scope.

This mirrors the approach used by tracing-opentelemetry for similar thread-local guard management.

§Async Behavior

Tokio async code should use AsyncDcontextLayer, which stores span state in dcontext::async_ctx task-local storage so mapped values, span info, and scope chain entries persist across .await points in the task.

SyncDcontextLayer (and the legacy DcontextLayer alias) remain useful for synchronous or explicitly thread-local code. dcontext::sync_ctx always uses thread-local storage directly, so no force_thread_local() wrapper is needed.

Structs§

AsyncDcontextLayer
A tracing layer that manages dcontext scopes on the task-local store.
AsyncDcontextLayerBuilder
Builder for configuring an AsyncDcontextLayer.
SpanInfo
Span metadata exposed as a dcontext value.
SyncDcontextLayer
A tracing layer that manages dcontext scopes on the thread-local store.
SyncDcontextLayerBuilder
Builder for configuring a SyncDcontextLayer.
TracingField
Unified tracing metadata for a context key.
TracingFieldBuilder
Builder for TracingField metadata.
WithContextFields
A FormatEvent wrapper that enriches log events with context values.

Constants§

SPAN_INFO_KEY
The dcontext key used for SpanInfo.

Functions§

collect_log_fields
Collect the current context log fields as (name, formatted_value) pairs.

Type Aliases§

DcontextLayer
Type alias for backward compatibility — DcontextLayer is now SyncDcontextLayer.
DcontextLayerBuilder
Type alias for backward compatibility — DcontextLayerBuilder is now SyncDcontextLayerBuilder.