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