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

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

tracing_subscriber/subscribe/
mod.rs

1//! The [`Subscribe`] trait, a composable abstraction for building [collector]s.
2//!
3//! The [`Collect`] trait in `tracing-core` represents the _complete_ set of
4//! functionality required to consume `tracing` instrumentation. This means that
5//! a single `Collect` instance is a self-contained implementation of a
6//! complete strategy for collecting traces; but it _also_ means that the
7//! `Collect` trait cannot easily be composed with other collectors.
8//!
9//! In particular, [collector]s are responsible for generating [span IDs] and
10//! assigning them to spans. Since these IDs must uniquely identify a span
11//! within the context of the current trace, this means that there may only be
12//! a single collector for a given thread at any point in time —
13//! otherwise, there would be no authoritative source of span IDs.
14//!
15//! On the other hand, the majority of the [`Collect`] trait's functionality
16//! is composable: any number of subscribers may _observe_ events, span entry
17//! and exit, and so on, provided that there is a single authoritative source of
18//! span IDs. The [`Subscribe`] trait represents this composable subset of the
19//! [`Collect`] behavior; it can _observe_ events and spans, but does not
20//! assign IDs.
21//!
22//! # Composing Subscribers
23//!
24//! Since a [subscriber] does not implement a complete strategy for collecting
25//! traces, it must be composed with a [collector] in order to be used. The
26//! [`Subscribe`] trait is generic over a type parameter (called `C` in the trait
27//! definition), representing the types of `Collect` they can be composed
28//! with. Thus, a subscriber may be implemented that will only compose with a
29//! particular `Collect` implementation, or additional trait bounds may be
30//! added to constrain what types implementing `Collect` a subscriber can wrap.
31//!
32//! Subscribers may be added to a collector by using the [`CollectExt::with`]
33//! method, which is provided by `tracing-subscriber`'s [prelude]. This method
34//! returns a [`Layered`] struct that implements [`Collect`] by composing the
35//! `Subscribe` with the collector.
36//!
37//! For example:
38//! ```rust
39//! use tracing_subscriber::Subscribe;
40//! use tracing_subscriber::prelude::*;
41//! use tracing::Collect;
42//!
43//! pub struct MySubscriber {
44//!     // ...
45//! }
46//!
47//! impl<C: Collect> Subscribe<C> for MySubscriber {
48//!     // ...
49//! }
50//!
51//! pub struct MyCollector {
52//!     // ...
53//! }
54//!
55//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
56//! impl Collect for MyCollector {
57//!     // ...
58//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
59//! #   fn record(&self, _: &Id, _: &Record) {}
60//! #   fn event(&self, _: &Event) {}
61//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
62//! #   fn enabled(&self, _: &Metadata) -> bool { false }
63//! #   fn enter(&self, _: &Id) {}
64//! #   fn exit(&self, _: &Id) {}
65//! #   fn current_span(&self) -> tracing_core::span::Current { tracing_core::span::Current::none() }
66//! }
67//! # impl MySubscriber {
68//! # fn new() -> Self { Self {} }
69//! # }
70//! # impl MyCollector {
71//! # fn new() -> Self { Self { }}
72//! # }
73//!
74//! let collector = MyCollector::new()
75//!     .with(MySubscriber::new());
76//!
77//! tracing::collect::set_global_default(collector);
78//! ```
79//!
80//! Multiple subscriber may be composed in the same manner:
81//! ```rust
82//! # use tracing_subscriber::{Subscribe, subscribe::CollectExt};
83//! # use tracing::Collect;
84//! pub struct MyOtherSubscriber {
85//!     // ...
86//! }
87//!
88//! impl<C: Collect> Subscribe<C> for MyOtherSubscriber {
89//!     // ...
90//! }
91//!
92//! pub struct MyThirdSubscriber {
93//!     // ...
94//! }
95//!
96//! impl<C: Collect> Subscribe<C> for MyThirdSubscriber {
97//!     // ...
98//! }
99//! # pub struct MySubscriber {}
100//! # impl<C: Collect> Subscribe<C> for MySubscriber {}
101//! # pub struct MyCollector { }
102//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
103//! # impl Collect for MyCollector {
104//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
105//! #   fn record(&self, _: &Id, _: &Record) {}
106//! #   fn event(&self, _: &Event) {}
107//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
108//! #   fn enabled(&self, _: &Metadata) -> bool { false }
109//! #   fn current_span(&self) -> tracing_core::span::Current { tracing_core::span::Current::none() }
110//! #   fn enter(&self, _: &Id) {}
111//! #   fn exit(&self, _: &Id) {}
112//! }
113//! # impl MySubscriber {
114//! # fn new() -> Self { Self {} }
115//! # }
116//! # impl MyOtherSubscriber {
117//! # fn new() -> Self { Self {} }
118//! # }
119//! # impl MyThirdSubscriber {
120//! # fn new() -> Self { Self {} }
121//! # }
122//! # impl MyCollector {
123//! # fn new() -> Self { Self { }}
124//! # }
125//!
126//! let collect = MyCollector::new()
127//!     .with(MySubscriber::new())
128//!     .with(MyOtherSubscriber::new())
129//!     .with(MyThirdSubscriber::new());
130//!
131//! tracing::collect::set_global_default(collect);
132//! ```
133//!
134//! The [`Subscribe::with_collector`] constructs the [`Layered`] type from a
135//! [`Subscribe`] and [`Collect`], and is called by [`CollectExt::with`]. In
136//! general, it is more idiomatic to use [`CollectExt::with`], and treat
137//! [`Subscribe::with_collector`] as an implementation detail, as `with_collector`
138//! calls must be nested, leading to less clear code for the reader.
139//!
140//! ## Runtime Configuration With Subscribers
141//!
142//! In some cases, a particular [subscriber] may be enabled or disabled based on
143//! runtime configuration. This can introduce challenges, because the type of a
144//! layered [collector] depends on which subscribers are added to it: if an `if`
145//! or `match` expression adds some [`Subscribe`] implementation in one branch,
146//! and other subscribers in another, the [collector] values returned by those
147//! branches will have different types. For example, the following _will not_
148//! work:
149//!
150//! ```compile_fail
151//! # fn docs() -> Result<(), Box<dyn std::error::Error + 'static>> {
152//! # struct Config {
153//! #    is_prod: bool,
154//! #    path: &'static str,
155//! # }
156//! # let cfg = Config { is_prod: false, path: "debug.log" };
157//! use std::fs::File;
158//! use tracing_subscriber::{Registry, prelude::*};
159//!
160//! let stdout_log = tracing_subscriber::fmt::subscriber().pretty();
161//! let collector = Registry::default().with(stdout_log);
162//!
163//! // The compile error will occur here because the if and else
164//! // branches have different (and therefore incompatible) types.
165//! let collector = if cfg.is_prod {
166//!     let file = File::create(cfg.path)?;
167//!     let collector = tracing_subscriber::fmt::subscriber()
168//!         .json()
169//!         .with_writer(Arc::new(file));
170//!     collector.with(subscriber)
171//! } else {
172//!     collector
173//! };
174//!
175//! tracing::collect::set_global_default(collector)
176//!     .expect("Unable to set global collector");
177//! # Ok(()) }
178//! ```
179//!
180//! However, a [`Subscribe`] wrapped in an [`Option`] [also implements the `Subscribe`
181//! trait][option-impl]. This allows individual layers to be enabled or disabled at
182//! runtime while always producing a [`Collect`] of the same type. For
183//! example:
184//!
185//! ```
186//! # fn docs() -> Result<(), Box<dyn std::error::Error + 'static>> {
187//! # struct Config {
188//! #    is_prod: bool,
189//! #    path: &'static str,
190//! # }
191//! # let cfg = Config { is_prod: false, path: "debug.log" };
192//! use std::fs::File;
193//! use tracing_subscriber::{Registry, prelude::*};
194//!
195//! let stdout_log = tracing_subscriber::fmt::subscriber().pretty();
196//! let collector = Registry::default().with(stdout_log);
197//!
198//! // if `cfg.is_prod` is true, also log JSON-formatted logs to a file.
199//! let json_log = if cfg.is_prod {
200//!     let file = File::create(cfg.path)?;
201//!     let json_log = tracing_subscriber::fmt::subscriber()
202//!         .json()
203//!         .with_writer(file);
204//!     Some(json_log)
205//! } else {
206//!     None
207//! };
208//!
209//! // If `cfg.is_prod` is false, then `json` will be `None`, and this subscriber
210//! // will do nothing. However, the collector will still have the same type
211//! // regardless of whether the `Option`'s value is `None` or `Some`.
212//! let collector = collector.with(json_log);
213//!
214//! tracing::collect::set_global_default(collector)
215//!    .expect("Unable to set global collector");
216//! # Ok(()) }
217//! ```
218//!
219//! If a subscriber may be one of several different types, note that [`Box<dyn
220//! Subscribe<C> + Send + Sync + 'static>` implements `Subscribe`][box-impl].
221//! This may be used to erase the type of a subscriber.
222//!
223//! For example, a function that configures a subscriber to log to one of
224//! several outputs might return a `Box<dyn Subscribe<C> + Send + Sync + 'static>`:
225//! ```
226//! use tracing_subscriber::{
227//!     Subscribe,
228//!     registry::LookupSpan,
229//!     prelude::*,
230//! };
231//! use std::{path::PathBuf, fs::File, io};
232//!
233//! /// Configures whether logs are emitted to a file, to stdout, or to stderr.
234//! pub enum LogConfig {
235//!     File(PathBuf),
236//!     Stdout,
237//!     Stderr,
238//! }
239//!
240//! impl LogConfig {
241//!     pub fn subscriber<C>(self) -> Box<dyn Subscribe<C> + Send + Sync + 'static>
242//!     where
243//!         C: tracing_core::Collect,
244//!         for<'a> C: LookupSpan<'a>,
245//!     {
246//!         // Shared configuration regardless of where logs are output to.
247//!         let fmt = tracing_subscriber::fmt::subscriber()
248//!             .with_target(true)
249//!             .with_thread_names(true);
250//!
251//!         // Configure the writer based on the desired log target:
252//!         match self {
253//!             LogConfig::File(path) => {
254//!                 let file = File::create(path).expect("failed to create log file");
255//!                 Box::new(fmt.with_writer(file))
256//!             },
257//!             LogConfig::Stdout => Box::new(fmt.with_writer(io::stdout)),
258//!             LogConfig::Stderr => Box::new(fmt.with_writer(io::stderr)),
259//!         }
260//!     }
261//! }
262//!
263//! let config = LogConfig::Stdout;
264//! tracing_subscriber::registry()
265//!     .with(config.subscriber())
266//!     .init();
267//! ```
268//!
269//! The [`Subscribe::boxed`] method is provided to make boxing a subscriber
270//! more convenient, but [`Box::new`] may be used as well.
271//!
272//! When the number of subscribers varies at runtime, note that a
273//! [`Vec<S> where S: Subscribe` also implements `Subscribe`][vec-impl]. This
274//! can be used to add a variable number of subscribers to a collector:
275//!
276//! ```
277//! use tracing_subscriber::{Subscribe, prelude::*};
278//! struct MySubscriber {
279//!     // ...
280//! }
281//! # impl MySubscriber { fn new() -> Self { Self {} }}
282//!
283//! impl<C: tracing_core::Collect> Subscribe<C> for MySubscriber {
284//!     // ...
285//! }
286//!
287//! /// Returns how many subscribers we need
288//! fn how_many_subscribers() -> usize {
289//!     // ...
290//!     # 3
291//! }
292//!
293//! // Create a variable-length `Vec` of subscribers
294//! let mut subscribers = Vec::new();
295//! for _ in 0..how_many_subscribers() {
296//!     subscribers.push(MySubscriber::new());
297//! }
298//!
299//! tracing_subscriber::registry()
300//!     .with(subscribers)
301//!     .init();
302//! ```
303//!
304//! If a variable number of subscribers is needed and those subscribers have
305//! different types, a `Vec` of [boxed subscriber trait objects][box-impl] may
306//! be used. For example:
307//!
308//! ```
309//! use tracing_subscriber::{filter::LevelFilter, Subscribe, prelude::*};
310//! use std::fs::File;
311//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
312//! struct Config {
313//!     enable_log_file: bool,
314//!     enable_stdout: bool,
315//!     enable_stderr: bool,
316//!     // ...
317//! }
318//! # impl Config {
319//! #    fn from_config_file()-> Result<Self, Box<dyn std::error::Error>> {
320//! #         // don't enable the log file so that the example doesn't actually create it
321//! #         Ok(Self { enable_log_file: false, enable_stdout: true, enable_stderr: true })
322//! #    }
323//! # }
324//!
325//! let cfg = Config::from_config_file()?;
326//!
327//! // Based on our dynamically loaded config file, create any number of subscribers:
328//! let mut subscribers = Vec::new();
329//!
330//! if cfg.enable_log_file {
331//!     let file = File::create("myapp.log")?;
332//!     let subscriber = tracing_subscriber::fmt::subscriber()
333//!         .with_thread_names(true)
334//!         .with_target(true)
335//!         .json()
336//!         .with_writer(file)
337//!         // Box the subscriber as a type-erased trait object, so that it can
338//!         // be pushed to the `Vec`.
339//!         .boxed();
340//!     subscribers.push(subscriber);
341//! }
342//!
343//! if cfg.enable_stdout {
344//!     let subscriber = tracing_subscriber::fmt::subscriber()
345//!         .pretty()
346//!         .with_filter(LevelFilter::INFO)
347//!         // Box the subscriber as a type-erased trait object, so that it can
348//!         // be pushed to the `Vec`.
349//!         .boxed();
350//!     subscribers.push(subscriber);
351//! }
352//!
353//! if cfg.enable_stdout {
354//!     let subscriber = tracing_subscriber::fmt::subscriber()
355//!         .with_target(false)
356//!         .with_filter(LevelFilter::WARN)
357//!         // Box the subscriber as a type-erased trait object, so that it can
358//!         // be pushed to the `Vec`.
359//!         .boxed();
360//!     subscribers.push(subscriber);
361//! }
362//!
363//! tracing_subscriber::registry()
364//!     .with(subscribers)
365//!     .init();
366//!# Ok(()) }
367//! ```
368//!
369//! Finally, if the number of subscribers _changes_ at runtime, a `Vec` of
370//! subscribers can be used alongside the [`reload`](crate::reload) module to
371//! add or remove subscribers dynamically at runtime.
372//!
373//! [prelude]: crate::prelude
374//! [option-impl]: crate::subscribe::Subscribe#impl-Subscribe<C>-for-Option<S>
375//! [box-impl]: Subscribe#impl-Subscribe%3CC%3E-for-Box%3Cdyn%20Subscribe%3CC%3E%20+%20Send%20+%20Sync%20+%20%27static%3E
376//! [vec-impl]: Subscribe#impl-Subscribe<C>-for-Vec<S>
377//!
378//! # Recording Traces
379//!
380//! The [`Subscribe`] trait defines a set of methods for consuming notifications from
381//! tracing instrumentation, which are generally equivalent to the similarly
382//! named methods on [`Collect`]. Unlike [`Collect`], the methods on
383//! `Subscribe` are additionally passed a [`Context`] type, which exposes additional
384//! information provided by the wrapped subscriber (such as [the current span])
385//! to the subscriber.
386//!
387//! # Filtering with `Subscriber`s
388//!
389//! As well as strategies for handling trace events, the `Subscribe` trait may also
390//! be used to represent composable _filters_. This allows the determination of
391//! what spans and events should be recorded to be decoupled from _how_ they are
392//! recorded: a filtering subscriber can be applied to other subscribers or
393//! subscribers. `Subscribe`s can be used to implement _global filtering_, where a
394//! `Subscribe` provides a filtering strategy for the entire subscriber.
395//! Additionally, individual recording `Subscribe`s or sets of `Subscribe`s may be
396//! combined with _per-subscriber filters_ that control what spans and events are
397//! recorded by those subscribers.
398//!
399//! ## Global Filtering
400//!
401//! A `Subscribe` that implements a filtering strategy should override the
402//! [`register_callsite`] and/or [`enabled`] methods. It may also choose to implement
403//! methods such as [`on_enter`], if it wishes to filter trace events based on
404//! the current span context.
405//!
406//! Note that the [`Subscribe::register_callsite`] and [`Subscribe::enabled`] methods
407//! determine whether a span or event is enabled *globally*. Thus, they should
408//! **not** be used to indicate whether an individual subscriber wishes to record a
409//! particular span or event. Instead, if a subscriber is only interested in a subset
410//! of trace data, but does *not* wish to disable other spans and events for the
411//! rest of the subscriber stack should ignore those spans and events in its
412//! notification methods.
413//!
414//! The filtering methods on a stack of `Subscribe`s are evaluated in a top-down
415//! order, starting with the outermost `Subscribe` and ending with the wrapped
416//! [`Collect`]. If any subscriber returns `false` from its [`enabled`] method, or
417//! [`Interest::never()`] from its [`register_callsite`] method, filter
418//! evaluation will short-circuit and the span or event will be disabled.
419//!
420//! ### Enabling Interest
421//!
422//! Whenever an tracing event (or span) is emitted, it goes through a number of
423//! steps to determine how and how much it should be processed. The earlier an
424//! event is disabled, the less work has to be done to process the event, so
425//! subscribers that implement filtering should attempt to disable unwanted
426//! events as early as possible. In order, each event checks:
427//!
428//! - [`register_callsite`], once per callsite (roughly: once per time that
429//!   `event!` or `span!` is written in the source code; this is cached at the
430//!   callsite). See [`Collect::register_callsite`] and
431//!   [`tracing_core::callsite`] for a summary of how this behaves.
432//! - [`enabled`], once per emitted event (roughly: once per time that `event!`
433//!   or `span!` is *executed*), and only if `register_callsite` registers an
434//!   [`Interest::sometimes`]. This is the main customization point to globally
435//!   filter events based on their [`Metadata`]. If an event can be disabled
436//!   based only on [`Metadata`], it should be, as this allows the construction
437//!   of the actual `Event`/`Span` to be skipped.
438//! - For events only (and not spans), [`event_enabled`] is called just before
439//!   processing the event. This gives subscribers one last chance to say that
440//!   an event should be filtered out, now that the event's fields are known.
441//!
442//! ## Per-Subscriber Filtering
443//!
444//! **Note**: per-subscriber filtering APIs currently require the [`"registry"` crate
445//! feature flag][feat] to be enabled.
446//!
447//! Sometimes, it may be desirable for one `Subscribe` to record a particular subset
448//! of spans and events, while a different subset of spans and events are
449//! recorded by other `Subscribe`s. For example:
450//!
451//! - A subscriber that records metrics may wish to observe only events including
452//!   particular tracked values, while a logging subscriber ignores those events.
453//! - If recording a distributed trace is expensive, it might be desirable to
454//!   only send spans with `INFO` and lower verbosity to the distributed tracing
455//!   system, while logging more verbose spans to a file.
456//! - Spans and events with a particular target might be recorded differently
457//!   from others, such as by generating an HTTP access log from a span that
458//!   tracks the lifetime of an HTTP request.
459//!
460//! The [`Filter`] trait is used to control what spans and events are
461//! observed by an individual `Subscribe`, while still allowing other `Subscribe`s to
462//! potentially record them. The [`Subscribe::with_filter`] method combines a
463//! `Subscribe` with a [`Filter`], returning a [`Filtered`] subscriber.
464//!
465//! This crate's [`filter`] module provides a number of types which implement
466//! the [`Filter`] trait, such as [`LevelFilter`], [`Targets`], and
467//! [`FilterFn`]. These [`Filter`]s provide ready-made implementations of common
468//! forms of filtering. For custom filtering policies, the [`FilterFn`] and
469//! [`DynFilterFn`] types allow implementing a [`Filter`] with a closure or
470//! function pointer. In addition, when more control is required, the [`Filter`]
471//! trait may also be implemented for user-defined types.
472//!
473//! [`Option<Filter>`] also implements [`Filter`], which allows for an optional
474//! filter. [`None`](Option::None) filters out _nothing_ (that is, allows
475//! everything through). For example:
476//!
477//! ```rust
478//! # use tracing_subscriber::{filter::filter_fn, Subscribe};
479//! # use tracing_core::{Metadata, collect::Collect};
480//! # struct MySubscriber<C>(std::marker::PhantomData<C>);
481//! # impl<C> MySubscriber<C> { fn new() -> Self { Self(std::marker::PhantomData)} }
482//! # impl<C: Collect> Subscribe<C> for MySubscriber<C> {}
483//! # fn my_filter(_: &str) -> impl Fn(&Metadata) -> bool { |_| true  }
484//! fn setup_tracing<C: Collect>(filter_config: Option<&str>) {
485//!     let layer = MySubscriber::<C>::new()
486//!         .with_filter(filter_config.map(|config| filter_fn(my_filter(config))));
487//! //...
488//! }
489//! ```
490//!
491//! <div class="example-wrap" style="display:inline-block">
492//! <pre class="compile_fail" style="white-space:normal;font:inherit;">
493//!     <strong>Warning</strong>: Currently, the <a href="../struct.Registry.html">
494//!     <code>Registry</code></a> type defined in this crate is the only root
495//!     <code>Collect</code> capable of supporting subscriberss with
496//!     per-subscriber filters. In the future, new APIs will be added to allow other
497//!     root <code>Collect</code>s to support per-subscriber filters.
498//! </pre></div>
499//!
500//! For example, to generate an HTTP access log based on spans with
501//! the `http_access` target, while logging other spans and events to
502//! standard out, a [`Filter`] can be added to the access log subscriber:
503//!
504//! ```
505//! use tracing_subscriber::{filter, prelude::*};
506//!
507//! // Generates an HTTP access log.
508//! let access_log = // ...
509//!     # filter::LevelFilter::INFO;
510//!
511//! // Add a filter to the access log subscriber so that it only observes
512//! // spans and events with the `http_access` target.
513//! let access_log = access_log.with_filter(filter::filter_fn(|metadata| {
514//!     // Returns `true` if and only if the span or event's target is
515//!     // "http_access".
516//!     metadata.target() == "http_access"
517//! }));
518//!
519//! // A general-purpose logging subscriber.
520//! let fmt_subscriber = tracing_subscriber::fmt::subscriber();
521//!
522//! // Build a subscriber that combines the access log and stdout log
523//! // subscribers.
524//! tracing_subscriber::registry()
525//!     .with(fmt_subscriber)
526//!     .with(access_log)
527//!     .init();
528//! ```
529//!
530//! Multiple subscribers can have their own, separate per-subscriber filters. A span or
531//! event will be recorded if it is enabled by _any_ per-subscriber filter, but it
532//! will be skipped by the subscribers whose filters did not enable it. Building on
533//! the previous example:
534//!
535//! ```
536//! use tracing_subscriber::{filter::{filter_fn, LevelFilter}, prelude::*};
537//!
538//! let access_log = // ...
539//!     # LevelFilter::INFO;
540//! let fmt_subscriber = tracing_subscriber::fmt::subscriber();
541//!
542//! tracing_subscriber::registry()
543//!     // Add the filter for the "http_access" target to the access
544//!     // log subscriber, like before.
545//!     .with(access_log.with_filter(filter_fn(|metadata| {
546//!         metadata.target() == "http_access"
547//!     })))
548//!     // Add a filter for spans and events with the INFO level
549//!     // and below to the logging subscriber.
550//!     .with(fmt_subscriber.with_filter(LevelFilter::INFO))
551//!     .init();
552//!
553//! // Neither subscriber will observe this event
554//! tracing::debug!(does_anyone_care = false, "a tree fell in the forest");
555//!
556//! // This event will be observed by the logging subscriber, but not
557//! // by the access log subscriber.
558//! tracing::warn!(dose_roentgen = %3.8, "not great, but not terrible");
559//!
560//! // This event will be observed only by the access log subscriber.
561//! tracing::trace!(target: "http_access", "HTTP request started");
562//!
563//! // Both subscribers will observe this event.
564//! tracing::error!(target: "http_access", "HTTP request failed with a very bad error!");
565//! ```
566//!
567//! A per-subscriber filter can be applied to multiple [`Subscribe`]s at a time, by
568//! combining them into a [`Layered`] subscriber using [`Subscribe::and_then`], and then
569//! calling [`Subscribe::with_filter`] on the resulting [`Layered`] subscriber.
570//!
571//! Consider the following:
572//! - `subscriber_a` and `subscriber_b`, which should only receive spans and events at
573//!   the [`INFO`] [level] and above.
574//! - A third subscriber, `subscriber_c`, which should receive spans and events at
575//!   the [`DEBUG`] [level] as well.
576//!
577//! The subscribers and filters would be composed thusly:
578//!
579//! ```
580//! use tracing_subscriber::{filter::LevelFilter, prelude::*};
581//!
582//! let subscriber_a = // ...
583//! # LevelFilter::INFO;
584//! let subscriber_b =  // ...
585//! # LevelFilter::INFO;
586//! let subscriber_c =  // ...
587//! # LevelFilter::INFO;
588//!
589//! let info_subscribers = subscriber_a
590//!     // Combine `subscriber_a` and `subscriber_b` into a `Layered` subscriber:
591//!     .and_then(subscriber_b)
592//!     // ...and then add an `INFO` `LevelFilter` to that subscriber:
593//!     .with_filter(LevelFilter::INFO);
594//!
595//! tracing_subscriber::registry()
596//!     // Add `subscriber_c` with a `DEBUG` filter.
597//!     .with(subscriber_c.with_filter(LevelFilter::DEBUG))
598//!     .with(info_subscribers)
599//!     .init();
600//!```
601//!
602//! If a [`Filtered`] [`Subscribe`] is combined with another [`Subscribe`]
603//! [`Subscribe::and_then`], and a filter is added to the [`Layered`] subscriber, that
604//! subscriber will be filtered by *both* the inner filter and the outer filter.
605//! Only spans and events that are enabled by *both* filters will be
606//! observed by that subscriber. This can be used to implement complex filtering
607//! trees.
608//!
609//! As an example, consider the following constraints:
610//! - Suppose that a particular [target] is used to indicate events that
611//!   should be counted as part of a metrics system, which should be only
612//!   observed by a subscriber that collects metrics.
613//! - A log of high-priority events ([`INFO`] and above) should be logged
614//!   to stdout, while more verbose events should be logged to a debugging log file.
615//! - Metrics-focused events should *not* be included in either log output.
616//!
617//! In that case, it is possible to apply a filter to both logging subscribers to
618//! exclude the metrics events, while additionally adding a [`LevelFilter`]
619//! to the stdout log:
620//!
621//! ```
622//! # // wrap this in a function so we don't actually create `debug.log` when
623//! # // running the doctests..
624//! # fn docs() -> Result<(), Box<dyn std::error::Error + 'static>> {
625//! use tracing_subscriber::{filter, prelude::*};
626//! use std::{fs::File, sync::Arc};
627//!
628//! // A subscriber that logs events to stdout using the human-readable "pretty"
629//! // format.
630//! let stdout_log = tracing_subscriber::fmt::subscriber()
631//!     .pretty();
632//!
633//! // A subscriber that logs events to a file.
634//! let file = File::create("debug.log")?;
635//! let debug_log = tracing_subscriber::fmt::subscriber()
636//!     .with_writer(file);
637//!
638//! // A subscriber that collects metrics using specific events.
639//! let metrics_subscriber = /* ... */ filter::LevelFilter::INFO;
640//!
641//! tracing_subscriber::registry()
642//!     .with(
643//!         stdout_log
644//!             // Add an `INFO` filter to the stdout logging subscriber
645//!             .with_filter(filter::LevelFilter::INFO)
646//!             // Combine the filtered `stdout_log` subscriber with the
647//!             // `debug_log` subscriber, producing a new `Layered` subscriber.
648//!             .and_then(debug_log)
649//!             // Add a filter to *both* subscribers that rejects spans and
650//!             // events whose targets start with `metrics`.
651//!             .with_filter(filter::filter_fn(|metadata| {
652//!                 !metadata.target().starts_with("metrics")
653//!             }))
654//!     )
655//!     .with(
656//!         // Add a filter to the metrics label that *only* enables
657//!         // events whose targets start with `metrics`.
658//!         metrics_subscriber.with_filter(filter::filter_fn(|metadata| {
659//!             metadata.target().starts_with("metrics")
660//!         }))
661//!     )
662//!     .init();
663//!
664//! // This event will *only* be recorded by the metrics subscriber.
665//! tracing::info!(target: "metrics::cool_stuff_count", value = 42);
666//!
667//! // This event will only be seen by the debug log file subscriber:
668//! tracing::debug!("this is a message, and part of a system of messages");
669//!
670//! // This event will be seen by both the stdout log subscriber *and*
671//! // the debug log file subscriber, but not by the metrics subscriber.
672//! tracing::warn!("the message is a warning about danger!");
673//! # Ok(()) }
674//! ```
675//!
676//! [subscriber]: Subscribe
677//! [`Collect`]:tracing_core::Collect
678//! [collector]: tracing_core::Collect
679//! [span IDs]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Id.html
680//! [the current span]: Context::current_span
681//! [`register_callsite`]: Subscribe::register_callsite
682//! [`enabled`]: Subscribe::enabled
683//! [`event_enabled`]: Subscribe::event_enabled
684//! [`on_enter`]: Subscribe::on_enter
685//! [`Subscribe::register_callsite`]: Subscribe::register_callsite
686//! [`Subscribe::enabled`]: Subscribe::enabled
687//! [`Interest::never()`]: tracing_core::collect::Interest::never
688//! [`Filtered`]: crate::filter::Filtered
689//! [`filter`]: crate::filter
690//! [`Targets`]: crate::filter::Targets
691//! [`FilterFn`]: crate::filter::FilterFn
692//! [`DynFilterFn`]: crate::filter::DynFilterFn
693//! [level]: tracing_core::Level
694//! [`INFO`]: tracing_core::Level::INFO
695//! [`DEBUG`]: tracing_core::Level::DEBUG
696//! [target]: tracing_core::Metadata::target
697//! [`LevelFilter`]: crate::filter::LevelFilter
698//! [feat]: crate#feature-flags
699use crate::filter;
700
701use tracing_core::{
702    collect::{Collect, Interest},
703    metadata::Metadata,
704    span, Dispatch, Event, LevelFilter,
705};
706
707use core::{any::TypeId, ptr::NonNull};
708
709feature! {
710    #![feature = "alloc"]
711    use alloc::boxed::Box;
712    use core::ops::{Deref, DerefMut};
713}
714
715mod context;
716mod layered;
717pub use self::{context::*, layered::*};
718
719// The `tests` module is `pub(crate)` because it contains test utilities used by
720// other modules.
721#[cfg(test)]
722pub(crate) mod tests;
723
724/// A composable handler for `tracing` events.
725///
726/// A type that implements `Subscribe` &mdash a "subscriber" &mdash; provides a
727/// particular behavior for recording or collecting traces that can
728/// be composed together with other subscribers to build a [collector]. See the
729/// [module-level documentation](crate::subscribe) for details.
730///
731/// [collector]: tracing_core::Collect
732#[cfg_attr(docsrs, doc(notable_trait))]
733pub trait Subscribe<C>
734where
735    C: Collect,
736    Self: 'static,
737{
738    /// Performs late initialization when installing this subscriber as a
739    /// [collector].
740    ///
741    /// ## Avoiding Memory Leaks
742    ///
743    /// Subscribers should not store the [`Dispatch`] pointing to the collector
744    /// that they are a part of. Because the `Dispatch` owns the collector,
745    /// storing the `Dispatch` within the collector will create a reference
746    /// count cycle, preventing the `Dispatch` from ever being dropped.
747    ///
748    /// Instead, when it is necessary to store a cyclical reference to the
749    /// `Dispatch` within a subscriber, use [`Dispatch::downgrade`] to convert a
750    /// `Dispatch` into a [`WeakDispatch`]. This type is analogous to
751    /// [`std::sync::Weak`], and does not create a reference count cycle. A
752    /// [`WeakDispatch`] can be stored within a subscriber without causing a
753    /// memory leak, and can be [upgraded] into a `Dispatch` temporarily when
754    /// the `Dispatch` must be accessed by the subscriber.
755    ///
756    /// [`WeakDispatch`]: tracing_core::dispatch::WeakDispatch
757    /// [upgraded]: tracing_core::dispatch::WeakDispatch::upgrade
758    /// [collector]: tracing_core::Collect
759    fn on_register_dispatch(&self, collector: &Dispatch) {
760        let _ = collector;
761    }
762
763    /// Performs late initialization when attaching a subscriber to a
764    /// [collector].
765    ///
766    /// This is a callback that is called when the `Subscribe` is added to a
767    /// [`Collect`] (e.g. in [`Subscribe::with_collector`] and
768    /// [`CollectExt::with`]). Since this can only occur before the
769    /// [`Collect`] has been set as the default, both the subscriber and
770    /// [`Collect`] are passed to this method _mutably_. This gives the
771    /// subscribe the opportunity to set any of its own fields with values
772    /// received by method calls on the [`Collect`].
773    ///
774    /// For example, [`Filtered`] subscribers implement `on_subscribe` to call the
775    /// [`Collect`]'s [`register_filter`] method, and store the returned
776    /// [`FilterId`] as a field.
777    ///
778    /// **Note** In most cases, subscriber implementations will not need to
779    /// implement this method. However, in cases where a type implementing
780    /// subscriber wraps one or more other types that implement `Subscribe`, like the
781    /// [`Layered`] and [`Filtered`] types in this crate, that type MUST ensure
782    /// that the inner `Subscribe` instance's' `on_subscribe` methods are
783    /// called. Otherwise, unctionality that relies on `on_subscribe`, such as
784    /// [per-subscriber filtering], may not work correctly.
785    ///
786    /// [`Filtered`]: crate::filter::Filtered
787    /// [`register_filter`]: crate::registry::LookupSpan::register_filter
788    /// [per-subscribe filtering]: #per-subscriber-filtering
789    /// [`FilterId`]: crate::filter::FilterId
790    /// [collector]: tracing_core::Collect
791    fn on_subscribe(&mut self, collector: &mut C) {
792        let _ = collector;
793    }
794
795    /// Registers a new callsite with this subscriber, returning whether or not
796    /// the subscriber is interested in being notified about the callsite, similarly
797    /// to [`Collect::register_callsite`].
798    ///
799    /// By default, this returns [`Interest::always()`] if [`self.enabled`] returns
800    /// true, or [`Interest::never()`] if it returns false.
801    ///
802    /// <div class="example-wrap" style="display:inline-block">
803    /// <pre class="ignore" style="white-space:normal;font:inherit;">
804    ///
805    /// **Note**: This method (and [`Subscribe::enabled`]) determine whether a span or event is
806    /// globally enabled, *not* whether the individual subscriber will be notified about that
807    /// span or event.  This is intended to be used by subscribers that implement filtering for
808    /// the entire stack. Subscribers which do not wish to be notified about certain spans or
809    /// events but do not wish to globally disable them should ignore those spans or events in
810    /// their [on_event][Self::on_event], [on_enter][Self::on_enter], [on_exit][Self::on_exit],
811    /// and other notification methods.
812    ///
813    /// </pre></div>
814    ///
815    /// See [the trait-level documentation] for more information on filtering
816    /// with subscribers.
817    ///
818    /// Subscribers may also implement this method to perform any behaviour that
819    /// should be run once per callsite. If the subscriber wishes to use
820    /// `register_callsite` for per-callsite behaviour, but does not want to
821    /// globally enable or disable those callsites, it should always return
822    /// [`Interest::always()`].
823    ///
824    /// [`Interest`]: tracing_core::collect::Interest
825    /// [`Collect::register_callsite`]: tracing_core::Collect::register_callsite()
826    /// [`self.enabled`]: Subscribe::enabled()
827    /// [the trait-level documentation]: #filtering-with-subscribers
828    fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
829        if self.enabled(metadata, Context::none()) {
830            Interest::always()
831        } else {
832            Interest::never()
833        }
834    }
835
836    /// Returns `true` if this subscriber is interested in a span or event with the
837    /// given `metadata` in the current [`Context`], similarly to
838    /// [`Collect::enabled`].
839    ///
840    /// By default, this always returns `true`, allowing the wrapped collector
841    /// to choose to disable the span.
842    ///
843    /// <div class="example-wrap" style="display:inline-block">
844    /// <pre class="ignore" style="white-space:normal;font:inherit;">
845    ///
846    /// **Note**: This method (and [`register_callsite`][Self::register_callsite])
847    /// determine whether a span or event is
848    /// globally enabled, *not* whether the individual subscriber will be
849    /// notified about that span or event. This is intended to be used
850    /// by subscribers that implement filtering for the entire stack. Layers which do
851    /// not wish to be notified about certain spans or events but do not wish to
852    /// globally disable them should ignore those spans or events in their
853    /// [on_event][Self::on_event], [on_enter][Self::on_enter], [on_exit][Self::on_exit],
854    /// and other notification methods.
855    ///
856    /// </pre></div>
857    ///
858    ///
859    /// See [the trait-level documentation] for more information on filtering
860    /// with subscribers.
861    ///
862    /// [`Interest`]: tracing_core::Interest
863    /// [the trait-level documentation]: #filtering-with-subscribers
864    fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, C>) -> bool {
865        let _ = (metadata, ctx);
866        true
867    }
868
869    /// Notifies this subscriber that a new span was constructed with the given
870    /// `Attributes` and `Id`.
871    fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, C>) {
872        let _ = (attrs, id, ctx);
873    }
874
875    // TODO(eliza): do we want this to be a public API? If we end up moving
876    // filtering subscribers to a separate trait, we may no longer want subscribers to
877    // be able to participate in max level hinting...
878    #[doc(hidden)]
879    fn max_level_hint(&self) -> Option<LevelFilter> {
880        None
881    }
882
883    /// Notifies this subscriber that a span with the given `Id` recorded the given
884    /// `values`.
885    // Note: it's unclear to me why we'd need the current span in `record` (the
886    // only thing the `Context` type currently provides), but passing it in anyway
887    // seems like a good future-proofing measure as it may grow other methods later...
888    fn on_record(&self, _span: &span::Id, _values: &span::Record<'_>, _ctx: Context<'_, C>) {}
889
890    /// Notifies this subscriber that a span with the ID `span` recorded that it
891    /// follows from the span with the ID `follows`.
892    // Note: it's unclear to me why we'd need the current span in `record` (the
893    // only thing the `Context` type currently provides), but passing it in anyway
894    // seems like a good future-proofing measure as it may grow other methods later...
895    fn on_follows_from(&self, _span: &span::Id, _follows: &span::Id, _ctx: Context<'_, C>) {}
896
897    /// Called before [`on_event`], to determine if `on_event` should be called.
898    ///
899    /// <div class="example-wrap" style="display:inline-block">
900    /// <pre class="ignore" style="white-space:normal;font:inherit;">
901    ///
902    /// **Note**: This method determines whether an event is globally enabled,
903    /// *not* whether the individual subscriber will be notified about the
904    /// event. This is intended to be used by subscribers that implement
905    /// filtering for the entire stack. Subscribers which do not wish to be
906    /// notified about certain events but do not wish to globally disable them
907    /// should ignore those events in their [on_event][Self::on_event].
908    ///
909    /// </pre></div>
910    ///
911    /// See [the trait-level documentation] for more information on filtering
912    /// with `Subscriber`s.
913    ///
914    /// [`on_event`]: Self::on_event
915    /// [`Interest`]: tracing_core::Interest
916    /// [the trait-level documentation]: #filtering-with-subscribers
917    #[inline] // collapse this to a constant please mrs optimizer
918    fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, C>) -> bool {
919        true
920    }
921
922    /// Notifies this subscriber that an event has occurred.
923    fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, C>) {}
924
925    /// Notifies this subscriber that a span with the given ID was entered.
926    fn on_enter(&self, _id: &span::Id, _ctx: Context<'_, C>) {}
927
928    /// Notifies this subscriber that the span with the given ID was exited.
929    fn on_exit(&self, _id: &span::Id, _ctx: Context<'_, C>) {}
930
931    /// Notifies this subscriber that the span with the given ID has been closed.
932    fn on_close(&self, _id: span::Id, _ctx: Context<'_, C>) {}
933
934    /// Notifies this subscriber that a span ID has been cloned, and that the
935    /// subscriber returned a different ID.
936    fn on_id_change(&self, _old: &span::Id, _new: &span::Id, _ctx: Context<'_, C>) {}
937
938    /// Composes this subscriber around the given collector, returning a `Layered`
939    /// struct implementing `Subscribe`.
940    ///
941    /// The returned subscriber will call the methods on this subscriber and then
942    /// those of the new subscriber, before calling the methods on the collector
943    /// it wraps. For example:
944    ///
945    /// ```rust
946    /// # use tracing_subscriber::subscribe::Subscribe;
947    /// # use tracing_core::Collect;
948    /// # use tracing_core::span::Current;
949    /// pub struct FooSubscriber {
950    ///     // ...
951    /// }
952    ///
953    /// pub struct BarSubscriber {
954    ///     // ...
955    /// }
956    ///
957    /// pub struct MyCollector {
958    ///     // ...
959    /// }
960    ///
961    /// impl<C: Collect> Subscribe<C> for FooSubscriber {
962    ///     // ...
963    /// }
964    ///
965    /// impl<C: Collect> Subscribe<C> for BarSubscriber {
966    ///     // ...
967    /// }
968    ///
969    /// # impl FooSubscriber {
970    /// # fn new() -> Self { Self {} }
971    /// # }
972    /// # impl BarSubscriber {
973    /// # fn new() -> Self { Self { }}
974    /// # }
975    /// # impl MyCollector {
976    /// # fn new() -> Self { Self { }}
977    /// # }
978    /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
979    /// # impl tracing_core::Collect for MyCollector {
980    /// #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
981    /// #   fn record(&self, _: &Id, _: &Record) {}
982    /// #   fn event(&self, _: &Event) {}
983    /// #   fn record_follows_from(&self, _: &Id, _: &Id) {}
984    /// #   fn enabled(&self, _: &Metadata) -> bool { false }
985    /// #   fn enter(&self, _: &Id) {}
986    /// #   fn exit(&self, _: &Id) {}
987    /// #   fn current_span(&self) -> Current { Current::unknown() }
988    /// # }
989    /// let collector = FooSubscriber::new()
990    ///     .and_then(BarSubscriber::new())
991    ///     .with_collector(MyCollector::new());
992    /// ```
993    ///
994    /// Multiple subscribers may be composed in this manner:
995    ///
996    /// ```rust
997    /// # use tracing_subscriber::subscribe::Subscribe;
998    /// # use tracing_core::{Collect, span::Current};
999    /// # pub struct FooSubscriber {}
1000    /// # pub struct BarSubscriber {}
1001    /// # pub struct MyCollector {}
1002    /// # impl<C: Collect> Subscribe<C> for FooSubscriber {}
1003    /// # impl<C: Collect> Subscribe<C> for BarSubscriber {}
1004    /// # impl FooSubscriber {
1005    /// # fn new() -> Self { Self {} }
1006    /// # }
1007    /// # impl BarSubscriber {
1008    /// # fn new() -> Self { Self { }}
1009    /// # }
1010    /// # impl MyCollector {
1011    /// # fn new() -> Self { Self { }}
1012    /// # }
1013    /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
1014    /// # impl tracing_core::Collect for MyCollector {
1015    /// #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
1016    /// #   fn record(&self, _: &Id, _: &Record) {}
1017    /// #   fn event(&self, _: &Event) {}
1018    /// #   fn record_follows_from(&self, _: &Id, _: &Id) {}
1019    /// #   fn enabled(&self, _: &Metadata) -> bool { false }
1020    /// #   fn enter(&self, _: &Id) {}
1021    /// #   fn exit(&self, _: &Id) {}
1022    /// #   fn current_span(&self) -> Current { Current::unknown() }
1023    /// # }
1024    /// pub struct BazSubscriber {
1025    ///     // ...
1026    /// }
1027    ///
1028    /// impl<C: Collect> Subscribe<C> for BazSubscriber {
1029    ///     // ...
1030    /// }
1031    /// # impl BazSubscriber { fn new() -> Self { BazSubscriber {} } }
1032    ///
1033    /// let collector = FooSubscriber::new()
1034    ///     .and_then(BarSubscriber::new())
1035    ///     .and_then(BazSubscriber::new())
1036    ///     .with_collector(MyCollector::new());
1037    /// ```
1038    fn and_then<S>(self, subscriber: S) -> Layered<S, Self, C>
1039    where
1040        S: Subscribe<C>,
1041        Self: Sized,
1042    {
1043        let inner_has_subscriber_filter = filter::subscriber_has_psf(&self);
1044        Layered::new(subscriber, self, inner_has_subscriber_filter)
1045    }
1046
1047    /// Composes this subscriber with the given collector, returning a
1048    /// `Layered` struct that implements [`Collect`].
1049    ///
1050    /// The returned `Layered` subscriber will call the methods on this subscriber
1051    /// and then those of the wrapped collector.
1052    ///
1053    /// For example:
1054    /// ```rust
1055    /// # use tracing_subscriber::subscribe::Subscribe;
1056    /// # use tracing_core::Collect;
1057    /// # use tracing_core::span::Current;
1058    /// pub struct FooSubscriber {
1059    ///     // ...
1060    /// }
1061    ///
1062    /// pub struct MyCollector {
1063    ///     // ...
1064    /// }
1065    ///
1066    /// impl<C: Collect> Subscribe<C> for FooSubscriber {
1067    ///     // ...
1068    /// }
1069    ///
1070    /// # impl FooSubscriber {
1071    /// # fn new() -> Self { Self {} }
1072    /// # }
1073    /// # impl MyCollector {
1074    /// # fn new() -> Self { Self { }}
1075    /// # }
1076    /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata};
1077    /// # impl tracing_core::Collect for MyCollector {
1078    /// #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
1079    /// #   fn record(&self, _: &Id, _: &Record) {}
1080    /// #   fn event(&self, _: &tracing_core::Event) {}
1081    /// #   fn record_follows_from(&self, _: &Id, _: &Id) {}
1082    /// #   fn enabled(&self, _: &Metadata) -> bool { false }
1083    /// #   fn enter(&self, _: &Id) {}
1084    /// #   fn exit(&self, _: &Id) {}
1085    /// #   fn current_span(&self) -> Current { Current::unknown() }
1086    /// # }
1087    /// let collector = FooSubscriber::new()
1088    ///     .with_collector(MyCollector::new());
1089    ///```
1090    ///
1091    /// [`Collect`]: tracing_core::Collect
1092    fn with_collector(mut self, mut inner: C) -> Layered<Self, C>
1093    where
1094        Self: Sized,
1095    {
1096        let inner_has_subscriber_filter = filter::collector_has_psf(&inner);
1097        self.on_subscribe(&mut inner);
1098        Layered::new(self, inner, inner_has_subscriber_filter)
1099    }
1100
1101    /// Combines `self` with a [`Filter`], returning a [`Filtered`] subscriber.
1102    ///
1103    /// The [`Filter`] will control which spans and events are enabled for
1104    /// this subscriber. See [the trait-level documentation][psf] for details on
1105    /// per-subscriber filtering.
1106    ///
1107    /// [`Filtered`]: crate::filter::Filtered
1108    /// [psf]: #per-subscriber-filtering
1109    #[cfg(all(feature = "registry", feature = "std"))]
1110    #[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))]
1111    fn with_filter<F>(self, filter: F) -> filter::Filtered<Self, F, C>
1112    where
1113        Self: Sized,
1114        F: Filter<C>,
1115    {
1116        filter::Filtered::new(self, filter)
1117    }
1118
1119    /// Erases the type of this subscriber, returning a [`Box`]ed `dyn
1120    /// Subscribe` trait object.
1121    ///
1122    /// This can be used when a function returns a subscriber which may be of
1123    /// one of several types, or when a composed subscriber has a very long type
1124    /// signature.
1125    ///
1126    /// # Examples
1127    ///
1128    /// The following example will *not* compile, because the value assigned to
1129    /// `log_subscriber` may have one of several different types:
1130    ///
1131    /// ```compile_fail
1132    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
1133    /// use tracing_subscriber::{Subscribe, filter::LevelFilter, prelude::*};
1134    /// use std::{path::PathBuf, fs::File, io};
1135    ///
1136    /// /// Configures whether logs are emitted to a file, to stdout, or to stderr.
1137    /// pub enum LogConfig {
1138    ///     File(PathBuf),
1139    ///     Stdout,
1140    ///     Stderr,
1141    /// }
1142    ///
1143    /// let config = // ...
1144    ///     # LogConfig::Stdout;
1145    ///
1146    /// // Depending on the config, construct a subscriber of one of several types.
1147    /// let log_subscriber = match config {
1148    ///     // If logging to a file, use a maximally-verbose configuration.
1149    ///     LogConfig::File(path) => {
1150    ///         let file = File::create(path)?;
1151    ///         tracing_subscriber::fmt::subscriber()
1152    ///             .with_thread_ids(true)
1153    ///             .with_thread_names(true)
1154    ///             // Selecting the JSON logging format changes the subscriber's
1155    ///             // type.
1156    ///             .json()
1157    ///             .with_span_list(true)
1158    ///             // Setting the writer to use our log file changes the
1159    ///             // subscriber's type again.
1160    ///             .with_writer(file)
1161    ///     },
1162    ///
1163    ///     // If logging to stdout, use a pretty, human-readable configuration.
1164    ///     LogConfig::Stdout => tracing_subscriber::fmt::subscriber()
1165    ///         // Selecting the "pretty" logging format changes the
1166    ///         // subscriber's type!
1167    ///         .pretty()
1168    ///         .with_writer(io::stdout)
1169    ///         // Add a filter based on the RUST_LOG environment variable;
1170    ///         // this changes the type too!
1171    ///         .and_then(tracing_subscriber::EnvFilter::from_default_env()),
1172    ///
1173    ///     // If logging to stdout, only log errors and warnings.
1174    ///     LogConfig::Stderr => tracing_subscriber::fmt::subscriber()
1175    ///         // Changing the writer changes the subscriber's type
1176    ///         .with_writer(io::stderr)
1177    ///         // Only log the `WARN` and `ERROR` levels. Adding a filter
1178    ///         // changes the subscriber's type to `Filtered<LevelFilter, ...>`.
1179    ///         .with_filter(LevelFilter::WARN),
1180    /// };
1181    ///
1182    /// tracing_subscriber::registry()
1183    ///     .with(log_subscriber)
1184    ///     .init();
1185    /// # Ok(()) }
1186    /// ```
1187    ///
1188    /// However, adding a call to `.boxed()` after each match arm erases the
1189    /// subscriber's type, so this code *does* compile:
1190    ///
1191    /// ```
1192    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
1193    /// # use tracing_subscriber::{Subscribe, filter::LevelFilter, prelude::*};
1194    /// # use std::{path::PathBuf, fs::File, io};
1195    /// # pub enum LogConfig {
1196    /// #    File(PathBuf),
1197    /// #    Stdout,
1198    /// #    Stderr,
1199    /// # }
1200    /// # let config = LogConfig::Stdout;
1201    /// let log_subscriber = match config {
1202    ///     LogConfig::File(path) => {
1203    ///         let file = File::create(path)?;
1204    ///         tracing_subscriber::fmt::subscriber()
1205    ///             .with_thread_ids(true)
1206    ///             .with_thread_names(true)
1207    ///             .json()
1208    ///             .with_span_list(true)
1209    ///             .with_writer(file)
1210    ///             // Erase the type by boxing the subscriber
1211    ///             .boxed()
1212    ///     },
1213    ///
1214    ///     LogConfig::Stdout => tracing_subscriber::fmt::subscriber()
1215    ///         .pretty()
1216    ///         .with_writer(io::stdout)
1217    ///         .and_then(tracing_subscriber::EnvFilter::from_default_env())
1218    ///         // Erase the type by boxing the subscriber
1219    ///         .boxed(),
1220    ///
1221    ///     LogConfig::Stderr => tracing_subscriber::fmt::subscriber()
1222    ///         .with_writer(io::stderr)
1223    ///         .with_filter(LevelFilter::WARN)
1224    ///         // Erase the type by boxing the subscriber
1225    ///         .boxed(),
1226    /// };
1227    ///
1228    /// tracing_subscriber::registry()
1229    ///     .with(log_subscriber)
1230    ///     .init();
1231    /// # Ok(()) }
1232    /// ```
1233    #[cfg(any(feature = "alloc", feature = "std"))]
1234    #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
1235    fn boxed(self) -> Box<dyn Subscribe<C> + Send + Sync + 'static>
1236    where
1237        Self: Sized,
1238        Self: Subscribe<C> + Send + Sync + 'static,
1239        C: Collect,
1240    {
1241        Box::new(self)
1242    }
1243
1244    #[doc(hidden)]
1245    unsafe fn downcast_raw(&self, id: TypeId) -> Option<NonNull<()>> {
1246        if id == TypeId::of::<Self>() {
1247            Some(NonNull::from(self).cast())
1248        } else {
1249            None
1250        }
1251    }
1252}
1253
1254/// A per-[`Subscribe`] filter that determines whether a span or event is enabled
1255/// for an individual subscriber.
1256#[cfg(all(feature = "registry", feature = "std"))]
1257#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))]
1258#[cfg_attr(docsrs, doc(notable_trait))]
1259pub trait Filter<S> {
1260    /// Returns `true` if this subscriber is interested in a span or event with the
1261    /// given [`Metadata`] in the current [`Context`], similarly to
1262    /// [`Collect::enabled`].
1263    ///
1264    /// If this returns `false`, the span or event will be disabled _for the
1265    /// wrapped [`Subscribe`]_. Unlike [`Subscribe::enabled`], the span or event will
1266    /// still be recorded if any _other_ subscribers choose to enable it. However,
1267    /// the subscriber [filtered] by this filter will skip recording that span or
1268    /// event.
1269    ///
1270    /// If all subscribers indicate that they do not wish to see this span or event,
1271    /// it will be disabled.
1272    ///
1273    /// [`metadata`]: tracing_core::Metadata
1274    /// [`Collect::enabled`]: tracing_core::Collect::enabled
1275    /// [filtered]: crate::filter::Filtered
1276    fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool;
1277
1278    /// Returns an [`Interest`] indicating whether this subscriber will [always],
1279    /// [sometimes], or [never] be interested in the given [`Metadata`].
1280    ///
1281    /// When a given callsite will [always] or [never] be enabled, the results
1282    /// of evaluating the filter may be cached for improved performance.
1283    /// Therefore, if a filter is capable of determining that it will always or
1284    /// never enable a particular callsite, providing an implementation of this
1285    /// function is recommended.
1286    ///
1287    /// <div class="example-wrap" style="display:inline-block">
1288    /// <pre class="ignore" style="white-space:normal;font:inherit;">
1289    /// <strong>Note</strong>: If a <code>Filter</code> will perform
1290    /// <em>dynamic filtering</em> that depends on the current context in which
1291    /// a span or event was observed (e.g. only enabling an event when it
1292    /// occurs within a particular span), it <strong>must</strong> return
1293    /// <code>Interest::sometimes()</code> from this method. If it returns
1294    /// <code>Interest::always()</code> or <code>Interest::never()</code>, the
1295    /// <code>enabled</code> method may not be called when a particular instance
1296    /// of that span or event is recorded.
1297    /// </pre>
1298    /// </div>
1299    ///
1300    /// This method is broadly similar to [`Collect::register_callsite`];
1301    /// however, since the returned value represents only the interest of
1302    /// *this* subscriber, the resulting behavior is somewhat different.
1303    ///
1304    /// If a [`Collect`] returns [`Interest::always()`][always] or
1305    /// [`Interest::never()`][never] for a given [`Metadata`], its [`enabled`]
1306    /// method is then *guaranteed* to never be called for that callsite. On the
1307    /// other hand, when a `Filter` returns [`Interest::always()`][always] or
1308    /// [`Interest::never()`][never] for a callsite, _other_ [`Subscribe`]s may have
1309    /// differing interests in that callsite. If this is the case, the callsite
1310    /// will receive [`Interest::sometimes()`][sometimes], and the [`enabled`]
1311    /// method will still be called for that callsite when it records a span or
1312    /// event.
1313    ///
1314    /// Returning [`Interest::always()`][always] or [`Interest::never()`][never] from
1315    /// `Filter::callsite_enabled` will permanently enable or disable a
1316    /// callsite (without requiring subsequent calls to [`enabled`]) if and only
1317    /// if the following is true:
1318    ///
1319    /// - all [`Subscribe`]s that comprise the subscriber include `Filter`s
1320    ///   (this includes a tree of [`Layered`] subscribers that share the same
1321    ///   `Filter`)
1322    /// - all those `Filter`s return the same [`Interest`].
1323    ///
1324    /// For example, if a [`Collect`] consists of two [`Filtered`] subscribers,
1325    /// and both of those subscribers return [`Interest::never()`][never], that
1326    /// callsite *will* never be enabled, and the [`enabled`] methods of those
1327    /// [`Filter`]s will not be called.
1328    ///
1329    /// ## Default Implementation
1330    ///
1331    /// The default implementation of this method assumes that the
1332    /// `Filter`'s [`enabled`] method _may_ perform dynamic filtering, and
1333    /// returns [`Interest::sometimes()`][sometimes], to ensure that [`enabled`]
1334    /// is called to determine whether a particular _instance_ of the callsite
1335    /// is enabled in the current context. If this is *not* the case, and the
1336    /// `Filter`'s [`enabled`] method will always return the same result
1337    /// for a particular [`Metadata`], this method can be overridden as
1338    /// follows:
1339    ///
1340    /// ```
1341    /// use tracing_subscriber::subscribe;
1342    /// use tracing_core::{Metadata, collect::Interest};
1343    ///
1344    /// struct MyFilter {
1345    ///     // ...
1346    /// }
1347    ///
1348    /// impl MyFilter {
1349    ///     // The actual logic for determining whether a `Metadata` is enabled
1350    ///     // must be factored out from the `enabled` method, so that it can be
1351    ///     // called without a `Context` (which is not provided to the
1352    ///     // `callsite_enabled` method).
1353    ///     fn is_enabled(&self, metadata: &Metadata<'_>) -> bool {
1354    ///         // ...
1355    ///         # drop(metadata); true
1356    ///     }
1357    /// }
1358    ///
1359    /// impl<C> subscribe::Filter<C> for MyFilter {
1360    ///     fn enabled(&self, metadata: &Metadata<'_>, _: &subscribe::Context<'_, C>) -> bool {
1361    ///         // Even though we are implementing `callsite_enabled`, we must still provide a
1362    ///         // working implementation of `enabled`, as returning `Interest::always()` or
1363    ///         // `Interest::never()` will *allow* caching, but will not *guarantee* it.
1364    ///         // Other filters may still return `Interest::sometimes()`, so we may be
1365    ///         // asked again in `enabled`.
1366    ///         self.is_enabled(metadata)
1367    ///     }
1368    ///
1369    ///     fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest {
1370    ///         // The result of `self.enabled(metadata, ...)` will always be
1371    ///         // the same for any given `Metadata`, so we can convert it into
1372    ///         // an `Interest`:
1373    ///         if self.is_enabled(metadata) {
1374    ///             Interest::always()
1375    ///         } else {
1376    ///             Interest::never()
1377    ///         }
1378    ///     }
1379    /// }
1380    /// ```
1381    ///
1382    /// [`Metadata`]: tracing_core::Metadata
1383    /// [`Interest`]: tracing_core::Interest
1384    /// [always]: tracing_core::Interest::always
1385    /// [sometimes]: tracing_core::Interest::sometimes
1386    /// [never]: tracing_core::Interest::never
1387    /// [`Collect::register_callsite`]: tracing_core::Collect::register_callsite
1388    /// [`Collect`]: tracing_core::Collect
1389    /// [`enabled`]: Filter::enabled
1390    /// [`Filtered`]: crate::filter::Filtered
1391    fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
1392        let _ = meta;
1393        Interest::sometimes()
1394    }
1395
1396    /// Returns an optional hint of the highest [verbosity level][level] that
1397    /// this `Filter` will enable.
1398    ///
1399    /// If this method returns a [`LevelFilter`], it will be used as a hint to
1400    /// determine the most verbose level that will be enabled. This will allow
1401    /// spans and events which are more verbose than that level to be skipped
1402    /// more efficiently. An implementation of this method is optional, but
1403    /// strongly encouraged.
1404    ///
1405    /// If the maximum level the `Filter` will enable can change over the
1406    /// course of its lifetime, it is free to return a different value from
1407    /// multiple invocations of this method. However, note that changes in the
1408    /// maximum level will **only** be reflected after the callsite [`Interest`]
1409    /// cache is rebuilt, by calling the
1410    /// [`tracing_core::callsite::rebuild_interest_cache`] function.
1411    /// Therefore, if the `Filter will change the value returned by this
1412    /// method, it is responsible for ensuring that [`rebuild_interest_cache`]
1413    /// is called after the value of the max level changes.
1414    ///
1415    /// ## Default Implementation
1416    ///
1417    /// By default, this method returns `None`, indicating that the maximum
1418    /// level is unknown.
1419    ///
1420    /// [level]: tracing_core::metadata::Level
1421    /// [`LevelFilter`]: crate::filter::LevelFilter
1422    /// [`Interest`]: tracing_core::collect::Interest
1423    /// [`rebuild_interest_cache`]: tracing_core::callsite::rebuild_interest_cache
1424    fn max_level_hint(&self) -> Option<LevelFilter> {
1425        None
1426    }
1427
1428    /// Called before the filtered subscribers' [`on_event`], to determine if
1429    /// `on_event` should be called.
1430    ///
1431    /// This gives a chance to filter events based on their fields. Note,
1432    /// however, that this *does not* override [`enabled`], and is not even
1433    /// called if [`enabled`] returns `false`.
1434    ///
1435    /// ## Default Implementation
1436    ///
1437    /// By default, this method returns `true`, indicating that no events are
1438    /// filtered out based on their fields.
1439    ///
1440    /// [`enabled`]: crate::subscribe::Filter::enabled
1441    /// [`on_event`]: crate::subscribe::Subscribe::on_event
1442    #[inline] // collapse this to a constant please mrs optimizer
1443    fn event_enabled(&self, event: &Event<'_>, cx: &Context<'_, S>) -> bool {
1444        let _ = (event, cx);
1445        true
1446    }
1447
1448    /// Notifies this filter that a new span was constructed with the given
1449    /// `Attributes` and `Id`.
1450    ///
1451    /// By default, this method does nothing. `Filter` implementations that
1452    /// need to be notified when new spans are created can override this
1453    /// method.
1454    fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
1455        let _ = (attrs, id, ctx);
1456    }
1457
1458    /// Notifies this filter that a span with the given `Id` recorded the given
1459    /// `values`.
1460    ///
1461    /// By default, this method does nothing. `Filter` implementations that
1462    /// need to be notified when new spans are created can override this
1463    /// method.
1464    fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
1465        let _ = (id, values, ctx);
1466    }
1467
1468    /// Notifies this filter that a span with the given ID was entered.
1469    ///
1470    /// By default, this method does nothing. `Filter` implementations that
1471    /// need to be notified when a span is entered can override this method.
1472    fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
1473        let _ = (id, ctx);
1474    }
1475
1476    /// Notifies this filter that a span with the given ID was exited.
1477    ///
1478    /// By default, this method does nothing. `Filter` implementations that
1479    /// need to be notified when a span is exited can override this method.
1480    fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
1481        let _ = (id, ctx);
1482    }
1483
1484    /// Notifies this filter that a span with the given ID has been closed.
1485    ///
1486    /// By default, this method does nothing. `Filter` implementations that
1487    /// need to be notified when a span is closed can override this method.
1488    fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
1489        let _ = (id, ctx);
1490    }
1491}
1492
1493/// Extension trait adding a `with(Subscribe)` combinator to types implementing
1494/// [`Collect`].
1495pub trait CollectExt: Collect + crate::sealed::Sealed {
1496    /// Wraps `self` with the provided `subscriber`.
1497    fn with<S>(self, subscriber: S) -> Layered<S, Self>
1498    where
1499        S: Subscribe<Self>,
1500        Self: Sized,
1501    {
1502        subscriber.with_collector(self)
1503    }
1504}
1505/// A subscriber that does nothing.
1506#[derive(Clone, Debug, Default)]
1507pub struct Identity {
1508    _p: (),
1509}
1510
1511// === impl Subscribe ===
1512
1513#[derive(Clone, Copy)]
1514pub(crate) struct NoneLayerMarker(());
1515static NONE_LAYER_MARKER: NoneLayerMarker = NoneLayerMarker(());
1516
1517/// Is a type implementing `Subscriber` `Option::<_>::None`?
1518pub(crate) fn subscriber_is_none<S, C>(subscriber: &S) -> bool
1519where
1520    S: Subscribe<C>,
1521    C: Collect,
1522{
1523    unsafe {
1524        // Safety: we're not actually *doing* anything with this pointer ---
1525        // this only care about the `Option`, which is essentially being used
1526        // as a bool. We can rely on the pointer being valid, because it is
1527        // a crate-private type, and is only returned by the `Subscribe` impl
1528        // for `Option`s. However, even if the subscriber *does* decide to be
1529        // evil and give us an invalid pointer here, that's fine, because we'll
1530        // never actually dereference it.
1531        subscriber.downcast_raw(TypeId::of::<NoneLayerMarker>())
1532    }
1533    .is_some()
1534}
1535
1536/// Is a type implementing `Collect` `Option::<_>::None`?
1537pub(crate) fn collector_is_none<C>(collector: &C) -> bool
1538where
1539    C: Collect,
1540{
1541    unsafe {
1542        // Safety: we're not actually *doing* anything with this pointer ---
1543        // this only care about the `Option`, which is essentially being used
1544        // as a bool. We can rely on the pointer being valid, because it is
1545        // a crate-private type, and is only returned by the `Subscribe` impl
1546        // for `Option`s. However, even if the subscriber *does* decide to be
1547        // evil and give us an invalid pointer here, that's fine, because we'll
1548        // never actually dereference it.
1549        collector.downcast_raw(TypeId::of::<NoneLayerMarker>())
1550    }
1551    .is_some()
1552}
1553
1554impl<S, C> Subscribe<C> for Option<S>
1555where
1556    S: Subscribe<C>,
1557    C: Collect,
1558{
1559    fn on_register_dispatch(&self, collector: &Dispatch) {
1560        if let Some(ref subscriber) = self {
1561            subscriber.on_register_dispatch(collector)
1562        }
1563    }
1564
1565    fn on_subscribe(&mut self, collector: &mut C) {
1566        if let Some(ref mut subscriber) = self {
1567            subscriber.on_subscribe(collector)
1568        }
1569    }
1570
1571    #[inline]
1572    fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, C>) {
1573        if let Some(ref inner) = self {
1574            inner.on_new_span(attrs, id, ctx)
1575        }
1576    }
1577
1578    #[inline]
1579    fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
1580        match self {
1581            Some(ref inner) => inner.register_callsite(metadata),
1582            None => Interest::always(),
1583        }
1584    }
1585
1586    #[inline]
1587    fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, C>) -> bool {
1588        match self {
1589            Some(ref inner) => inner.enabled(metadata, ctx),
1590            None => true,
1591        }
1592    }
1593
1594    #[inline]
1595    fn max_level_hint(&self) -> Option<LevelFilter> {
1596        match self {
1597            Some(ref inner) => inner.max_level_hint(),
1598            None => {
1599                // There is no inner subscriber, so this subscriber will
1600                // never enable anything.
1601                Some(LevelFilter::OFF)
1602            }
1603        }
1604    }
1605
1606    #[inline]
1607    fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, C>) {
1608        if let Some(ref inner) = self {
1609            inner.on_record(span, values, ctx);
1610        }
1611    }
1612
1613    #[inline]
1614    fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, C>) {
1615        if let Some(ref inner) = self {
1616            inner.on_follows_from(span, follows, ctx);
1617        }
1618    }
1619
1620    #[inline]
1621    fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, C>) -> bool {
1622        match self {
1623            Some(ref inner) => inner.event_enabled(event, ctx),
1624            None => true,
1625        }
1626    }
1627
1628    #[inline]
1629    fn on_event(&self, event: &Event<'_>, ctx: Context<'_, C>) {
1630        if let Some(ref inner) = self {
1631            inner.on_event(event, ctx);
1632        }
1633    }
1634
1635    #[inline]
1636    fn on_enter(&self, id: &span::Id, ctx: Context<'_, C>) {
1637        if let Some(ref inner) = self {
1638            inner.on_enter(id, ctx);
1639        }
1640    }
1641
1642    #[inline]
1643    fn on_exit(&self, id: &span::Id, ctx: Context<'_, C>) {
1644        if let Some(ref inner) = self {
1645            inner.on_exit(id, ctx);
1646        }
1647    }
1648
1649    #[inline]
1650    fn on_close(&self, id: span::Id, ctx: Context<'_, C>) {
1651        if let Some(ref inner) = self {
1652            inner.on_close(id, ctx);
1653        }
1654    }
1655
1656    #[inline]
1657    fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, C>) {
1658        if let Some(ref inner) = self {
1659            inner.on_id_change(old, new, ctx)
1660        }
1661    }
1662
1663    #[doc(hidden)]
1664    #[inline]
1665    unsafe fn downcast_raw(&self, id: TypeId) -> Option<NonNull<()>> {
1666        if id == TypeId::of::<Self>() {
1667            Some(NonNull::from(self).cast())
1668        } else if id == TypeId::of::<NoneLayerMarker>() && self.is_none() {
1669            Some(NonNull::from(&NONE_LAYER_MARKER).cast())
1670        } else {
1671            self.as_ref().and_then(|inner| inner.downcast_raw(id))
1672        }
1673    }
1674}
1675
1676#[cfg(any(feature = "std", feature = "alloc"))]
1677macro_rules! subscriber_impl_body {
1678    () => {
1679        fn on_register_dispatch(&self, collector: &Dispatch) {
1680            self.deref().on_register_dispatch(collector);
1681        }
1682
1683        #[inline]
1684        fn on_subscribe(&mut self, collect: &mut C) {
1685            self.deref_mut().on_subscribe(collect);
1686        }
1687
1688        #[inline]
1689        fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
1690            self.deref().register_callsite(metadata)
1691        }
1692
1693        #[inline]
1694        fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, C>) {
1695            self.deref().on_new_span(attrs, id, ctx)
1696        }
1697
1698        #[inline]
1699        fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, C>) -> bool {
1700            self.deref().enabled(metadata, ctx)
1701        }
1702
1703        #[inline]
1704        fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, C>) {
1705            self.deref().on_record(span, values, ctx)
1706        }
1707
1708        #[inline]
1709        fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, C>) {
1710            self.deref().on_follows_from(span, follows, ctx)
1711        }
1712
1713        #[inline]
1714        fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, C>) -> bool {
1715            self.deref().event_enabled(event, ctx)
1716        }
1717
1718        #[inline]
1719        fn on_event(&self, event: &Event<'_>, ctx: Context<'_, C>) {
1720            self.deref().on_event(event, ctx)
1721        }
1722
1723        #[inline]
1724        fn on_enter(&self, id: &span::Id, ctx: Context<'_, C>) {
1725            self.deref().on_enter(id, ctx)
1726        }
1727
1728        #[inline]
1729        fn on_exit(&self, id: &span::Id, ctx: Context<'_, C>) {
1730            self.deref().on_exit(id, ctx)
1731        }
1732
1733        #[inline]
1734        fn on_close(&self, id: span::Id, ctx: Context<'_, C>) {
1735            self.deref().on_close(id, ctx)
1736        }
1737
1738        #[inline]
1739        fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, C>) {
1740            self.deref().on_id_change(old, new, ctx)
1741        }
1742
1743        #[inline]
1744        fn max_level_hint(&self) -> Option<LevelFilter> {
1745            self.deref().max_level_hint()
1746        }
1747
1748        #[doc(hidden)]
1749        #[inline]
1750        unsafe fn downcast_raw(&self, id: TypeId) -> ::core::option::Option<NonNull<()>> {
1751            self.deref().downcast_raw(id)
1752        }
1753    };
1754}
1755
1756feature! {
1757    #![any(feature = "std", feature = "alloc")]
1758
1759    impl<S, C> Subscribe<C> for Box<S>
1760    where
1761        S: Subscribe<C>,
1762        C: Collect,
1763    {
1764        subscriber_impl_body! {}
1765    }
1766
1767    impl<C> Subscribe<C> for Box<dyn Subscribe<C> + Send + Sync + 'static>
1768    where
1769        C: Collect,
1770    {
1771        subscriber_impl_body! {}
1772    }
1773
1774
1775    impl<C, S> Subscribe<C> for alloc::vec::Vec<S>
1776    where
1777        S: Subscribe<C>,
1778        C: Collect,
1779    {
1780        fn on_register_dispatch(&self, collector: &Dispatch) {
1781            for s in self {
1782                s.on_register_dispatch(collector);
1783            }
1784        }
1785
1786        fn on_subscribe(&mut self, collector: &mut C) {
1787            for s in self {
1788                s.on_subscribe(collector);
1789            }
1790        }
1791
1792        fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
1793            // Return highest level of interest.
1794            let mut interest = Interest::never();
1795            for s in self {
1796                let new_interest = s.register_callsite(metadata);
1797                if (interest.is_sometimes() && new_interest.is_always())
1798                    || (interest.is_never() && !new_interest.is_never())
1799                {
1800                    interest = new_interest;
1801                }
1802            }
1803
1804            interest
1805        }
1806
1807        fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, C>) -> bool {
1808            self.iter().all(|s| s.enabled(metadata, ctx.clone()))
1809        }
1810
1811        fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, C>) {
1812            for s in self {
1813                s.on_new_span(attrs, id, ctx.clone());
1814            }
1815        }
1816
1817        fn max_level_hint(&self) -> Option<LevelFilter> {
1818            // Default to `OFF` if there are no underlying subscribers
1819            let mut max_level = LevelFilter::OFF;
1820            for s in self {
1821                // NOTE(eliza): this is slightly subtle: if *any* subscriber
1822                // returns `None`, we have to return `None`, assuming there is
1823                // no max level hint, since that particular subscriber cannot
1824                // provide a hint.
1825                let hint = s.max_level_hint()?;
1826                max_level = core::cmp::max(hint, max_level);
1827            }
1828            Some(max_level)
1829        }
1830
1831        fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, C>) {
1832            for s in self {
1833                s.on_record(span, values, ctx.clone())
1834            }
1835        }
1836
1837        fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, C>) {
1838            for s in self {
1839                s.on_follows_from(span, follows, ctx.clone());
1840            }
1841        }
1842
1843        fn on_event(&self, event: &Event<'_>, ctx: Context<'_, C>) {
1844            for s in self {
1845                s.on_event(event, ctx.clone());
1846            }
1847        }
1848
1849        fn on_enter(&self, id: &span::Id, ctx: Context<'_, C>) {
1850            for s in self {
1851                s.on_enter(id, ctx.clone());
1852            }
1853        }
1854
1855        fn on_exit(&self, id: &span::Id, ctx: Context<'_, C>) {
1856            for s in self {
1857                s.on_exit(id, ctx.clone());
1858            }
1859        }
1860
1861        fn on_close(&self, id: span::Id, ctx: Context<'_, C>) {
1862            for s in self {
1863                s.on_close(id.clone(), ctx.clone());
1864            }
1865        }
1866
1867        #[doc(hidden)]
1868        unsafe fn downcast_raw(&self, id: TypeId) -> Option<NonNull<()>> {
1869            // If downcasting to `Self`, return a pointer to `self`.
1870            if id == TypeId::of::<Self>() {
1871                return Some(NonNull::from(self).cast());
1872            }
1873
1874            // Someone is looking for per-subscriber filters. But, this `Vec`
1875            // might contain subscribers with per-subscriber filters *and*
1876            // subscribers without filters. It should only be treated as a
1877            // per-subscriber-filtered subscriber if *all* its subscribers have
1878            // per-subscriber filters.
1879            // XXX(eliza): it's a bummer we have to do this linear search every
1880            // time. It would be nice if this could be cached, but that would
1881            // require replacing the `Vec` impl with an impl for a newtype...
1882            if filter::is_psf_downcast_marker(id) && self.iter().any(|s| s.downcast_raw(id).is_none()) {
1883                return None;
1884            }
1885
1886            // Otherwise, return the first child of `self` that downcaaasts to
1887            // the selected type, if any.
1888            // XXX(eliza): hope this is reasonable lol
1889            self.iter().find_map(|s| s.downcast_raw(id))
1890        }
1891    }
1892}
1893
1894// === impl CollectExt ===
1895
1896impl<C: Collect> crate::sealed::Sealed for C {}
1897impl<C: Collect> CollectExt for C {}
1898
1899// === impl Identity ===
1900
1901impl<C: Collect> Subscribe<C> for Identity {}
1902
1903impl Identity {
1904    /// Returns a new `Identity` subscriber.
1905    pub fn new() -> Self {
1906        Self { _p: () }
1907    }
1908}