Skip to main content

Crate tracing_wide

Crate tracing_wide 

Source
Expand description

§tracing-wide

CI docs.rs

[!CAUTION] This is NOT an official tokio / tokio-tracing product or associated crate.

This crate enables wide events for tokio tracing. It enables additional functionality for tracing but does not implement / replace it.

Wide events are built as one struct per event, carrying every observability-relevant field for that event. The message text of such an event stays static; all variance lives in typed fields.

The core of the crate is no_std and runs in WASM.

Highlights include:

  • Typed wide events: one struct per event via #[message]; event! checks required fields, fills unset Options from the ambient span, fans out to subscribers, then records to tracing at the type’s level.
  • Flexible serialization: none, serde, or facet; opt-in per type, never a bound on Message.
  • Catalogue: every message a binary can emit, auto-registered and walkable, including messages defined in libraries or member crates as long as they’re linked in. The catalogue is representation-agnostic - it’s plain data you can serialize to any format (or none): a manifest (msg is the unique join key) that non-technical stakeholders can reason about, with duplicate keys detectable in a test.
  • Automatic origin: crate / module / file / line / column captured per message, object-safe and drift-free.
  • Ambient autocapture: Option fields fill at emit time from same-named fields on the surrounding tracing::instrument span, across crate boundaries.
  • Subscribers: each event reaches registered sinks as a typed &dyn Message before the tracing handoff; stay generic via accessors or downcast.
  • Routing: on static tags() with no downcast, or (with facet) on live field values read by name.

§Getting started

use tracing_wide::{event, message};

// One struct per event: the message text is static, the fields carry the variance.
#[message(msg = "hello world")]
struct Hello {
    who: &'static str,
}

// Emit it: builds the struct and records it to `tracing` at the type's level.
event!(Hello { who: "world" });

§Examples

§Feature flags

  • docs — Documentation-only: pulls in every dependency and rendering needed to build the full rustdoc (currently document-features, which renders this list). Enabled by docs.rs and just docs; never needed by applications or libraries.

  • catalogue — Auto-collected per-type catalogue: inventory registration + descriptors. On its own the descriptors are plain data; add serde and they gain Serialize.

    Tooling-only feature. Should neither be enabled for applications nor libraries.

  • facet — Facet reflection integration. The as_facet hook on Message hands a subscriber a facet::Peek over a live message body — enabled per type by #[derive(Facet)] alone — for introspection: pull fields out by name and filter on an individual field, not just on tags. Distinct from serde, which forwards the body whole; this pulls it apart.

    Unstable: facet is pre-1.0 and every minor is a breaking change, so this feature tracks that churn — expect breakage. facet is re-exported as tracing_wide::facet so a subscriber names Peek/Facet/the derive through one coherent version.

  • instrument — Instrument integration (ambient autocapture): a tracing-subscriber Layer that captures span field values — i.e. what tracing::instrument records — and an emit-time join that fills a message’s still-None Option fields by name from the current span scope. Only Option fields join; a miss is legal (None). Requires the app’s subscriber to be built on tracing_subscriber::registry() with instrument::layer() installed — without them, event! degrades gracefully (fields stay None).

    Application-only feature. Should only be enabled for applications, not for libraries.

  • serde — Serde integration. On its own: the erased-serde hook on Message (as_serialize) that lets a subscriber serialize a live message body without naming its concrete type — enabled per type by #[derive(Serialize)] alone. Combined with catalogue, the catalogue descriptors also derive Serialize (for dumping to JSON/TOML).

  • std (enabled by default) — Opt-in std - required for all features beyond core functionality.

  • subscriber — Global subscriber registry + typed &dyn Message fan-out that runs before the tracing handoff. Without it, event! just records to tracing.

    Application-only feature. Should only be enabled for applications, not for libraries.

Re-exports§

pub use ::facet;

Modules§

catalogue
The auto-collected catalogue: per-type descriptors registered by #[message] and read back at runtime. Gated as a whole by the catalogue feature.
examples
Examples
instrument
Ambient autocapture: fill a message’s Option fields from the tracing span scope at emit time. Gated by the instrument feature.
subscriber
App-level subscriber mechanics: a global registry whose handlers see each emitted message as a typed &dyn Message before the tracing handoff. Gated by the subscriber feature — without it, event! just records to tracing and the core stays free of global state.

Macros§

event
Function-like macro: construct a Message and record it.

Structs§

Origin
Where a message type is defined — automatic provenance captured by #[message], which emits the core location builtins (env!("CARGO_PKG_NAME"), module_path!, file!, line!, column!) for rustc to fill while compiling the defining crate.

Traits§

Field
Marker trait: a type eligible to be a field of a message.
Message
A struct that may be emitted as a wide event.

Attribute Macros§

message
Attribute macro: mark a struct as a Message.