🛈 Note: This is pre-release documentation for the upcoming tracing 0.2.0 ecosystem.

For the release documentation, please see docs.rs, instead.

tracing/
dispatch.rs

1//! Dispatches trace events to a [`Collect`].
2//!
3//! The _dispatcher_ is the component of the tracing system which is responsible
4//! for forwarding trace data from the instrumentation points that generate it
5//! to the collector that collects it.
6//!
7//! # Using the Trace Dispatcher
8//!
9//! Every thread in a program using `tracing` has a _default collector_. When
10//! events occur, or spans are created, they are dispatched to the thread's
11//! current collector.
12//!
13//! ## Setting the Default Collector
14//!
15//! By default, the current collector is an empty implementation that does
16//! nothing. Trace data provided to this "do nothing" implementation is
17//! immediately discarded, and is not available for any purpose.
18//!
19//! To use another collector implementation, it must be set as the default.
20//! There are two methods for doing so: [`with_default`] and
21//! [`set_global_default`]. `with_default` sets the default collector for the
22//! duration of a scope, while `set_global_default` sets a default collector
23//! for the entire process.
24//!
25//! To use either of these functions, we must first wrap our collector in a
26//! [`Dispatch`], a cloneable, type-erased reference to a collector. For
27//! example:
28//! ```rust
29//! # pub struct FooCollector;
30//! # use tracing_core::{
31//! #   dispatch, Event, Metadata,
32//! #   span::{Attributes, Current, Id, Record}
33//! # };
34//! # impl tracing_core::Collect for FooCollector {
35//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
36//! #   fn record(&self, _: &Id, _: &Record) {}
37//! #   fn event(&self, _: &Event) {}
38//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
39//! #   fn enabled(&self, _: &Metadata) -> bool { false }
40//! #   fn enter(&self, _: &Id) {}
41//! #   fn exit(&self, _: &Id) {}
42//! #   fn current_span(&self) -> Current { Current::unknown() }
43//! # }
44//! # impl FooCollector { fn new() -> Self { FooCollector } }
45//! # #[cfg(feature = "alloc")]
46//! use dispatch::Dispatch;
47//!
48//! # #[cfg(feature = "alloc")]
49//! let my_collector = FooCollector::new();
50//! # #[cfg(feature = "alloc")]
51//! let my_dispatch = Dispatch::new(my_collector);
52//! ```
53//! Then, we can use [`with_default`] to set our `Dispatch` as the default for
54//! the duration of a block:
55//! ```rust
56//! # pub struct FooCollector;
57//! # use tracing_core::{
58//! #   dispatch, Event, Metadata,
59//! #   span::{Attributes, Current, Id, Record}
60//! # };
61//! # impl tracing_core::Collect for FooCollector {
62//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
63//! #   fn record(&self, _: &Id, _: &Record) {}
64//! #   fn event(&self, _: &Event) {}
65//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
66//! #   fn enabled(&self, _: &Metadata) -> bool { false }
67//! #   fn enter(&self, _: &Id) {}
68//! #   fn exit(&self, _: &Id) {}
69//! #   fn current_span(&self) -> Current { Current::unknown() }
70//! # }
71//! # impl FooCollector { fn new() -> Self { FooCollector } }
72//! # #[cfg(feature = "alloc")]
73//! # let my_collector = FooCollector::new();
74//! # #[cfg(feature = "alloc")]
75//! # let my_dispatch = dispatch::Dispatch::new(my_collector);
76//! // no default collector
77//!
78//! # #[cfg(feature = "std")]
79//! dispatch::with_default(&my_dispatch, || {
80//!     // my_collector is the default
81//! });
82//!
83//! // no default collector again
84//! ```
85//! It's important to note that `with_default` will not propagate the current
86//! thread's default collector to any threads spawned within the `with_default`
87//! block. To propagate the default collector to new threads, either use
88//! `with_default` from the new thread, or use `set_global_default`.
89//!
90//! As an alternative to `with_default`, we can use [`set_global_default`] to
91//! set a `Dispatch` as the default for all threads, for the lifetime of the
92//! program. For example:
93//! ```rust
94//! # pub struct FooCollector;
95//! # use tracing_core::{
96//! #   dispatch, Event, Metadata,
97//! #   span::{Attributes, Current, Id, Record}
98//! # };
99//! # impl tracing_core::Collect for FooCollector {
100//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
101//! #   fn record(&self, _: &Id, _: &Record) {}
102//! #   fn event(&self, _: &Event) {}
103//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
104//! #   fn enabled(&self, _: &Metadata) -> bool { false }
105//! #   fn enter(&self, _: &Id) {}
106//! #   fn exit(&self, _: &Id) {}
107//! #   fn current_span(&self) -> Current { Current::unknown() }
108//! # }
109//! # impl FooCollector { fn new() -> Self { FooCollector } }
110//! # #[cfg(feature = "alloc")]
111//! # let my_collector = FooCollector::new();
112//! # #[cfg(feature = "alloc")]
113//! # let my_dispatch = dispatch::Dispatch::new(my_collector);
114//! // no default collector
115//!
116//! # #[cfg(feature = "alloc")]
117//! dispatch::set_global_default(my_dispatch)
118//!     // `set_global_default` will return an error if the global default
119//!     // collector has already been set.
120//!     .expect("global default was already set!");
121//!
122//! // `my_collector` is now the default
123//! ```
124//! <div class="example-wrap" style="display:inline-block">
125//! <pre class="ignore" style="white-space:normal;font:inherit;">
126//!
127//! **Note**: The thread-local scoped dispatcher (`with_default`)
128//! requires the Rust standard library. `no_std` users should
129//! use [`set_global_default()`] instead.
130//!
131//! </pre></div>
132//!
133//! ## Accessing the Default Collector
134//!
135//! A thread's current default collector can be accessed using the
136//! [`get_default`] function, which executes a closure with a reference to the
137//! currently default `Dispatch`. This is used primarily by `tracing`
138//! instrumentation.
139//!
140//! [`Collect`]: tracing_core::Collect
141#[cfg(feature = "std")]
142#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
143pub use tracing_core::dispatch::set_default;
144#[cfg(feature = "std")]
145#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
146pub use tracing_core::dispatch::with_default;
147#[cfg(feature = "std")]
148#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
149pub use tracing_core::dispatch::DefaultGuard;
150pub use tracing_core::dispatch::{
151    get_default, set_global_default, Dispatch, SetGlobalDefaultError, WeakDispatch,
152};
153
154/// Private API for internal use by tracing's macros.
155///
156/// This function is *not* considered part of `tracing`'s public API, and has no
157/// stability guarantees. If you use it, and it breaks or disappears entirely,
158/// don't say we didn't warn you.
159#[doc(hidden)]
160pub use tracing_core::dispatch::has_been_set;