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
113 //!     (<a href="#fn.with_default"><code>with_default</code></a>) requires the
114 //!     Rust standard library. <code>no_std</code> users should use
115 //!     <a href="#fn.set_global_default"><code>set_global_default</code></a>
116 //!     instead.
117 //! </pre>
118 //!
119 //! ## Accessing the Default Subscriber
120 //!
121 //! A thread's current default subscriber can be accessed using the
122 //! [`get_default`] function, which executes a closure with a reference to the
123 //! currently default `Dispatch`. This is used primarily by `tracing`
124 //! instrumentation.
125 //!
126 use crate::{
127     callsite, span,
128     subscriber::{self, NoSubscriber, Subscriber},
129     Event, LevelFilter, Metadata,
130 };
131 
132 use crate::stdlib::{
133     any::Any,
134     fmt,
135     sync::{
136         atomic::{AtomicBool, AtomicUsize, Ordering},
137         Arc, Weak,
138     },
139 };
140 
141 #[cfg(feature = "std")]
142 use crate::stdlib::{
143     cell::{Cell, Ref, RefCell},
144     error,
145 };
146 
147 #[cfg(feature = "alloc")]
148 use alloc::sync::{Arc, Weak};
149 
150 #[cfg(feature = "alloc")]
151 use core::ops::Deref;
152 
153 /// `Dispatch` trace data to a [`Subscriber`].
154 #[derive(Clone)]
155 pub struct Dispatch {
156     subscriber: Kind<Arc<dyn Subscriber + Send + Sync>>,
157 }
158 
159 /// `WeakDispatch` is a version of [`Dispatch`] that holds a non-owning reference
160 /// to a [`Subscriber`].
161 ///
162 /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
163 /// which returns an `Option<Dispatch>`. If all [`Dispatch`] clones that point
164 /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return
165 /// `None`. Otherwise, it will return `Some(Dispatch)`.
166 ///
167 /// A `WeakDispatch` may be created from a [`Dispatch`] by calling the
168 /// [`Dispatch::downgrade`] method. The primary use for creating a
169 /// [`WeakDispatch`] is to allow a Subscriber` to hold a cyclical reference to
170 /// itself without creating a memory leak. See [here] for details.
171 ///
172 /// This type is analogous to the [`std::sync::Weak`] type, but for a
173 /// [`Dispatch`] rather than an [`Arc`].
174 ///
175 /// [`Arc`]: std::sync::Arc
176 /// [here]: Subscriber#avoiding-memory-leaks
177 #[derive(Clone)]
178 pub struct WeakDispatch {
179     subscriber: Kind<Weak<dyn Subscriber + Send + Sync>>,
180 }
181 
182 #[derive(Clone)]
183 enum Kind<T> {
184     Global(&'static (dyn Subscriber + Send + Sync)),
185     Scoped(T),
186 }
187 
188 #[cfg(feature = "std")]
189 thread_local! {
190     static CURRENT_STATE: State = State {
191         default: RefCell::new(None),
192         can_enter: Cell::new(true),
193     };
194 }
195 
196 static EXISTS: AtomicBool = AtomicBool::new(false);
197 static GLOBAL_INIT: AtomicUsize = AtomicUsize::new(UNINITIALIZED);
198 
199 #[cfg(feature = "std")]
200 static SCOPED_COUNT: AtomicUsize = AtomicUsize::new(0);
201 
202 const UNINITIALIZED: usize = 0;
203 const INITIALIZING: usize = 1;
204 const INITIALIZED: usize = 2;
205 
206 static mut GLOBAL_DISPATCH: Dispatch = Dispatch {
207     subscriber: Kind::Global(&NO_SUBSCRIBER),
208 };
209 static NONE: Dispatch = Dispatch {
210     subscriber: Kind::Global(&NO_SUBSCRIBER),
211 };
212 static NO_SUBSCRIBER: NoSubscriber = NoSubscriber::new();
213 
214 /// The dispatch state of a thread.
215 #[cfg(feature = "std")]
216 struct State {
217     /// This thread's current default dispatcher.
218     default: RefCell<Option<Dispatch>>,
219     /// Whether or not we can currently begin dispatching a trace event.
220     ///
221     /// This is set to `false` when functions such as `enter`, `exit`, `event`,
222     /// and `new_span` are called on this thread's default dispatcher, to
223     /// prevent further trace events triggered inside those functions from
224     /// creating an infinite recursion. When we finish handling a dispatch, this
225     /// is set back to `true`.
226     can_enter: Cell<bool>,
227 }
228 
229 /// While this guard is active, additional calls to subscriber functions on
230 /// the default dispatcher will not be able to access the dispatch context.
231 /// Dropping the guard will allow the dispatch context to be re-entered.
232 #[cfg(feature = "std")]
233 struct Entered<'a>(&'a State);
234 
235 /// A guard that resets the current default dispatcher to the prior
236 /// default dispatcher when dropped.
237 #[cfg(feature = "std")]
238 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
239 #[derive(Debug)]
240 pub struct DefaultGuard(Option<Dispatch>);
241 
242 /// Sets this dispatch as the default for the duration of a closure.
243 ///
244 /// The default dispatcher is used when creating a new [span] or
245 /// [`Event`].
246 ///
247 /// <pre class="ignore" style="white-space:normal;font:inherit;">
248 ///     <strong>Note</strong>: This function required the Rust standard library.
249 ///     <code>no_std</code> users should use <a href="../fn.set_global_default.html">
250 ///     <code>set_global_default</code></a> instead.
251 /// </pre>
252 ///
253 /// [span]: super::span
254 /// [`Subscriber`]: super::subscriber::Subscriber
255 /// [`Event`]: super::event::Event
256 /// [`set_global_default`]: super::set_global_default
257 #[cfg(feature = "std")]
258 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
with_default<T>(dispatcher: &Dispatch, f: impl FnOnce() -> T) -> T259 pub fn with_default<T>(dispatcher: &Dispatch, f: impl FnOnce() -> T) -> T {
260     // When this guard is dropped, the default dispatcher will be reset to the
261     // prior default. Using this (rather than simply resetting after calling
262     // `f`) ensures that we always reset to the prior dispatcher even if `f`
263     // panics.
264     let _guard = set_default(dispatcher);
265     f()
266 }
267 
268 /// Sets the dispatch as the default dispatch for the duration of the lifetime
269 /// of the returned DefaultGuard
270 ///
271 /// <pre class="ignore" style="white-space:normal;font:inherit;">
272 ///     <strong>Note</strong>: This function required the Rust standard library.
273 ///     <code>no_std</code> users should use <a href="../fn.set_global_default.html">
274 ///     <code>set_global_default</code></a> instead.
275 /// </pre>
276 ///
277 /// [`set_global_default`]: super::set_global_default
278 #[cfg(feature = "std")]
279 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
280 #[must_use = "Dropping the guard unregisters the dispatcher."]
set_default(dispatcher: &Dispatch) -> DefaultGuard281 pub fn set_default(dispatcher: &Dispatch) -> DefaultGuard {
282     // When this guard is dropped, the default dispatcher will be reset to the
283     // prior default. Using this ensures that we always reset to the prior
284     // dispatcher even if the thread calling this function panics.
285     State::set_default(dispatcher.clone())
286 }
287 
288 /// Sets this dispatch as the global default for the duration of the entire program.
289 /// Will be used as a fallback if no thread-local dispatch has been set in a thread
290 /// (using `with_default`.)
291 ///
292 /// Can only be set once; subsequent attempts to set the global default will fail.
293 /// Returns `Err` if the global default has already been set.
294 ///
295 /// <div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
296 ///     <strong>Warning</strong>: In general, libraries should <em>not</em> call
297 ///     <code>set_global_default()</code>! Doing so will cause conflicts when
298 ///     executables that depend on the library try to set the default later.
299 /// </pre></div>
300 ///
301 /// [span]: super::span
302 /// [`Subscriber`]: super::subscriber::Subscriber
303 /// [`Event`]: super::event::Event
set_global_default(dispatcher: Dispatch) -> Result<(), SetGlobalDefaultError>304 pub fn set_global_default(dispatcher: Dispatch) -> Result<(), SetGlobalDefaultError> {
305     // if `compare_exchange` returns Result::Ok(_), then `new` has been set and
306     // `current`—now the prior value—has been returned in the `Ok()` branch.
307     if GLOBAL_INIT
308         .compare_exchange(
309             UNINITIALIZED,
310             INITIALIZING,
311             Ordering::SeqCst,
312             Ordering::SeqCst,
313         )
314         .is_ok()
315     {
316         let subscriber = {
317             let subscriber = match dispatcher.subscriber {
318                 Kind::Global(s) => s,
319                 Kind::Scoped(s) => unsafe {
320                     // safety: this leaks the subscriber onto the heap. the
321                     // reference count will always be at least 1, because the
322                     // global default will never be dropped.
323                     &*Arc::into_raw(s)
324                 },
325             };
326             Kind::Global(subscriber)
327         };
328         unsafe {
329             GLOBAL_DISPATCH = Dispatch { subscriber };
330         }
331         GLOBAL_INIT.store(INITIALIZED, Ordering::SeqCst);
332         EXISTS.store(true, Ordering::Release);
333         Ok(())
334     } else {
335         Err(SetGlobalDefaultError { _no_construct: () })
336     }
337 }
338 
339 /// Returns true if a `tracing` dispatcher has ever been set.
340 ///
341 /// This may be used to completely elide trace points if tracing is not in use
342 /// at all or has yet to be initialized.
343 #[doc(hidden)]
344 #[inline(always)]
has_been_set() -> bool345 pub fn has_been_set() -> bool {
346     EXISTS.load(Ordering::Relaxed)
347 }
348 
349 /// Returned if setting the global dispatcher fails.
350 pub struct SetGlobalDefaultError {
351     _no_construct: (),
352 }
353 
354 impl fmt::Debug for SetGlobalDefaultError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result355     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356         f.debug_tuple("SetGlobalDefaultError")
357             .field(&Self::MESSAGE)
358             .finish()
359     }
360 }
361 
362 impl fmt::Display for SetGlobalDefaultError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result363     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364         f.pad(Self::MESSAGE)
365     }
366 }
367 
368 #[cfg(feature = "std")]
369 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
370 impl error::Error for SetGlobalDefaultError {}
371 
372 impl SetGlobalDefaultError {
373     const MESSAGE: &'static str = "a global default trace dispatcher has already been set";
374 }
375 
376 /// Executes a closure with a reference to this thread's current [dispatcher].
377 ///
378 /// Note that calls to `get_default` should not be nested; if this function is
379 /// called while inside of another `get_default`, that closure will be provided
380 /// with `Dispatch::none` rather than the previously set dispatcher.
381 ///
382 /// [dispatcher]: super::dispatcher::Dispatch
383 #[cfg(feature = "std")]
get_default<T, F>(mut f: F) -> T where F: FnMut(&Dispatch) -> T,384 pub fn get_default<T, F>(mut f: F) -> T
385 where
386     F: FnMut(&Dispatch) -> T,
387 {
388     if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
389         // fast path if no scoped dispatcher has been set; just use the global
390         // default.
391         return f(get_global());
392     }
393 
394     CURRENT_STATE
395         .try_with(|state| {
396             if let Some(entered) = state.enter() {
397                 return f(&entered.current());
398             }
399 
400             f(&NONE)
401         })
402         .unwrap_or_else(|_| f(&NONE))
403 }
404 
405 /// Executes a closure with a reference to this thread's current [dispatcher].
406 ///
407 /// Note that calls to `get_default` should not be nested; if this function is
408 /// called while inside of another `get_default`, that closure will be provided
409 /// with `Dispatch::none` rather than the previously set dispatcher.
410 ///
411 /// [dispatcher]: super::dispatcher::Dispatch
412 #[cfg(feature = "std")]
413 #[doc(hidden)]
414 #[inline(never)]
get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T>415 pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
416     if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
417         // fast path if no scoped dispatcher has been set; just use the global
418         // default.
419         return Some(f(get_global()));
420     }
421 
422     CURRENT_STATE
423         .try_with(|state| {
424             let entered = state.enter()?;
425             Some(f(&entered.current()))
426         })
427         .ok()?
428 }
429 
430 /// Executes a closure with a reference to the current [dispatcher].
431 ///
432 /// [dispatcher]: super::dispatcher::Dispatch
433 #[cfg(not(feature = "std"))]
434 #[doc(hidden)]
get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T>435 pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
436     Some(f(get_global()))
437 }
438 
439 /// Executes a closure with a reference to the current [dispatcher].
440 ///
441 /// [dispatcher]: super::dispatcher::Dispatch
442 #[cfg(not(feature = "std"))]
get_default<T, F>(mut f: F) -> T where F: FnMut(&Dispatch) -> T,443 pub fn get_default<T, F>(mut f: F) -> T
444 where
445     F: FnMut(&Dispatch) -> T,
446 {
447     f(&get_global())
448 }
449 
450 #[inline]
get_global() -> &'static Dispatch451 fn get_global() -> &'static Dispatch {
452     if GLOBAL_INIT.load(Ordering::SeqCst) != INITIALIZED {
453         return &NONE;
454     }
455     unsafe {
456         // This is safe given the invariant that setting the global dispatcher
457         // also sets `GLOBAL_INIT` to `INITIALIZED`.
458         &GLOBAL_DISPATCH
459     }
460 }
461 
462 #[cfg(feature = "std")]
463 pub(crate) struct Registrar(Kind<Weak<dyn Subscriber + Send + Sync>>);
464 
465 impl Dispatch {
466     /// Returns a new `Dispatch` that discards events and spans.
467     #[inline]
none() -> Self468     pub fn none() -> Self {
469         Dispatch {
470             subscriber: Kind::Global(&NO_SUBSCRIBER),
471         }
472     }
473 
474     /// Returns a `Dispatch` that forwards to the given [`Subscriber`].
475     ///
476     /// [`Subscriber`]: super::subscriber::Subscriber
new<S>(subscriber: S) -> Self where S: Subscriber + Send + Sync + 'static,477     pub fn new<S>(subscriber: S) -> Self
478     where
479         S: Subscriber + Send + Sync + 'static,
480     {
481         let me = Dispatch {
482             subscriber: Kind::Scoped(Arc::new(subscriber)),
483         };
484         callsite::register_dispatch(&me);
485         me
486     }
487 
488     #[cfg(feature = "std")]
registrar(&self) -> Registrar489     pub(crate) fn registrar(&self) -> Registrar {
490         Registrar(self.subscriber.downgrade())
491     }
492 
493     /// Creates a [`WeakDispatch`] from this `Dispatch`.
494     ///
495     /// A [`WeakDispatch`] is similar to a [`Dispatch`], but it does not prevent
496     /// the underlying [`Subscriber`] from being dropped. Instead, it only permits
497     /// access while other references to the `Subscriber` exist. This is equivalent
498     /// to the standard library's [`Arc::downgrade`] method, but for `Dispatch`
499     /// rather than `Arc`.
500     ///
501     /// The primary use for creating a [`WeakDispatch`] is to allow a `Subscriber`
502     /// to hold a cyclical reference to itself without creating a memory leak.
503     /// See [here] for details.
504     ///
505     /// [`Arc::downgrade`]: std::sync::Arc::downgrade
506     /// [here]: Subscriber#avoiding-memory-leaks
downgrade(&self) -> WeakDispatch507     pub fn downgrade(&self) -> WeakDispatch {
508         WeakDispatch {
509             subscriber: self.subscriber.downgrade(),
510         }
511     }
512 
513     #[inline(always)]
subscriber(&self) -> &(dyn Subscriber + Send + Sync)514     pub(crate) fn subscriber(&self) -> &(dyn Subscriber + Send + Sync) {
515         match self.subscriber {
516             Kind::Global(s) => s,
517             Kind::Scoped(ref s) => s.as_ref(),
518         }
519     }
520 
521     /// Registers a new callsite with this subscriber, returning whether or not
522     /// the subscriber is interested in being notified about the callsite.
523     ///
524     /// This calls the [`register_callsite`] function on the [`Subscriber`]
525     /// that this `Dispatch` forwards to.
526     ///
527     /// [`Subscriber`]: super::subscriber::Subscriber
528     /// [`register_callsite`]: super::subscriber::Subscriber::register_callsite
529     #[inline]
register_callsite(&self, metadata: &'static Metadata<'static>) -> subscriber::Interest530     pub fn register_callsite(&self, metadata: &'static Metadata<'static>) -> subscriber::Interest {
531         self.subscriber().register_callsite(metadata)
532     }
533 
534     /// Returns the highest [verbosity level][level] that this [`Subscriber`] will
535     /// enable, or `None`, if the subscriber does not implement level-based
536     /// filtering or chooses not to implement this method.
537     ///
538     /// This calls the [`max_level_hint`] function on the [`Subscriber`]
539     /// that this `Dispatch` forwards to.
540     ///
541     /// [level]: super::Level
542     /// [`Subscriber`]: super::subscriber::Subscriber
543     /// [`register_callsite`]: super::subscriber::Subscriber::max_level_hint
544     // TODO(eliza): consider making this a public API?
545     #[inline]
max_level_hint(&self) -> Option<LevelFilter>546     pub(crate) fn max_level_hint(&self) -> Option<LevelFilter> {
547         self.subscriber().max_level_hint()
548     }
549 
550     /// Record the construction of a new span, returning a new [ID] for the
551     /// span being constructed.
552     ///
553     /// This calls the [`new_span`] function on the [`Subscriber`] that this
554     /// `Dispatch` forwards to.
555     ///
556     /// [ID]: super::span::Id
557     /// [`Subscriber`]: super::subscriber::Subscriber
558     /// [`new_span`]: super::subscriber::Subscriber::new_span
559     #[inline]
new_span(&self, span: &span::Attributes<'_>) -> span::Id560     pub fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
561         self.subscriber().new_span(span)
562     }
563 
564     /// Record a set of values on a span.
565     ///
566     /// This calls the [`record`] function on the [`Subscriber`] that this
567     /// `Dispatch` forwards to.
568     ///
569     /// [`Subscriber`]: super::subscriber::Subscriber
570     /// [`record`]: super::subscriber::Subscriber::record
571     #[inline]
record(&self, span: &span::Id, values: &span::Record<'_>)572     pub fn record(&self, span: &span::Id, values: &span::Record<'_>) {
573         self.subscriber().record(span, values)
574     }
575 
576     /// Adds an indication that `span` follows from the span with the id
577     /// `follows`.
578     ///
579     /// This calls the [`record_follows_from`] function on the [`Subscriber`]
580     /// that this `Dispatch` forwards to.
581     ///
582     /// [`Subscriber`]: super::subscriber::Subscriber
583     /// [`record_follows_from`]: super::subscriber::Subscriber::record_follows_from
584     #[inline]
record_follows_from(&self, span: &span::Id, follows: &span::Id)585     pub fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
586         self.subscriber().record_follows_from(span, follows)
587     }
588 
589     /// Returns true if a span with the specified [metadata] would be
590     /// recorded.
591     ///
592     /// This calls the [`enabled`] function on the [`Subscriber`] that this
593     /// `Dispatch` forwards to.
594     ///
595     /// [metadata]: super::metadata::Metadata
596     /// [`Subscriber`]: super::subscriber::Subscriber
597     /// [`enabled`]: super::subscriber::Subscriber::enabled
598     #[inline]
enabled(&self, metadata: &Metadata<'_>) -> bool599     pub fn enabled(&self, metadata: &Metadata<'_>) -> bool {
600         self.subscriber().enabled(metadata)
601     }
602 
603     /// Records that an [`Event`] has occurred.
604     ///
605     /// This calls the [`event`] function on the [`Subscriber`] that this
606     /// `Dispatch` forwards to.
607     ///
608     /// [`Event`]: super::event::Event
609     /// [`Subscriber`]: super::subscriber::Subscriber
610     /// [`event`]: super::subscriber::Subscriber::event
611     #[inline]
event(&self, event: &Event<'_>)612     pub fn event(&self, event: &Event<'_>) {
613         let subscriber = self.subscriber();
614         if subscriber.event_enabled(event) {
615             subscriber.event(event);
616         }
617     }
618 
619     /// Records that a span has been can_enter.
620     ///
621     /// This calls the [`enter`] function on the [`Subscriber`] that this
622     /// `Dispatch` forwards to.
623     ///
624     /// [`Subscriber`]: super::subscriber::Subscriber
625     /// [`enter`]: super::subscriber::Subscriber::enter
enter(&self, span: &span::Id)626     pub fn enter(&self, span: &span::Id) {
627         self.subscriber().enter(span);
628     }
629 
630     /// Records that a span has been exited.
631     ///
632     /// This calls the [`exit`] function on the [`Subscriber`] that this
633     /// `Dispatch` forwards to.
634     ///
635     /// [`Subscriber`]: super::subscriber::Subscriber
636     /// [`exit`]: super::subscriber::Subscriber::exit
exit(&self, span: &span::Id)637     pub fn exit(&self, span: &span::Id) {
638         self.subscriber().exit(span);
639     }
640 
641     /// Notifies the subscriber that a [span ID] has been cloned.
642     ///
643     /// This function must only be called with span IDs that were returned by
644     /// this `Dispatch`'s [`new_span`] function. The `tracing` crate upholds
645     /// this guarantee and any other libraries implementing instrumentation APIs
646     /// must as well.
647     ///
648     /// This calls the [`clone_span`] function on the `Subscriber` that this
649     /// `Dispatch` forwards to.
650     ///
651     /// [span ID]: super::span::Id
652     /// [`Subscriber`]: super::subscriber::Subscriber
653     /// [`clone_span`]: super::subscriber::Subscriber::clone_span
654     /// [`new_span`]: super::subscriber::Subscriber::new_span
655     #[inline]
clone_span(&self, id: &span::Id) -> span::Id656     pub fn clone_span(&self, id: &span::Id) -> span::Id {
657         self.subscriber().clone_span(id)
658     }
659 
660     /// Notifies the subscriber that a [span ID] has been dropped.
661     ///
662     /// This function must only be called with span IDs that were returned by
663     /// this `Dispatch`'s [`new_span`] function. The `tracing` crate upholds
664     /// this guarantee and any other libraries implementing instrumentation APIs
665     /// must as well.
666     ///
667     /// This calls the [`drop_span`] function on the [`Subscriber`] that this
668     /// `Dispatch` forwards to.
669     ///
670     /// <pre class="compile_fail" style="white-space:normal;font:inherit;">
671     ///     <strong>Deprecated</strong>: The <a href="#method.try_close"><code>
672     ///     try_close</code></a> method is functionally identical, but returns
673     ///     <code>true</code> if the span is now closed. It should be used
674     ///     instead of this method.
675     /// </pre>
676     ///
677     /// [span ID]: super::span::Id
678     /// [`Subscriber`]: super::subscriber::Subscriber
679     /// [`drop_span`]: super::subscriber::Subscriber::drop_span
680     /// [`new_span`]: super::subscriber::Subscriber::new_span
681     /// [`try_close`]: Entered::try_close()
682     #[inline]
683     #[deprecated(since = "0.1.2", note = "use `Dispatch::try_close` instead")]
drop_span(&self, id: span::Id)684     pub fn drop_span(&self, id: span::Id) {
685         #[allow(deprecated)]
686         self.subscriber().drop_span(id);
687     }
688 
689     /// Notifies the subscriber that a [span ID] has been dropped, and returns
690     /// `true` if there are now 0 IDs referring to that span.
691     ///
692     /// This function must only be called with span IDs that were returned by
693     /// this `Dispatch`'s [`new_span`] function. The `tracing` crate upholds
694     /// this guarantee and any other libraries implementing instrumentation APIs
695     /// must as well.
696     ///
697     /// This calls the [`try_close`] function on the [`Subscriber`] that this
698     ///  `Dispatch` forwards to.
699     ///
700     /// [span ID]: super::span::Id
701     /// [`Subscriber`]: super::subscriber::Subscriber
702     /// [`try_close`]: super::subscriber::Subscriber::try_close
703     /// [`new_span`]: super::subscriber::Subscriber::new_span
try_close(&self, id: span::Id) -> bool704     pub fn try_close(&self, id: span::Id) -> bool {
705         self.subscriber().try_close(id)
706     }
707 
708     /// Returns a type representing this subscriber's view of the current span.
709     ///
710     /// This calls the [`current`] function on the `Subscriber` that this
711     /// `Dispatch` forwards to.
712     ///
713     /// [`current`]: super::subscriber::Subscriber::current_span
714     #[inline]
current_span(&self) -> span::Current715     pub fn current_span(&self) -> span::Current {
716         self.subscriber().current_span()
717     }
718 
719     /// Returns `true` if this `Dispatch` forwards to a `Subscriber` of type
720     /// `T`.
721     #[inline]
is<T: Any>(&self) -> bool722     pub fn is<T: Any>(&self) -> bool {
723         <dyn Subscriber>::is::<T>(self.subscriber())
724     }
725 
726     /// Returns some reference to the `Subscriber` this `Dispatch` forwards to
727     /// if it is of type `T`, or `None` if it isn't.
728     #[inline]
downcast_ref<T: Any>(&self) -> Option<&T>729     pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
730         <dyn Subscriber>::downcast_ref(self.subscriber())
731     }
732 }
733 
734 impl Default for Dispatch {
735     /// Returns the current default dispatcher
default() -> Self736     fn default() -> Self {
737         get_default(|default| default.clone())
738     }
739 }
740 
741 impl fmt::Debug for Dispatch {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result742     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743         match self.subscriber {
744             Kind::Scoped(ref s) => f
745                 .debug_tuple("Dispatch::Scoped")
746                 .field(&format_args!("{:p}", s))
747                 .finish(),
748             Kind::Global(s) => f
749                 .debug_tuple("Dispatch::Global")
750                 .field(&format_args!("{:p}", s))
751                 .finish(),
752         }
753     }
754 }
755 
756 impl<S> From<S> for Dispatch
757 where
758     S: Subscriber + Send + Sync + 'static,
759 {
760     #[inline]
from(subscriber: S) -> Self761     fn from(subscriber: S) -> Self {
762         Dispatch::new(subscriber)
763     }
764 }
765 
766 // === impl WeakDispatch ===
767 
768 impl WeakDispatch {
769     /// Attempts to upgrade this `WeakDispatch` to a [`Dispatch`].
770     ///
771     /// Returns `None` if the referenced `Dispatch` has already been dropped.
772     ///
773     /// ## Examples
774     ///
775     /// ```
776     /// # use tracing_core::subscriber::NoSubscriber;
777     /// # use tracing_core::dispatcher::Dispatch;
778     /// let strong = Dispatch::new(NoSubscriber::default());
779     /// let weak = strong.downgrade();
780     ///
781     /// // The strong here keeps it alive, so we can still access the object.
782     /// assert!(weak.upgrade().is_some());
783     ///
784     /// drop(strong); // But not any more.
785     /// assert!(weak.upgrade().is_none());
786     /// ```
upgrade(&self) -> Option<Dispatch>787     pub fn upgrade(&self) -> Option<Dispatch> {
788         self.subscriber
789             .upgrade()
790             .map(|subscriber| Dispatch { subscriber })
791     }
792 }
793 
794 impl fmt::Debug for WeakDispatch {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result795     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796         match self.subscriber {
797             Kind::Scoped(ref s) => f
798                 .debug_tuple("WeakDispatch::Scoped")
799                 .field(&format_args!("{:p}", s))
800                 .finish(),
801             Kind::Global(s) => f
802                 .debug_tuple("WeakDispatch::Global")
803                 .field(&format_args!("{:p}", s))
804                 .finish(),
805         }
806     }
807 }
808 
809 #[cfg(feature = "std")]
810 impl Registrar {
upgrade(&self) -> Option<Dispatch>811     pub(crate) fn upgrade(&self) -> Option<Dispatch> {
812         self.0.upgrade().map(|subscriber| Dispatch { subscriber })
813     }
814 }
815 
816 // ===== impl State =====
817 
818 impl Kind<Arc<dyn Subscriber + Send + Sync>> {
downgrade(&self) -> Kind<Weak<dyn Subscriber + Send + Sync>>819     fn downgrade(&self) -> Kind<Weak<dyn Subscriber + Send + Sync>> {
820         match self {
821             Kind::Global(s) => Kind::Global(*s),
822             Kind::Scoped(ref s) => Kind::Scoped(Arc::downgrade(s)),
823         }
824     }
825 }
826 
827 impl Kind<Weak<dyn Subscriber + Send + Sync>> {
upgrade(&self) -> Option<Kind<Arc<dyn Subscriber + Send + Sync>>>828     fn upgrade(&self) -> Option<Kind<Arc<dyn Subscriber + Send + Sync>>> {
829         match self {
830             Kind::Global(s) => Some(Kind::Global(*s)),
831             Kind::Scoped(ref s) => Some(Kind::Scoped(s.upgrade()?)),
832         }
833     }
834 }
835 
836 // ===== impl State =====
837 
838 #[cfg(feature = "std")]
839 impl State {
840     /// Replaces the current default dispatcher on this thread with the provided
841     /// dispatcher.Any
842     ///
843     /// Dropping the returned `ResetGuard` will reset the default dispatcher to
844     /// the previous value.
845     #[inline]
set_default(new_dispatch: Dispatch) -> DefaultGuard846     fn set_default(new_dispatch: Dispatch) -> DefaultGuard {
847         let prior = CURRENT_STATE
848             .try_with(|state| {
849                 state.can_enter.set(true);
850                 state.default.replace(Some(new_dispatch))
851             })
852             .ok()
853             .flatten();
854         EXISTS.store(true, Ordering::Release);
855         SCOPED_COUNT.fetch_add(1, Ordering::Release);
856         DefaultGuard(prior)
857     }
858 
859     #[inline]
enter(&self) -> Option<Entered<'_>>860     fn enter(&self) -> Option<Entered<'_>> {
861         if self.can_enter.replace(false) {
862             Some(Entered(self))
863         } else {
864             None
865         }
866     }
867 }
868 
869 // ===== impl Entered =====
870 
871 #[cfg(feature = "std")]
872 impl<'a> Entered<'a> {
873     #[inline]
current(&self) -> Ref<'a, Dispatch>874     fn current(&self) -> Ref<'a, Dispatch> {
875         let default = self.0.default.borrow();
876         Ref::map(default, |default| match default {
877             Some(default) => default,
878             None => get_global(),
879         })
880     }
881 }
882 
883 #[cfg(feature = "std")]
884 impl<'a> Drop for Entered<'a> {
885     #[inline]
drop(&mut self)886     fn drop(&mut self) {
887         self.0.can_enter.set(true);
888     }
889 }
890 
891 // ===== impl DefaultGuard =====
892 
893 #[cfg(feature = "std")]
894 impl Drop for DefaultGuard {
895     #[inline]
drop(&mut self)896     fn drop(&mut self) {
897         // Replace the dispatcher and then drop the old one outside
898         // of the thread-local context. Dropping the dispatch may
899         // lead to the drop of a subscriber which, in the process,
900         // could then also attempt to access the same thread local
901         // state -- causing a clash.
902         let prev = CURRENT_STATE.try_with(|state| state.default.replace(self.0.take()));
903         SCOPED_COUNT.fetch_sub(1, Ordering::Release);
904         drop(prev)
905     }
906 }
907 
908 #[cfg(test)]
909 mod test {
910     use super::*;
911     #[cfg(feature = "std")]
912     use crate::stdlib::sync::atomic::{AtomicUsize, Ordering};
913     use crate::{
914         callsite::Callsite,
915         metadata::{Kind, Level, Metadata},
916         subscriber::Interest,
917     };
918 
919     #[test]
dispatch_is()920     fn dispatch_is() {
921         let dispatcher = Dispatch::new(NoSubscriber::default());
922         assert!(dispatcher.is::<NoSubscriber>());
923     }
924 
925     #[test]
dispatch_downcasts()926     fn dispatch_downcasts() {
927         let dispatcher = Dispatch::new(NoSubscriber::default());
928         assert!(dispatcher.downcast_ref::<NoSubscriber>().is_some());
929     }
930 
931     struct TestCallsite;
932     static TEST_CALLSITE: TestCallsite = TestCallsite;
933     static TEST_META: Metadata<'static> = metadata! {
934         name: "test",
935         target: module_path!(),
936         level: Level::DEBUG,
937         fields: &[],
938         callsite: &TEST_CALLSITE,
939         kind: Kind::EVENT
940     };
941 
942     impl Callsite for TestCallsite {
set_interest(&self, _: Interest)943         fn set_interest(&self, _: Interest) {}
metadata(&self) -> &Metadata<'_>944         fn metadata(&self) -> &Metadata<'_> {
945             &TEST_META
946         }
947     }
948 
949     #[test]
950     #[cfg(feature = "std")]
events_dont_infinite_loop()951     fn events_dont_infinite_loop() {
952         // This test ensures that an event triggered within a subscriber
953         // won't cause an infinite loop of events.
954         struct TestSubscriber;
955         impl Subscriber for TestSubscriber {
956             fn enabled(&self, _: &Metadata<'_>) -> bool {
957                 true
958             }
959 
960             fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
961                 span::Id::from_u64(0xAAAA)
962             }
963 
964             fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
965 
966             fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
967 
968             fn event(&self, _: &Event<'_>) {
969                 static EVENTS: AtomicUsize = AtomicUsize::new(0);
970                 assert_eq!(
971                     EVENTS.fetch_add(1, Ordering::Relaxed),
972                     0,
973                     "event method called twice!"
974                 );
975                 Event::dispatch(&TEST_META, &TEST_META.fields().value_set(&[]))
976             }
977 
978             fn enter(&self, _: &span::Id) {}
979 
980             fn exit(&self, _: &span::Id) {}
981         }
982 
983         with_default(&Dispatch::new(TestSubscriber), || {
984             Event::dispatch(&TEST_META, &TEST_META.fields().value_set(&[]))
985         })
986     }
987 
988     #[test]
989     #[cfg(feature = "std")]
spans_dont_infinite_loop()990     fn spans_dont_infinite_loop() {
991         // This test ensures that a span created within a subscriber
992         // won't cause an infinite loop of new spans.
993 
994         fn mk_span() {
995             get_default(|current| {
996                 current.new_span(&span::Attributes::new(
997                     &TEST_META,
998                     &TEST_META.fields().value_set(&[]),
999                 ))
1000             });
1001         }
1002 
1003         struct TestSubscriber;
1004         impl Subscriber for TestSubscriber {
1005             fn enabled(&self, _: &Metadata<'_>) -> bool {
1006                 true
1007             }
1008 
1009             fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
1010                 static NEW_SPANS: AtomicUsize = AtomicUsize::new(0);
1011                 assert_eq!(
1012                     NEW_SPANS.fetch_add(1, Ordering::Relaxed),
1013                     0,
1014                     "new_span method called twice!"
1015                 );
1016                 mk_span();
1017                 span::Id::from_u64(0xAAAA)
1018             }
1019 
1020             fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
1021 
1022             fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
1023 
1024             fn event(&self, _: &Event<'_>) {}
1025 
1026             fn enter(&self, _: &span::Id) {}
1027 
1028             fn exit(&self, _: &span::Id) {}
1029         }
1030 
1031         with_default(&Dispatch::new(TestSubscriber), mk_span)
1032     }
1033 
1034     #[test]
default_no_subscriber()1035     fn default_no_subscriber() {
1036         let default_dispatcher = Dispatch::default();
1037         assert!(default_dispatcher.is::<NoSubscriber>());
1038     }
1039 
1040     #[cfg(feature = "std")]
1041     #[test]
default_dispatch()1042     fn default_dispatch() {
1043         struct TestSubscriber;
1044         impl Subscriber for TestSubscriber {
1045             fn enabled(&self, _: &Metadata<'_>) -> bool {
1046                 true
1047             }
1048 
1049             fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
1050                 span::Id::from_u64(0xAAAA)
1051             }
1052 
1053             fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
1054 
1055             fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
1056 
1057             fn event(&self, _: &Event<'_>) {}
1058 
1059             fn enter(&self, _: &span::Id) {}
1060 
1061             fn exit(&self, _: &span::Id) {}
1062         }
1063         let guard = set_default(&Dispatch::new(TestSubscriber));
1064         let default_dispatcher = Dispatch::default();
1065         assert!(default_dispatcher.is::<TestSubscriber>());
1066 
1067         drop(guard);
1068         let default_dispatcher = Dispatch::default();
1069         assert!(default_dispatcher.is::<NoSubscriber>());
1070     }
1071 }
1072