diff options
Diffstat (limited to 'vendor/tracing-subscriber/src/filter/targets.rs')
-rw-r--r-- | vendor/tracing-subscriber/src/filter/targets.rs | 710 |
1 files changed, 0 insertions, 710 deletions
diff --git a/vendor/tracing-subscriber/src/filter/targets.rs b/vendor/tracing-subscriber/src/filter/targets.rs deleted file mode 100644 index 2a30d2db6..000000000 --- a/vendor/tracing-subscriber/src/filter/targets.rs +++ /dev/null @@ -1,710 +0,0 @@ -//! A [filter] that enables or disables spans and events based on their [target] and [level]. -//! -//! See [`Targets`] for details. -//! -//! [target]: tracing_core::Metadata::target -//! [level]: tracing_core::Level -//! [filter]: crate::layer#filtering-with-layers - -use crate::{ - filter::{ - directive::{DirectiveSet, ParseError, StaticDirective}, - LevelFilter, - }, - layer, -}; -#[cfg(not(feature = "std"))] -use alloc::string::String; -use core::{ - iter::{Extend, FilterMap, FromIterator}, - slice, - str::FromStr, -}; -use tracing_core::{Interest, Level, Metadata, Subscriber}; - -/// A filter that enables or disables spans and events based on their [target] -/// and [level]. -/// -/// Targets are typically equal to the Rust module path of the code where the -/// span or event was recorded, although they may be overridden. -/// -/// This type can be used for both [per-layer filtering][plf] (using its -/// [`Filter`] implementation) and [global filtering][global] (using its -/// [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// # Filtering With `Targets` -/// -/// A `Targets` filter consists of one or more [target] prefixes, paired with -/// [`LevelFilter`]s. If a span or event's [target] begins with one of those -/// prefixes, and its [level] is at or below the [`LevelFilter`] enabled for -/// that prefix, then the span or event will be enabled. -/// -/// This is similar to the behavior implemented by the [`env_logger` crate] in -/// the `log` ecosystem. -/// -/// The [`EnvFilter`] type also provided by this crate is very similar to `Targets`, -/// but is capable of a more sophisticated form of filtering where events may -/// also be enabled or disabled based on the span they are recorded in. -/// `Targets` can be thought of as a lighter-weight form of [`EnvFilter`] that -/// can be used instead when this dynamic filtering is not required. -/// -/// # Examples -/// -/// A `Targets` filter can be constructed by programmatically adding targets and -/// levels to enable: -/// -/// ``` -/// use tracing_subscriber::{filter, prelude::*}; -/// use tracing_core::Level; -/// -/// let filter = filter::Targets::new() -/// // Enable the `INFO` level for anything in `my_crate` -/// .with_target("my_crate", Level::INFO) -/// // Enable the `DEBUG` level for a specific module. -/// .with_target("my_crate::interesting_module", Level::DEBUG); -/// -/// // Build a new subscriber with the `fmt` layer using the `Targets` -/// // filter we constructed above. -/// tracing_subscriber::registry() -/// .with(tracing_subscriber::fmt::layer()) -/// .with(filter) -/// .init(); -/// ``` -/// -/// [`LevelFilter::OFF`] can be used to disable a particular target: -/// ``` -/// use tracing_subscriber::filter::{Targets, LevelFilter}; -/// use tracing_core::Level; -/// -/// let filter = Targets::new() -/// .with_target("my_crate", Level::INFO) -/// // Disable all traces from `annoying_module`. -/// .with_target("my_crate::annoying_module", LevelFilter::OFF); -/// # drop(filter); -/// ``` -/// -/// Alternatively, `Targets` implements [`std::str::FromStr`], allowing it to be -/// parsed from a comma-delimited list of `target=level` pairs. For example: -/// -/// ```rust -/// # fn main() -> Result<(), Box<dyn std::error::Error>> { -/// use tracing_subscriber::filter; -/// use tracing_core::Level; -/// -/// let filter = "my_crate=info,my_crate::interesting_module=trace,other_crate=debug" -/// .parse::<filter::Targets>()?; -/// -/// // The parsed filter is identical to a filter constructed using `with_target`: -/// assert_eq!( -/// filter, -/// filter::Targets::new() -/// .with_target("my_crate", Level::INFO) -/// .with_target("my_crate::interesting_module", Level::TRACE) -/// .with_target("other_crate", Level::DEBUG) -/// ); -/// # Ok(()) } -/// ``` -/// -/// This is particularly useful when the list of enabled targets is configurable -/// by the user at runtime. -/// -/// The `Targets` filter can be used as a [per-layer filter][plf] *and* as a -/// [global filter][global]: -/// -/// ```rust -/// use tracing_subscriber::{ -/// fmt, -/// filter::{Targets, LevelFilter}, -/// prelude::*, -/// }; -/// use tracing_core::Level; -/// use std::{sync::Arc, fs::File}; -/// # fn docs() -> Result<(), Box<dyn std::error::Error>> { -/// -/// // A layer that logs events to stdout using the human-readable "pretty" -/// // format. -/// let stdout_log = fmt::layer().pretty(); -/// -/// // A layer that logs events to a file, using the JSON format. -/// let file = File::create("debug_log.json")?; -/// let debug_log = fmt::layer() -/// .with_writer(Arc::new(file)) -/// .json(); -/// -/// tracing_subscriber::registry() -/// // Only log INFO and above to stdout, unless the span or event -/// // has the `my_crate::cool_module` target prefix. -/// .with(stdout_log -/// .with_filter( -/// Targets::default() -/// .with_target("my_crate::cool_module", Level::DEBUG) -/// .with_default(Level::INFO) -/// ) -/// ) -/// // Log everything enabled by the global filter to `debug_log.json`. -/// .with(debug_log) -/// // Configure a global filter for the whole subscriber stack. This will -/// // control what spans and events are recorded by both the `debug_log` -/// // and the `stdout_log` layers, and `stdout_log` will *additionally* be -/// // filtered by its per-layer filter. -/// .with( -/// Targets::default() -/// .with_target("my_crate", Level::TRACE) -/// .with_target("other_crate", Level::INFO) -/// .with_target("other_crate::annoying_module", LevelFilter::OFF) -/// .with_target("third_crate", Level::DEBUG) -/// ).init(); -/// # Ok(()) } -///``` -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -/// [`env_logger` crate]: https://docs.rs/env_logger/0.9.0/env_logger/index.html#enabling-logging -/// [`EnvFilter`]: crate::filter::EnvFilter -#[derive(Debug, Default, Clone, PartialEq)] -pub struct Targets(DirectiveSet<StaticDirective>); - -impl Targets { - /// Returns a new `Targets` filter. - /// - /// This filter will enable no targets. Call [`with_target`] or [`with_targets`] - /// to add enabled targets, and [`with_default`] to change the default level - /// enabled for spans and events that didn't match any of the provided targets. - /// - /// [`with_target`]: Targets::with_target - /// [`with_targets`]: Targets::with_targets - /// [`with_default`]: Targets::with_default - pub fn new() -> Self { - Self::default() - } - - /// Enables spans and events with [target]s starting with the provided target - /// prefix if they are at or below the provided [`LevelFilter`]. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter; - /// use tracing_core::Level; - /// - /// let filter = filter::Targets::new() - /// // Enable the `INFO` level for anything in `my_crate` - /// .with_target("my_crate", Level::INFO) - /// // Enable the `DEBUG` level for a specific module. - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// # drop(filter); - /// ``` - /// - /// [`LevelFilter::OFF`] can be used to disable a particular target: - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// // Disable all traces from `annoying_module`. - /// .with_target("my_crate::interesting_module", LevelFilter::OFF); - /// # drop(filter); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn with_target(mut self, target: impl Into<String>, level: impl Into<LevelFilter>) -> Self { - self.0.add(StaticDirective::new( - Some(target.into()), - Default::default(), - level.into(), - )); - self - } - /// Adds [target]s from an iterator of [target]-[`LevelFilter`] pairs to this filter. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter; - /// use tracing_core::Level; - /// - /// let filter = filter::Targets::new() - /// .with_targets(vec![ - /// ("my_crate", Level::INFO), - /// ("my_crate::some_module", Level::DEBUG), - /// ("my_crate::other_module::cool_stuff", Level::TRACE), - /// ("other_crate", Level::WARN) - /// ]); - /// # drop(filter); - /// ``` - /// - /// [`LevelFilter::OFF`] can be used to disable a particular target: - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// // Disable all traces from `annoying_module`. - /// .with_target("my_crate::interesting_module", LevelFilter::OFF); - /// # drop(filter); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn with_targets<T, L>(mut self, targets: impl IntoIterator<Item = (T, L)>) -> Self - where - String: From<T>, - LevelFilter: From<L>, - { - self.extend(targets); - self - } - - /// Sets the default level to enable for spans and events whose targets did - /// not match any of the configured prefixes. - /// - /// By default, this is [`LevelFilter::OFF`]. This means that spans and - /// events will only be enabled if they match one of the configured target - /// prefixes. If this is changed to a different [`LevelFilter`], spans and - /// events with targets that did not match any of the configured prefixes - /// will be enabled if their level is at or below the provided level. - pub fn with_default(mut self, level: impl Into<LevelFilter>) -> Self { - self.0 - .add(StaticDirective::new(None, Default::default(), level.into())); - self - } - - /// Returns an iterator over the [target]-[`LevelFilter`] pairs in this filter. - /// - /// The order of iteration is undefined. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// - /// let mut targets: Vec<_> = filter.iter().collect(); - /// targets.sort(); - /// - /// assert_eq!(targets, vec![ - /// ("my_crate", LevelFilter::INFO), - /// ("my_crate::interesting_module", LevelFilter::DEBUG), - /// ]); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn iter(&self) -> Iter<'_> { - self.into_iter() - } - - #[inline] - fn interested(&self, metadata: &'static Metadata<'static>) -> Interest { - if self.0.enabled(metadata) { - Interest::always() - } else { - Interest::never() - } - } - - /// Returns whether a [target]-[`Level`] pair would be enabled - /// by this `Targets`. - /// - /// This method can be used with [`module_path!`] from `std` as the target - /// in order to emulate the behavior of the [`tracing::event!`] and [`tracing::span!`] - /// macros. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// - /// assert!(filter.would_enable("my_crate", &Level::INFO)); - /// assert!(!filter.would_enable("my_crate::interesting_module", &Level::TRACE)); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - /// [`module_path!`]: std::module_path! - pub fn would_enable(&self, target: &str, level: &Level) -> bool { - // "Correct" to call because `Targets` only produces `StaticDirective`'s with NO - // fields - self.0.target_enabled(target, level) - } -} - -impl<T, L> Extend<(T, L)> for Targets -where - T: Into<String>, - L: Into<LevelFilter>, -{ - fn extend<I: IntoIterator<Item = (T, L)>>(&mut self, iter: I) { - let iter = iter.into_iter().map(|(target, level)| { - StaticDirective::new(Some(target.into()), Default::default(), level.into()) - }); - self.0.extend(iter); - } -} - -impl<T, L> FromIterator<(T, L)> for Targets -where - T: Into<String>, - L: Into<LevelFilter>, -{ - fn from_iter<I: IntoIterator<Item = (T, L)>>(iter: I) -> Self { - let mut this = Self::default(); - this.extend(iter); - this - } -} - -impl FromStr for Targets { - type Err = ParseError; - fn from_str(s: &str) -> Result<Self, Self::Err> { - s.split(',') - .map(StaticDirective::from_str) - .collect::<Result<_, _>>() - .map(Self) - } -} - -impl<S> layer::Layer<S> for Targets -where - S: Subscriber, -{ - fn enabled(&self, metadata: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { - self.0.enabled(metadata) - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.interested(metadata) - } - - fn max_level_hint(&self) -> Option<LevelFilter> { - Some(self.0.max_level) - } -} - -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -impl<S> layer::Filter<S> for Targets { - fn enabled(&self, metadata: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { - self.0.enabled(metadata) - } - - fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - self.interested(metadata) - } - - fn max_level_hint(&self) -> Option<LevelFilter> { - Some(self.0.max_level) - } -} - -impl IntoIterator for Targets { - type Item = (String, LevelFilter); - - type IntoIter = IntoIter; - - fn into_iter(self) -> Self::IntoIter { - IntoIter::new(self) - } -} - -impl<'a> IntoIterator for &'a Targets { - type Item = (&'a str, LevelFilter); - - type IntoIter = Iter<'a>; - - fn into_iter(self) -> Self::IntoIter { - Iter::new(self) - } -} - -/// An owning iterator over the [target]-[level] pairs of a `Targets` filter. -/// -/// This struct is created by the `IntoIterator` trait implementation of [`Targets`]. -/// -/// # Examples -/// -/// Merge the targets from one `Targets` with another: -/// -/// ``` -/// use tracing_subscriber::filter::Targets; -/// use tracing_core::Level; -/// -/// let mut filter = Targets::new().with_target("my_crate", Level::INFO); -/// let overrides = Targets::new().with_target("my_crate::interesting_module", Level::DEBUG); -/// -/// filter.extend(overrides); -/// # drop(filter); -/// ``` -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -#[derive(Debug)] -pub struct IntoIter( - #[allow(clippy::type_complexity)] // alias indirection would probably make this more confusing - FilterMap< - <DirectiveSet<StaticDirective> as IntoIterator>::IntoIter, - fn(StaticDirective) -> Option<(String, LevelFilter)>, - >, -); - -impl IntoIter { - fn new(targets: Targets) -> Self { - Self(targets.0.into_iter().filter_map(|directive| { - let level = directive.level; - directive.target.map(|target| (target, level)) - })) - } -} - -impl Iterator for IntoIter { - type Item = (String, LevelFilter); - - fn next(&mut self) -> Option<Self::Item> { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.0.size_hint() - } -} - -/// A borrowing iterator over the [target]-[level] pairs of a `Targets` filter. -/// -/// This struct is created by [`iter`] method of [`Targets`], or from the `IntoIterator` -/// implementation for `&Targets`. -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -/// [`iter`]: Targets::iter -#[derive(Debug)] -pub struct Iter<'a>( - FilterMap< - slice::Iter<'a, StaticDirective>, - fn(&'a StaticDirective) -> Option<(&'a str, LevelFilter)>, - >, -); - -impl<'a> Iter<'a> { - fn new(targets: &'a Targets) -> Self { - Self(targets.0.iter().filter_map(|directive| { - directive - .target - .as_deref() - .map(|target| (target, directive.level)) - })) - } -} - -impl<'a> Iterator for Iter<'a> { - type Item = (&'a str, LevelFilter); - - fn next(&mut self) -> Option<Self::Item> { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.0.size_hint() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - feature! { - #![not(feature = "std")] - use alloc::{vec, vec::Vec, string::ToString}; - - // `dbg!` is only available with `libstd`; just nop it out when testing - // with alloc only. - macro_rules! dbg { - ($x:expr) => { $x } - } - } - - fn expect_parse(s: &str) -> Targets { - match dbg!(s).parse::<Targets>() { - Err(e) => panic!("string {:?} did not parse successfully: {}", s, e), - Ok(e) => e, - } - } - - fn expect_parse_ralith(s: &str) { - let dirs = expect_parse(s).0.into_vec(); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("server".to_string())); - assert_eq!(dirs[0].level, LevelFilter::DEBUG); - assert_eq!(dirs[0].field_names, Vec::<String>::new()); - - assert_eq!(dirs[1].target, Some("common".to_string())); - assert_eq!(dirs[1].level, LevelFilter::INFO); - assert_eq!(dirs[1].field_names, Vec::<String>::new()); - } - - fn expect_parse_level_directives(s: &str) { - let dirs = expect_parse(s).0.into_vec(); - assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); - - assert_eq!(dirs[0].target, Some("crate3::mod2::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::OFF); - assert_eq!(dirs[0].field_names, Vec::<String>::new()); - - assert_eq!(dirs[1].target, Some("crate1::mod2::mod3".to_string())); - assert_eq!(dirs[1].level, LevelFilter::INFO); - assert_eq!(dirs[1].field_names, Vec::<String>::new()); - - assert_eq!(dirs[2].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::WARN); - assert_eq!(dirs[2].field_names, Vec::<String>::new()); - - assert_eq!(dirs[3].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[3].level, LevelFilter::ERROR); - assert_eq!(dirs[3].field_names, Vec::<String>::new()); - - assert_eq!(dirs[4].target, Some("crate3".to_string())); - assert_eq!(dirs[4].level, LevelFilter::TRACE); - assert_eq!(dirs[4].field_names, Vec::<String>::new()); - - assert_eq!(dirs[5].target, Some("crate2".to_string())); - assert_eq!(dirs[5].level, LevelFilter::DEBUG); - assert_eq!(dirs[5].field_names, Vec::<String>::new()); - } - - #[test] - fn parse_ralith() { - expect_parse_ralith("common=info,server=debug"); - } - - #[test] - fn parse_ralith_uc() { - expect_parse_ralith("common=INFO,server=DEBUG"); - } - - #[test] - fn parse_ralith_mixed() { - expect_parse("common=iNfo,server=dEbUg"); - } - - #[test] - fn expect_parse_valid() { - let dirs = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .0 - .into_vec(); - assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::TRACE); - assert_eq!(dirs[0].field_names, Vec::<String>::new()); - - assert_eq!(dirs[1].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[1].level, LevelFilter::ERROR); - assert_eq!(dirs[1].field_names, Vec::<String>::new()); - - assert_eq!(dirs[2].target, Some("crate3".to_string())); - assert_eq!(dirs[2].level, LevelFilter::OFF); - assert_eq!(dirs[2].field_names, Vec::<String>::new()); - - assert_eq!(dirs[3].target, Some("crate2".to_string())); - assert_eq!(dirs[3].level, LevelFilter::DEBUG); - assert_eq!(dirs[3].field_names, Vec::<String>::new()); - } - - #[test] - fn parse_level_directives() { - expect_parse_level_directives( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ) - } - - #[test] - fn parse_uppercase_level_directives() { - expect_parse_level_directives( - "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\ - crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF", - ) - } - - #[test] - fn parse_numeric_level_directives() { - expect_parse_level_directives( - "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\ - crate3=5,crate3::mod2::mod1=0", - ) - } - - #[test] - fn targets_iter() { - let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .with_default(LevelFilter::WARN); - - let mut targets: Vec<_> = filter.iter().collect(); - targets.sort(); - - assert_eq!( - targets, - vec![ - ("crate1::mod1", LevelFilter::ERROR), - ("crate1::mod2", LevelFilter::TRACE), - ("crate2", LevelFilter::DEBUG), - ("crate3", LevelFilter::OFF), - ] - ); - } - - #[test] - fn targets_into_iter() { - let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .with_default(LevelFilter::WARN); - - let mut targets: Vec<_> = filter.into_iter().collect(); - targets.sort(); - - assert_eq!( - targets, - vec![ - ("crate1::mod1".to_string(), LevelFilter::ERROR), - ("crate1::mod2".to_string(), LevelFilter::TRACE), - ("crate2".to_string(), LevelFilter::DEBUG), - ("crate3".to_string(), LevelFilter::OFF), - ] - ); - } - - #[test] - // `println!` is only available with `libstd`. - #[cfg(feature = "std")] - fn size_of_filters() { - fn print_sz(s: &str) { - let filter = s.parse::<Targets>().expect("filter should parse"); - println!( - "size_of_val({:?})\n -> {}B", - s, - std::mem::size_of_val(&filter) - ); - } - - print_sz("info"); - - print_sz("foo=debug"); - - print_sz( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ); - } -} |