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