summaryrefslogtreecommitdiffstats
path: root/vendor/tracing-subscriber/src/filter
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tracing-subscriber/src/filter')
-rw-r--r--vendor/tracing-subscriber/src/filter/directive.rs456
-rw-r--r--vendor/tracing-subscriber/src/filter/env/builder.rs324
-rw-r--r--vendor/tracing-subscriber/src/filter/env/directive.rs860
-rw-r--r--vendor/tracing-subscriber/src/filter/env/field.rs626
-rw-r--r--vendor/tracing-subscriber/src/filter/env/mod.rs991
-rw-r--r--vendor/tracing-subscriber/src/filter/filter_fn.rs749
-rw-r--r--vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs469
-rw-r--r--vendor/tracing-subscriber/src/filter/layer_filters/mod.rs1135
-rw-r--r--vendor/tracing-subscriber/src/filter/level.rs27
-rw-r--r--vendor/tracing-subscriber/src/filter/mod.rs66
-rw-r--r--vendor/tracing-subscriber/src/filter/targets.rs710
11 files changed, 0 insertions, 6413 deletions
diff --git a/vendor/tracing-subscriber/src/filter/directive.rs b/vendor/tracing-subscriber/src/filter/directive.rs
deleted file mode 100644
index 2ae3f0f24..000000000
--- a/vendor/tracing-subscriber/src/filter/directive.rs
+++ /dev/null
@@ -1,456 +0,0 @@
-use crate::filter::level::{self, LevelFilter};
-#[cfg(not(feature = "smallvec"))]
-use alloc::vec;
-#[cfg(not(feature = "std"))]
-use alloc::{string::String, vec::Vec};
-
-use core::{cmp::Ordering, fmt, iter::FromIterator, slice, str::FromStr};
-use tracing_core::{Level, Metadata};
-/// Indicates that a string could not be parsed as a filtering directive.
-#[derive(Debug)]
-pub struct ParseError {
- kind: ParseErrorKind,
-}
-
-/// A directive which will statically enable or disable a given callsite.
-///
-/// Unlike a dynamic directive, this can be cached by the callsite.
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub(crate) struct StaticDirective {
- pub(in crate::filter) target: Option<String>,
- pub(in crate::filter) field_names: Vec<String>,
- pub(in crate::filter) level: LevelFilter,
-}
-
-#[cfg(feature = "smallvec")]
-pub(crate) type FilterVec<T> = smallvec::SmallVec<[T; 8]>;
-#[cfg(not(feature = "smallvec"))]
-pub(crate) type FilterVec<T> = Vec<T>;
-
-#[derive(Debug, PartialEq, Clone)]
-pub(in crate::filter) struct DirectiveSet<T> {
- directives: FilterVec<T>,
- pub(in crate::filter) max_level: LevelFilter,
-}
-
-pub(in crate::filter) trait Match {
- fn cares_about(&self, meta: &Metadata<'_>) -> bool;
- fn level(&self) -> &LevelFilter;
-}
-
-#[derive(Debug)]
-enum ParseErrorKind {
- #[cfg(feature = "std")]
- Field(Box<dyn std::error::Error + Send + Sync>),
- Level(level::ParseError),
- Other(Option<&'static str>),
-}
-
-// === impl DirectiveSet ===
-
-impl<T> DirectiveSet<T> {
- #[cfg(feature = "env-filter")]
- pub(crate) fn is_empty(&self) -> bool {
- self.directives.is_empty()
- }
-
- pub(crate) fn iter(&self) -> slice::Iter<'_, T> {
- self.directives.iter()
- }
-}
-
-impl<T: Ord> Default for DirectiveSet<T> {
- fn default() -> Self {
- Self {
- directives: FilterVec::new(),
- max_level: LevelFilter::OFF,
- }
- }
-}
-
-impl<T: Match + Ord> DirectiveSet<T> {
- pub(crate) fn directives(&self) -> impl Iterator<Item = &T> {
- self.directives.iter()
- }
-
- pub(crate) fn directives_for<'a>(
- &'a self,
- metadata: &'a Metadata<'a>,
- ) -> impl Iterator<Item = &'a T> + 'a {
- self.directives().filter(move |d| d.cares_about(metadata))
- }
-
- pub(crate) fn add(&mut self, directive: T) {
- // does this directive enable a more verbose level than the current
- // max? if so, update the max level.
- let level = *directive.level();
- if level > self.max_level {
- self.max_level = level;
- }
- // insert the directive into the vec of directives, ordered by
- // specificity (length of target + number of field filters). this
- // ensures that, when finding a directive to match a span or event, we
- // search the directive set in most specific first order.
- match self.directives.binary_search(&directive) {
- Ok(i) => self.directives[i] = directive,
- Err(i) => self.directives.insert(i, directive),
- }
- }
-
- #[cfg(test)]
- pub(in crate::filter) fn into_vec(self) -> FilterVec<T> {
- self.directives
- }
-}
-
-impl<T: Match + Ord> FromIterator<T> for DirectiveSet<T> {
- fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
- let mut this = Self::default();
- this.extend(iter);
- this
- }
-}
-
-impl<T: Match + Ord> Extend<T> for DirectiveSet<T> {
- fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
- for directive in iter.into_iter() {
- self.add(directive);
- }
- }
-}
-
-impl<T> IntoIterator for DirectiveSet<T> {
- type Item = T;
-
- #[cfg(feature = "smallvec")]
- type IntoIter = smallvec::IntoIter<[T; 8]>;
- #[cfg(not(feature = "smallvec"))]
- type IntoIter = vec::IntoIter<T>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.directives.into_iter()
- }
-}
-
-// === impl Statics ===
-
-impl DirectiveSet<StaticDirective> {
- pub(crate) fn enabled(&self, meta: &Metadata<'_>) -> bool {
- let level = meta.level();
- match self.directives_for(meta).next() {
- Some(d) => d.level >= *level,
- None => false,
- }
- }
-
- /// Same as `enabled` above, but skips `Directive`'s with fields.
- pub(crate) fn target_enabled(&self, target: &str, level: &Level) -> bool {
- match self.directives_for_target(target).next() {
- Some(d) => d.level >= *level,
- None => false,
- }
- }
-
- pub(crate) fn directives_for_target<'a>(
- &'a self,
- target: &'a str,
- ) -> impl Iterator<Item = &'a StaticDirective> + 'a {
- self.directives()
- .filter(move |d| d.cares_about_target(target))
- }
-}
-
-// === impl StaticDirective ===
-
-impl StaticDirective {
- pub(in crate::filter) fn new(
- target: Option<String>,
- field_names: Vec<String>,
- level: LevelFilter,
- ) -> Self {
- Self {
- target,
- field_names,
- level,
- }
- }
-
- pub(in crate::filter) fn cares_about_target(&self, to_check: &str) -> bool {
- // Does this directive have a target filter, and does it match the
- // metadata's target?
- if let Some(ref target) = self.target {
- if !to_check.starts_with(&target[..]) {
- return false;
- }
- }
-
- if !self.field_names.is_empty() {
- return false;
- }
-
- true
- }
-}
-
-impl Ord for StaticDirective {
- fn cmp(&self, other: &StaticDirective) -> Ordering {
- // We attempt to order directives by how "specific" they are. This
- // ensures that we try the most specific directives first when
- // attempting to match a piece of metadata.
-
- // First, we compare based on whether a target is specified, and the
- // lengths of those targets if both have targets.
- let ordering = self
- .target
- .as_ref()
- .map(String::len)
- .cmp(&other.target.as_ref().map(String::len))
- // Then we compare how many field names are matched by each directive.
- .then_with(|| self.field_names.len().cmp(&other.field_names.len()))
- // Finally, we fall back to lexicographical ordering if the directives are
- // equally specific. Although this is no longer semantically important,
- // we need to define a total ordering to determine the directive's place
- // in the BTreeMap.
- .then_with(|| {
- self.target
- .cmp(&other.target)
- .then_with(|| self.field_names[..].cmp(&other.field_names[..]))
- })
- .reverse();
-
- #[cfg(debug_assertions)]
- {
- if ordering == Ordering::Equal {
- debug_assert_eq!(
- self.target, other.target,
- "invariant violated: Ordering::Equal must imply a.target == b.target"
- );
- debug_assert_eq!(
- self.field_names, other.field_names,
- "invariant violated: Ordering::Equal must imply a.field_names == b.field_names"
- );
- }
- }
-
- ordering
- }
-}
-
-impl PartialOrd for StaticDirective {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Match for StaticDirective {
- fn cares_about(&self, meta: &Metadata<'_>) -> bool {
- // Does this directive have a target filter, and does it match the
- // metadata's target?
- if let Some(ref target) = self.target {
- if !meta.target().starts_with(&target[..]) {
- return false;
- }
- }
-
- if meta.is_event() && !self.field_names.is_empty() {
- let fields = meta.fields();
- for name in &self.field_names {
- if fields.field(name).is_none() {
- return false;
- }
- }
- }
-
- true
- }
-
- fn level(&self) -> &LevelFilter {
- &self.level
- }
-}
-
-impl Default for StaticDirective {
- fn default() -> Self {
- StaticDirective {
- target: None,
- field_names: Vec::new(),
- level: LevelFilter::ERROR,
- }
- }
-}
-
-impl fmt::Display for StaticDirective {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut wrote_any = false;
- if let Some(ref target) = self.target {
- fmt::Display::fmt(target, f)?;
- wrote_any = true;
- }
-
- if !self.field_names.is_empty() {
- f.write_str("[")?;
-
- let mut fields = self.field_names.iter();
- if let Some(field) = fields.next() {
- write!(f, "{{{}", field)?;
- for field in fields {
- write!(f, ",{}", field)?;
- }
- f.write_str("}")?;
- }
-
- f.write_str("]")?;
- wrote_any = true;
- }
-
- if wrote_any {
- f.write_str("=")?;
- }
-
- fmt::Display::fmt(&self.level, f)
- }
-}
-
-impl FromStr for StaticDirective {
- type Err = ParseError;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- // This method parses a filtering directive in one of the following
- // forms:
- //
- // * `foo=trace` (TARGET=LEVEL)
- // * `foo[{bar,baz}]=info` (TARGET[{FIELD,+}]=LEVEL)
- // * `trace` (bare LEVEL)
- // * `foo` (bare TARGET)
- let mut split = s.split('=');
- let part0 = split
- .next()
- .ok_or_else(|| ParseError::msg("string must not be empty"))?;
-
- // Directive includes an `=`:
- // * `foo=trace`
- // * `foo[{bar}]=trace`
- // * `foo[{bar,baz}]=trace`
- if let Some(part1) = split.next() {
- if split.next().is_some() {
- return Err(ParseError::msg(
- "too many '=' in filter directive, expected 0 or 1",
- ));
- }
-
- let mut split = part0.split("[{");
- let target = split.next().map(String::from);
- let mut field_names = Vec::new();
- // Directive includes fields:
- // * `foo[{bar}]=trace`
- // * `foo[{bar,baz}]=trace`
- if let Some(maybe_fields) = split.next() {
- if split.next().is_some() {
- return Err(ParseError::msg(
- "too many '[{' in filter directive, expected 0 or 1",
- ));
- }
-
- if !maybe_fields.ends_with("}]") {
- return Err(ParseError::msg("expected fields list to end with '}]'"));
- }
-
- let fields = maybe_fields
- .trim_end_matches("}]")
- .split(',')
- .filter_map(|s| {
- if s.is_empty() {
- None
- } else {
- Some(String::from(s))
- }
- });
- field_names.extend(fields);
- };
- let level = part1.parse()?;
- return Ok(Self {
- level,
- field_names,
- target,
- });
- }
-
- // Okay, the part after the `=` was empty, the directive is either a
- // bare level or a bare target.
- // * `foo`
- // * `info`
- Ok(match part0.parse::<LevelFilter>() {
- Ok(level) => Self {
- level,
- target: None,
- field_names: Vec::new(),
- },
- Err(_) => Self {
- target: Some(String::from(part0)),
- level: LevelFilter::TRACE,
- field_names: Vec::new(),
- },
- })
- }
-}
-
-// === impl ParseError ===
-
-impl ParseError {
- #[cfg(feature = "env-filter")]
- pub(crate) fn new() -> Self {
- ParseError {
- kind: ParseErrorKind::Other(None),
- }
- }
-
- pub(crate) fn msg(s: &'static str) -> Self {
- ParseError {
- kind: ParseErrorKind::Other(Some(s)),
- }
- }
-}
-
-impl fmt::Display for ParseError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.kind {
- ParseErrorKind::Other(None) => f.pad("invalid filter directive"),
- ParseErrorKind::Other(Some(msg)) => write!(f, "invalid filter directive: {}", msg),
- ParseErrorKind::Level(ref l) => l.fmt(f),
- #[cfg(feature = "std")]
- ParseErrorKind::Field(ref e) => write!(f, "invalid field filter: {}", e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for ParseError {
- fn description(&self) -> &str {
- "invalid filter directive"
- }
-
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self.kind {
- ParseErrorKind::Other(_) => None,
- ParseErrorKind::Level(ref l) => Some(l),
- ParseErrorKind::Field(ref n) => Some(n.as_ref()),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl From<Box<dyn std::error::Error + Send + Sync>> for ParseError {
- fn from(e: Box<dyn std::error::Error + Send + Sync>) -> Self {
- Self {
- kind: ParseErrorKind::Field(e),
- }
- }
-}
-
-impl From<level::ParseError> for ParseError {
- fn from(l: level::ParseError) -> Self {
- Self {
- kind: ParseErrorKind::Level(l),
- }
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/env/builder.rs b/vendor/tracing-subscriber/src/filter/env/builder.rs
deleted file mode 100644
index 36b520543..000000000
--- a/vendor/tracing-subscriber/src/filter/env/builder.rs
+++ /dev/null
@@ -1,324 +0,0 @@
-use super::{
- directive::{self, Directive},
- EnvFilter, FromEnvError,
-};
-use crate::sync::RwLock;
-use std::env;
-use thread_local::ThreadLocal;
-use tracing::level_filters::STATIC_MAX_LEVEL;
-
-/// A [builder] for constructing new [`EnvFilter`]s.
-///
-/// [builder]: https://rust-unofficial.github.io/patterns/patterns/creational/builder.html
-#[derive(Debug, Clone)]
-pub struct Builder {
- regex: bool,
- env: Option<String>,
- default_directive: Option<Directive>,
-}
-
-impl Builder {
- /// Sets whether span field values can be matched with regular expressions.
- ///
- /// If this is `true`, field filter directives will be interpreted as
- /// regular expressions if they are not able to be interpreted as a `bool`,
- /// `i64`, `u64`, or `f64` literal. If this is `false,` those field values
- /// will be interpreted as literal [`std::fmt::Debug`] output instead.
- ///
- /// By default, regular expressions are enabled.
- ///
- /// **Note**: when [`EnvFilter`]s are constructed from untrusted inputs,
- /// disabling regular expressions is strongly encouraged.
- pub fn with_regex(self, regex: bool) -> Self {
- Self { regex, ..self }
- }
-
- /// Sets a default [filtering directive] that will be added to the filter if
- /// the parsed string or environment variable contains no filter directives.
- ///
- /// By default, there is no default directive.
- ///
- /// # Examples
- ///
- /// If [`parse`], [`parse_lossy`], [`from_env`], or [`from_env_lossy`] are
- /// called with an empty string or environment variable, the default
- /// directive is used instead:
- ///
- /// ```rust
- /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// let filter = EnvFilter::builder()
- /// .with_default_directive(LevelFilter::INFO.into())
- /// .parse("")?;
- ///
- /// assert_eq!(format!("{}", filter), "info");
- /// # Ok(()) }
- /// ```
- ///
- /// Note that the `lossy` variants ([`parse_lossy`] and [`from_env_lossy`])
- /// will ignore any invalid directives. If all directives in a filter
- /// string or environment variable are invalid, those methods will also use
- /// the default directive:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// let filter = EnvFilter::builder()
- /// .with_default_directive(LevelFilter::INFO.into())
- /// .parse_lossy("some_target=fake level,foo::bar=lolwut");
- ///
- /// assert_eq!(format!("{}", filter), "info");
- /// ```
- ///
- ///
- /// If the string or environment variable contains valid filtering
- /// directives, the default directive is not used:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// let filter = EnvFilter::builder()
- /// .with_default_directive(LevelFilter::INFO.into())
- /// .parse_lossy("foo=trace");
- ///
- /// // The default directive is *not* used:
- /// assert_eq!(format!("{}", filter), "foo=trace");
- /// ```
- ///
- /// Parsing a more complex default directive from a string:
- ///
- /// ```rust
- /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// let default = "myapp=debug".parse()
- /// .expect("hard-coded default directive should be valid");
- ///
- /// let filter = EnvFilter::builder()
- /// .with_default_directive(default)
- /// .parse("")?;
- ///
- /// assert_eq!(format!("{}", filter), "myapp=debug");
- /// # Ok(()) }
- /// ```
- ///
- /// [`parse_lossy`]: Self::parse_lossy
- /// [`from_env_lossy`]: Self::from_env_lossy
- /// [`parse`]: Self::parse
- /// [`from_env`]: Self::from_env
- pub fn with_default_directive(self, default_directive: Directive) -> Self {
- Self {
- default_directive: Some(default_directive),
- ..self
- }
- }
-
- /// Sets the name of the environment variable used by the [`from_env`],
- /// [`from_env_lossy`], and [`try_from_env`] methods.
- ///
- /// By default, this is the value of [`EnvFilter::DEFAULT_ENV`]
- /// (`RUST_LOG`).
- ///
- /// [`from_env`]: Self::from_env
- /// [`from_env_lossy`]: Self::from_env_lossy
- /// [`try_from_env`]: Self::try_from_env
- pub fn with_env_var(self, var: impl ToString) -> Self {
- Self {
- env: Some(var.to_string()),
- ..self
- }
- }
-
- /// Returns a new [`EnvFilter`] from the directives in the given string,
- /// *ignoring* any that are invalid.
- pub fn parse_lossy<S: AsRef<str>>(&self, dirs: S) -> EnvFilter {
- let directives = dirs
- .as_ref()
- .split(',')
- .filter(|s| !s.is_empty())
- .filter_map(|s| match Directive::parse(s, self.regex) {
- Ok(d) => Some(d),
- Err(err) => {
- eprintln!("ignoring `{}`: {}", s, err);
- None
- }
- });
- self.from_directives(directives)
- }
-
- /// Returns a new [`EnvFilter`] from the directives in the given string,
- /// or an error if any are invalid.
- pub fn parse<S: AsRef<str>>(&self, dirs: S) -> Result<EnvFilter, directive::ParseError> {
- let dirs = dirs.as_ref();
- if dirs.is_empty() {
- return Ok(self.from_directives(std::iter::empty()));
- }
- let directives = dirs
- .split(',')
- .filter(|s| !s.is_empty())
- .map(|s| Directive::parse(s, self.regex))
- .collect::<Result<Vec<_>, _>>()?;
- Ok(self.from_directives(directives))
- }
-
- /// Returns a new [`EnvFilter`] from the directives in the configured
- /// environment variable, ignoring any directives that are invalid.
- pub fn from_env_lossy(&self) -> EnvFilter {
- let var = env::var(self.env_var_name()).unwrap_or_default();
- self.parse_lossy(var)
- }
-
- /// Returns a new [`EnvFilter`] from the directives in the in the configured
- /// environment variable, or an error if the environment variable is not set
- /// or contains invalid directives.
- pub fn from_env(&self) -> Result<EnvFilter, FromEnvError> {
- let var = env::var(self.env_var_name()).unwrap_or_default();
- self.parse(var).map_err(Into::into)
- }
-
- /// Returns a new [`EnvFilter`] from the directives in the in the configured
- /// environment variable, or an error if the environment variable is not set
- /// or contains invalid directives.
- pub fn try_from_env(&self) -> Result<EnvFilter, FromEnvError> {
- let var = env::var(self.env_var_name())?;
- self.parse(var).map_err(Into::into)
- }
-
- // TODO(eliza): consider making this a public API?
- // Clippy doesn't love this naming, because it suggests that `from_` methods
- // should not take a `Self`...but in this case, it's the `EnvFilter` that is
- // being constructed "from" the directives, rather than the builder itself.
- #[allow(clippy::wrong_self_convention)]
- pub(super) fn from_directives(
- &self,
- directives: impl IntoIterator<Item = Directive>,
- ) -> EnvFilter {
- use tracing::Level;
-
- let mut directives: Vec<_> = directives.into_iter().collect();
- let mut disabled = Vec::new();
- for directive in &mut directives {
- if directive.level > STATIC_MAX_LEVEL {
- disabled.push(directive.clone());
- }
- if !self.regex {
- directive.deregexify();
- }
- }
-
- if !disabled.is_empty() {
- #[cfg(feature = "ansi_term")]
- use ansi_term::{Color, Style};
- // NOTE: We can't use a configured `MakeWriter` because the EnvFilter
- // has no knowledge of any underlying subscriber or collector, which
- // may or may not use a `MakeWriter`.
- let warn = |msg: &str| {
- #[cfg(not(feature = "ansi_term"))]
- let msg = format!("warning: {}", msg);
- #[cfg(feature = "ansi_term")]
- let msg = {
- let bold = Style::new().bold();
- let mut warning = Color::Yellow.paint("warning");
- warning.style_ref_mut().is_bold = true;
- format!("{}{} {}", warning, bold.paint(":"), bold.paint(msg))
- };
- eprintln!("{}", msg);
- };
- let ctx_prefixed = |prefix: &str, msg: &str| {
- #[cfg(not(feature = "ansi_term"))]
- let msg = format!("{} {}", prefix, msg);
- #[cfg(feature = "ansi_term")]
- let msg = {
- let mut equal = Color::Fixed(21).paint("="); // dark blue
- equal.style_ref_mut().is_bold = true;
- format!(" {} {} {}", equal, Style::new().bold().paint(prefix), msg)
- };
- eprintln!("{}", msg);
- };
- let ctx_help = |msg| ctx_prefixed("help:", msg);
- let ctx_note = |msg| ctx_prefixed("note:", msg);
- let ctx = |msg: &str| {
- #[cfg(not(feature = "ansi_term"))]
- let msg = format!("note: {}", msg);
- #[cfg(feature = "ansi_term")]
- let msg = {
- let mut pipe = Color::Fixed(21).paint("|");
- pipe.style_ref_mut().is_bold = true;
- format!(" {} {}", pipe, msg)
- };
- eprintln!("{}", msg);
- };
- warn("some trace filter directives would enable traces that are disabled statically");
- for directive in disabled {
- let target = if let Some(target) = &directive.target {
- format!("the `{}` target", target)
- } else {
- "all targets".into()
- };
- let level = directive
- .level
- .into_level()
- .expect("=off would not have enabled any filters");
- ctx(&format!(
- "`{}` would enable the {} level for {}",
- directive, level, target
- ));
- }
- ctx_note(&format!("the static max level is `{}`", STATIC_MAX_LEVEL));
- let help_msg = || {
- let (feature, filter) = match STATIC_MAX_LEVEL.into_level() {
- Some(Level::TRACE) => unreachable!(
- "if the max level is trace, no static filtering features are enabled"
- ),
- Some(Level::DEBUG) => ("max_level_debug", Level::TRACE),
- Some(Level::INFO) => ("max_level_info", Level::DEBUG),
- Some(Level::WARN) => ("max_level_warn", Level::INFO),
- Some(Level::ERROR) => ("max_level_error", Level::WARN),
- None => return ("max_level_off", String::new()),
- };
- (feature, format!("{} ", filter))
- };
- let (feature, earlier_level) = help_msg();
- ctx_help(&format!(
- "to enable {}logging, remove the `{}` feature",
- earlier_level, feature
- ));
- }
-
- let (dynamics, statics) = Directive::make_tables(directives);
- let has_dynamics = !dynamics.is_empty();
-
- let mut filter = EnvFilter {
- statics,
- dynamics,
- has_dynamics,
- by_id: RwLock::new(Default::default()),
- by_cs: RwLock::new(Default::default()),
- scope: ThreadLocal::new(),
- regex: self.regex,
- };
-
- if !has_dynamics && filter.statics.is_empty() {
- if let Some(ref default) = self.default_directive {
- filter = filter.add_directive(default.clone());
- }
- }
-
- filter
- }
-
- fn env_var_name(&self) -> &str {
- self.env.as_deref().unwrap_or(EnvFilter::DEFAULT_ENV)
- }
-}
-
-impl Default for Builder {
- fn default() -> Self {
- Self {
- regex: true,
- env: None,
- default_directive: None,
- }
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/env/directive.rs b/vendor/tracing-subscriber/src/filter/env/directive.rs
deleted file mode 100644
index f062e6ef9..000000000
--- a/vendor/tracing-subscriber/src/filter/env/directive.rs
+++ /dev/null
@@ -1,860 +0,0 @@
-pub(crate) use crate::filter::directive::{FilterVec, ParseError, StaticDirective};
-use crate::filter::{
- directive::{DirectiveSet, Match},
- env::{field, FieldMap},
- level::LevelFilter,
-};
-use once_cell::sync::Lazy;
-use regex::Regex;
-use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr};
-use tracing_core::{span, Level, Metadata};
-
-/// A single filtering directive.
-// TODO(eliza): add a builder for programmatically constructing directives?
-#[derive(Clone, Debug, Eq, PartialEq)]
-#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))]
-pub struct Directive {
- in_span: Option<String>,
- fields: Vec<field::Match>,
- pub(crate) target: Option<String>,
- pub(crate) level: LevelFilter,
-}
-
-/// A set of dynamic filtering directives.
-pub(super) type Dynamics = DirectiveSet<Directive>;
-
-/// A set of static filtering directives.
-pub(super) type Statics = DirectiveSet<StaticDirective>;
-
-pub(crate) type CallsiteMatcher = MatchSet<field::CallsiteMatch>;
-pub(crate) type SpanMatcher = MatchSet<field::SpanMatch>;
-
-#[derive(Debug, PartialEq, Eq)]
-pub(crate) struct MatchSet<T> {
- field_matches: FilterVec<T>,
- base_level: LevelFilter,
-}
-
-impl Directive {
- pub(super) fn has_name(&self) -> bool {
- self.in_span.is_some()
- }
-
- pub(super) fn has_fields(&self) -> bool {
- !self.fields.is_empty()
- }
-
- pub(super) fn to_static(&self) -> Option<StaticDirective> {
- if !self.is_static() {
- return None;
- }
-
- // TODO(eliza): these strings are all immutable; we should consider
- // `Arc`ing them to make this more efficient...
- let field_names = self.fields.iter().map(field::Match::name).collect();
-
- Some(StaticDirective::new(
- self.target.clone(),
- field_names,
- self.level,
- ))
- }
-
- fn is_static(&self) -> bool {
- !self.has_name() && !self.fields.iter().any(field::Match::has_value)
- }
-
- pub(super) fn is_dynamic(&self) -> bool {
- self.has_name() || self.has_fields()
- }
-
- pub(crate) fn field_matcher(&self, meta: &Metadata<'_>) -> Option<field::CallsiteMatch> {
- let fieldset = meta.fields();
- let fields = self
- .fields
- .iter()
- .filter_map(
- |field::Match {
- ref name,
- ref value,
- }| {
- if let Some(field) = fieldset.field(name) {
- let value = value.as_ref().cloned()?;
- Some(Ok((field, value)))
- } else {
- Some(Err(()))
- }
- },
- )
- .collect::<Result<FieldMap<_>, ()>>()
- .ok()?;
- Some(field::CallsiteMatch {
- fields,
- level: self.level,
- })
- }
-
- pub(super) fn make_tables(
- directives: impl IntoIterator<Item = Directive>,
- ) -> (Dynamics, Statics) {
- // TODO(eliza): this could be made more efficient...
- let (dyns, stats): (Vec<Directive>, Vec<Directive>) =
- directives.into_iter().partition(Directive::is_dynamic);
- let statics = stats
- .into_iter()
- .filter_map(|d| d.to_static())
- .chain(dyns.iter().filter_map(Directive::to_static))
- .collect();
- (Dynamics::from_iter(dyns), statics)
- }
-
- pub(super) fn deregexify(&mut self) {
- for field in &mut self.fields {
- field.value = match field.value.take() {
- Some(field::ValueMatch::Pat(pat)) => {
- Some(field::ValueMatch::Debug(pat.into_debug_match()))
- }
- x => x,
- }
- }
- }
-
- pub(super) fn parse(from: &str, regex: bool) -> Result<Self, ParseError> {
- static DIRECTIVE_RE: Lazy<Regex> = Lazy::new(|| Regex::new(
- r"(?x)
- ^(?P<global_level>(?i:trace|debug|info|warn|error|off|[0-5]))$ |
- # ^^^.
- # `note: we match log level names case-insensitively
- ^
- (?: # target name or span name
- (?P<target>[\w:-]+)|(?P<span>\[[^\]]*\])
- ){1,2}
- (?: # level or nothing
- =(?P<level>(?i:trace|debug|info|warn|error|off|[0-5]))?
- # ^^^.
- # `note: we match log level names case-insensitively
- )?
- $
- "
- )
- .unwrap());
- static SPAN_PART_RE: Lazy<Regex> =
- Lazy::new(|| Regex::new(r#"(?P<name>[^\]\{]+)?(?:\{(?P<fields>[^\}]*)\})?"#).unwrap());
- static FIELD_FILTER_RE: Lazy<Regex> =
- // TODO(eliza): this doesn't _currently_ handle value matchers that include comma
- // characters. We should fix that.
- Lazy::new(|| Regex::new(r#"(?x)
- (
- # field name
- [[:word:]][[[:word:]]\.]*
- # value part (optional)
- (?:=[^,]+)?
- )
- # trailing comma or EOS
- (?:,\s?|$)
- "#).unwrap());
-
- let caps = DIRECTIVE_RE.captures(from).ok_or_else(ParseError::new)?;
-
- if let Some(level) = caps
- .name("global_level")
- .and_then(|s| s.as_str().parse().ok())
- {
- return Ok(Directive {
- level,
- ..Default::default()
- });
- }
-
- let target = caps.name("target").and_then(|c| {
- let s = c.as_str();
- if s.parse::<LevelFilter>().is_ok() {
- None
- } else {
- Some(s.to_owned())
- }
- });
-
- let (in_span, fields) = caps
- .name("span")
- .and_then(|cap| {
- let cap = cap.as_str().trim_matches(|c| c == '[' || c == ']');
- let caps = SPAN_PART_RE.captures(cap)?;
- let span = caps.name("name").map(|c| c.as_str().to_owned());
- let fields = caps
- .name("fields")
- .map(|c| {
- FIELD_FILTER_RE
- .find_iter(c.as_str())
- .map(|c| field::Match::parse(c.as_str(), regex))
- .collect::<Result<Vec<_>, _>>()
- })
- .unwrap_or_else(|| Ok(Vec::new()));
- Some((span, fields))
- })
- .unwrap_or_else(|| (None, Ok(Vec::new())));
-
- let level = caps
- .name("level")
- .and_then(|l| l.as_str().parse().ok())
- // Setting the target without the level enables every level for that target
- .unwrap_or(LevelFilter::TRACE);
-
- Ok(Self {
- level,
- target,
- in_span,
- fields: fields?,
- })
- }
-}
-
-impl Match for Directive {
- fn cares_about(&self, meta: &Metadata<'_>) -> bool {
- // Does this directive have a target filter, and does it match the
- // metadata's target?
- if let Some(ref target) = self.target {
- if !meta.target().starts_with(&target[..]) {
- return false;
- }
- }
-
- // Do we have a name filter, and does it match the metadata's name?
- // TODO(eliza): put name globbing here?
- if let Some(ref name) = self.in_span {
- if name != meta.name() {
- return false;
- }
- }
-
- // Does the metadata define all the fields that this directive cares about?
- let actual_fields = meta.fields();
- for expected_field in &self.fields {
- // Does the actual field set (from the metadata) contain this field?
- if actual_fields.field(&expected_field.name).is_none() {
- return false;
- }
- }
-
- true
- }
-
- fn level(&self) -> &LevelFilter {
- &self.level
- }
-}
-
-impl FromStr for Directive {
- type Err = ParseError;
- fn from_str(from: &str) -> Result<Self, Self::Err> {
- Directive::parse(from, true)
- }
-}
-
-impl Default for Directive {
- fn default() -> Self {
- Directive {
- level: LevelFilter::OFF,
- target: None,
- in_span: None,
- fields: Vec::new(),
- }
- }
-}
-
-impl PartialOrd for Directive {
- fn partial_cmp(&self, other: &Directive) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for Directive {
- fn cmp(&self, other: &Directive) -> Ordering {
- // We attempt to order directives by how "specific" they are. This
- // ensures that we try the most specific directives first when
- // attempting to match a piece of metadata.
-
- // First, we compare based on whether a target is specified, and the
- // lengths of those targets if both have targets.
- let ordering = self
- .target
- .as_ref()
- .map(String::len)
- .cmp(&other.target.as_ref().map(String::len))
- // Next compare based on the presence of span names.
- .then_with(|| self.in_span.is_some().cmp(&other.in_span.is_some()))
- // Then we compare how many fields are defined by each
- // directive.
- .then_with(|| self.fields.len().cmp(&other.fields.len()))
- // Finally, we fall back to lexicographical ordering if the directives are
- // equally specific. Although this is no longer semantically important,
- // we need to define a total ordering to determine the directive's place
- // in the BTreeMap.
- .then_with(|| {
- self.target
- .cmp(&other.target)
- .then_with(|| self.in_span.cmp(&other.in_span))
- .then_with(|| self.fields[..].cmp(&other.fields[..]))
- })
- .reverse();
-
- #[cfg(debug_assertions)]
- {
- if ordering == Ordering::Equal {
- debug_assert_eq!(
- self.target, other.target,
- "invariant violated: Ordering::Equal must imply a.target == b.target"
- );
- debug_assert_eq!(
- self.in_span, other.in_span,
- "invariant violated: Ordering::Equal must imply a.in_span == b.in_span"
- );
- debug_assert_eq!(
- self.fields, other.fields,
- "invariant violated: Ordering::Equal must imply a.fields == b.fields"
- );
- }
- }
-
- ordering
- }
-}
-
-impl fmt::Display for Directive {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut wrote_any = false;
- if let Some(ref target) = self.target {
- fmt::Display::fmt(target, f)?;
- wrote_any = true;
- }
-
- if self.in_span.is_some() || !self.fields.is_empty() {
- f.write_str("[")?;
-
- if let Some(ref span) = self.in_span {
- fmt::Display::fmt(span, f)?;
- }
-
- let mut fields = self.fields.iter();
- if let Some(field) = fields.next() {
- write!(f, "{{{}", field)?;
- for field in fields {
- write!(f, ",{}", field)?;
- }
- f.write_str("}")?;
- }
-
- f.write_str("]")?;
- wrote_any = true;
- }
-
- if wrote_any {
- f.write_str("=")?;
- }
-
- fmt::Display::fmt(&self.level, f)
- }
-}
-
-impl From<LevelFilter> for Directive {
- fn from(level: LevelFilter) -> Self {
- Self {
- level,
- ..Self::default()
- }
- }
-}
-
-impl From<Level> for Directive {
- fn from(level: Level) -> Self {
- LevelFilter::from_level(level).into()
- }
-}
-
-// === impl Dynamics ===
-
-impl Dynamics {
- pub(crate) fn matcher(&self, metadata: &Metadata<'_>) -> Option<CallsiteMatcher> {
- let mut base_level = None;
- let field_matches = self
- .directives_for(metadata)
- .filter_map(|d| {
- if let Some(f) = d.field_matcher(metadata) {
- return Some(f);
- }
- match base_level {
- Some(ref b) if d.level > *b => base_level = Some(d.level),
- None => base_level = Some(d.level),
- _ => {}
- }
- None
- })
- .collect();
-
- if let Some(base_level) = base_level {
- Some(CallsiteMatcher {
- field_matches,
- base_level,
- })
- } else if !field_matches.is_empty() {
- Some(CallsiteMatcher {
- field_matches,
- base_level: base_level.unwrap_or(LevelFilter::OFF),
- })
- } else {
- None
- }
- }
-
- pub(crate) fn has_value_filters(&self) -> bool {
- self.directives()
- .any(|d| d.fields.iter().any(|f| f.value.is_some()))
- }
-}
-
-// ===== impl DynamicMatch =====
-
-impl CallsiteMatcher {
- /// Create a new `SpanMatch` for a given instance of the matched callsite.
- pub(crate) fn to_span_match(&self, attrs: &span::Attributes<'_>) -> SpanMatcher {
- let field_matches = self
- .field_matches
- .iter()
- .map(|m| {
- let m = m.to_span_match();
- attrs.record(&mut m.visitor());
- m
- })
- .collect();
- SpanMatcher {
- field_matches,
- base_level: self.base_level,
- }
- }
-}
-
-impl SpanMatcher {
- /// Returns the level currently enabled for this callsite.
- pub(crate) fn level(&self) -> LevelFilter {
- self.field_matches
- .iter()
- .filter_map(field::SpanMatch::filter)
- .max()
- .unwrap_or(self.base_level)
- }
-
- pub(crate) fn record_update(&self, record: &span::Record<'_>) {
- for m in &self.field_matches {
- record.record(&mut m.visitor())
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- fn parse_directives(dirs: impl AsRef<str>) -> Vec<Directive> {
- dirs.as_ref()
- .split(',')
- .filter_map(|s| s.parse().ok())
- .collect()
- }
-
- fn expect_parse(dirs: impl AsRef<str>) -> Vec<Directive> {
- dirs.as_ref()
- .split(',')
- .map(|s| {
- s.parse()
- .unwrap_or_else(|err| panic!("directive '{:?}' should parse: {}", s, err))
- })
- .collect()
- }
-
- #[test]
- fn directive_ordering_by_target_len() {
- // TODO(eliza): it would be nice to have a property-based test for this
- // instead.
- let mut dirs = expect_parse(
- "foo::bar=debug,foo::bar::baz=trace,foo=info,a_really_long_name_with_no_colons=warn",
- );
- dirs.sort_unstable();
-
- let expected = vec![
- "a_really_long_name_with_no_colons",
- "foo::bar::baz",
- "foo::bar",
- "foo",
- ];
- let sorted = dirs
- .iter()
- .map(|d| d.target.as_ref().unwrap())
- .collect::<Vec<_>>();
-
- assert_eq!(expected, sorted);
- }
- #[test]
- fn directive_ordering_by_span() {
- // TODO(eliza): it would be nice to have a property-based test for this
- // instead.
- let mut dirs = expect_parse("bar[span]=trace,foo=debug,baz::quux=info,a[span]=warn");
- dirs.sort_unstable();
-
- let expected = vec!["baz::quux", "bar", "foo", "a"];
- let sorted = dirs
- .iter()
- .map(|d| d.target.as_ref().unwrap())
- .collect::<Vec<_>>();
-
- assert_eq!(expected, sorted);
- }
-
- #[test]
- fn directive_ordering_uses_lexicographic_when_equal() {
- // TODO(eliza): it would be nice to have a property-based test for this
- // instead.
- let mut dirs = expect_parse("span[b]=debug,b=debug,a=trace,c=info,span[a]=info");
- dirs.sort_unstable();
-
- let expected = vec![
- ("span", Some("b")),
- ("span", Some("a")),
- ("c", None),
- ("b", None),
- ("a", None),
- ];
- let sorted = dirs
- .iter()
- .map(|d| {
- (
- d.target.as_ref().unwrap().as_ref(),
- d.in_span.as_ref().map(String::as_ref),
- )
- })
- .collect::<Vec<_>>();
-
- assert_eq!(expected, sorted);
- }
-
- // TODO: this test requires the parser to support directives with multiple
- // fields, which it currently can't handle. We should enable this test when
- // that's implemented.
- #[test]
- #[ignore]
- fn directive_ordering_by_field_num() {
- // TODO(eliza): it would be nice to have a property-based test for this
- // instead.
- let mut dirs = expect_parse(
- "b[{foo,bar}]=info,c[{baz,quuux,quuux}]=debug,a[{foo}]=warn,bar[{field}]=trace,foo=debug,baz::quux=info"
- );
- dirs.sort_unstable();
-
- let expected = vec!["baz::quux", "bar", "foo", "c", "b", "a"];
- let sorted = dirs
- .iter()
- .map(|d| d.target.as_ref().unwrap())
- .collect::<Vec<_>>();
-
- assert_eq!(expected, sorted);
- }
-
- #[test]
- fn parse_directives_ralith() {
- let dirs = parse_directives("common=trace,server=trace");
- assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("common".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::TRACE);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("server".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::TRACE);
- assert_eq!(dirs[1].in_span, None);
- }
-
- #[test]
- fn parse_directives_ralith_uc() {
- let dirs = parse_directives("common=INFO,server=DEBUG");
- assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("common".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::INFO);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("server".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::DEBUG);
- assert_eq!(dirs[1].in_span, None);
- }
-
- #[test]
- fn parse_directives_ralith_mixed() {
- let dirs = parse_directives("common=iNfo,server=dEbUg");
- assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("common".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::INFO);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("server".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::DEBUG);
- assert_eq!(dirs[1].in_span, None);
- }
-
- #[test]
- fn parse_directives_valid() {
- let dirs = parse_directives("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off");
- assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate1::mod1".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::ERROR);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("crate1::mod2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::TRACE);
- assert_eq!(dirs[1].in_span, None);
-
- assert_eq!(dirs[2].target, Some("crate2".to_string()));
- assert_eq!(dirs[2].level, LevelFilter::DEBUG);
- assert_eq!(dirs[2].in_span, None);
-
- assert_eq!(dirs[3].target, Some("crate3".to_string()));
- assert_eq!(dirs[3].level, LevelFilter::OFF);
- assert_eq!(dirs[3].in_span, None);
- }
-
- #[test]
-
- fn parse_level_directives() {
- let dirs = parse_directives(
- "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\
- crate2=debug,crate3=trace,crate3::mod2::mod1=off",
- );
- assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate1::mod1".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::ERROR);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("crate1::mod2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::WARN);
- assert_eq!(dirs[1].in_span, None);
-
- assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string()));
- assert_eq!(dirs[2].level, LevelFilter::INFO);
- assert_eq!(dirs[2].in_span, None);
-
- assert_eq!(dirs[3].target, Some("crate2".to_string()));
- assert_eq!(dirs[3].level, LevelFilter::DEBUG);
- assert_eq!(dirs[3].in_span, None);
-
- assert_eq!(dirs[4].target, Some("crate3".to_string()));
- assert_eq!(dirs[4].level, LevelFilter::TRACE);
- assert_eq!(dirs[4].in_span, None);
-
- assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string()));
- assert_eq!(dirs[5].level, LevelFilter::OFF);
- assert_eq!(dirs[5].in_span, None);
- }
-
- #[test]
- fn parse_uppercase_level_directives() {
- let dirs = parse_directives(
- "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\
- crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF",
- );
- assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate1::mod1".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::ERROR);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("crate1::mod2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::WARN);
- assert_eq!(dirs[1].in_span, None);
-
- assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string()));
- assert_eq!(dirs[2].level, LevelFilter::INFO);
- assert_eq!(dirs[2].in_span, None);
-
- assert_eq!(dirs[3].target, Some("crate2".to_string()));
- assert_eq!(dirs[3].level, LevelFilter::DEBUG);
- assert_eq!(dirs[3].in_span, None);
-
- assert_eq!(dirs[4].target, Some("crate3".to_string()));
- assert_eq!(dirs[4].level, LevelFilter::TRACE);
- assert_eq!(dirs[4].in_span, None);
-
- assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string()));
- assert_eq!(dirs[5].level, LevelFilter::OFF);
- assert_eq!(dirs[5].in_span, None);
- }
-
- #[test]
- fn parse_numeric_level_directives() {
- let dirs = parse_directives(
- "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\
- crate3=5,crate3::mod2::mod1=0",
- );
- assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate1::mod1".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::ERROR);
- assert_eq!(dirs[0].in_span, None);
-
- assert_eq!(dirs[1].target, Some("crate1::mod2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::WARN);
- assert_eq!(dirs[1].in_span, None);
-
- assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string()));
- assert_eq!(dirs[2].level, LevelFilter::INFO);
- assert_eq!(dirs[2].in_span, None);
-
- assert_eq!(dirs[3].target, Some("crate2".to_string()));
- assert_eq!(dirs[3].level, LevelFilter::DEBUG);
- assert_eq!(dirs[3].in_span, None);
-
- assert_eq!(dirs[4].target, Some("crate3".to_string()));
- assert_eq!(dirs[4].level, LevelFilter::TRACE);
- assert_eq!(dirs[4].in_span, None);
-
- assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string()));
- assert_eq!(dirs[5].level, LevelFilter::OFF);
- assert_eq!(dirs[5].in_span, None);
- }
-
- #[test]
- fn parse_directives_invalid_crate() {
- // test parse_directives with multiple = in specification
- let dirs = parse_directives("crate1::mod1=warn=info,crate2=debug");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate2".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::DEBUG);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_invalid_level() {
- // test parse_directives with 'noNumber' as log level
- let dirs = parse_directives("crate1::mod1=noNumber,crate2=debug");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate2".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::DEBUG);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_string_level() {
- // test parse_directives with 'warn' as log level
- let dirs = parse_directives("crate1::mod1=wrong,crate2=warn");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate2".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::WARN);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_empty_level() {
- // test parse_directives with '' as log level
- let dirs = parse_directives("crate1::mod1=wrong,crate2=");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate2".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::TRACE);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_global() {
- // test parse_directives with no crate
- let dirs = parse_directives("warn,crate2=debug");
- assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, None);
- assert_eq!(dirs[0].level, LevelFilter::WARN);
- assert_eq!(dirs[1].in_span, None);
-
- assert_eq!(dirs[1].target, Some("crate2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::DEBUG);
- assert_eq!(dirs[1].in_span, None);
- }
-
- // helper function for tests below
- fn test_parse_bare_level(directive_to_test: &str, level_expected: LevelFilter) {
- let dirs = parse_directives(directive_to_test);
- assert_eq!(
- dirs.len(),
- 1,
- "\ninput: \"{}\"; parsed: {:#?}",
- directive_to_test,
- dirs
- );
- assert_eq!(dirs[0].target, None);
- assert_eq!(dirs[0].level, level_expected);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_global_bare_warn_lc() {
- // test parse_directives with no crate, in isolation, all lowercase
- test_parse_bare_level("warn", LevelFilter::WARN);
- }
-
- #[test]
- fn parse_directives_global_bare_warn_uc() {
- // test parse_directives with no crate, in isolation, all uppercase
- test_parse_bare_level("WARN", LevelFilter::WARN);
- }
-
- #[test]
- fn parse_directives_global_bare_warn_mixed() {
- // test parse_directives with no crate, in isolation, mixed case
- test_parse_bare_level("wArN", LevelFilter::WARN);
- }
-
- #[test]
- fn parse_directives_valid_with_spans() {
- let dirs = parse_directives("crate1::mod1[foo]=error,crate1::mod2[bar],crate2[baz]=debug");
- assert_eq!(dirs.len(), 3, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("crate1::mod1".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::ERROR);
- assert_eq!(dirs[0].in_span, Some("foo".to_string()));
-
- assert_eq!(dirs[1].target, Some("crate1::mod2".to_string()));
- assert_eq!(dirs[1].level, LevelFilter::TRACE);
- assert_eq!(dirs[1].in_span, Some("bar".to_string()));
-
- assert_eq!(dirs[2].target, Some("crate2".to_string()));
- assert_eq!(dirs[2].level, LevelFilter::DEBUG);
- assert_eq!(dirs[2].in_span, Some("baz".to_string()));
- }
-
- #[test]
- fn parse_directives_with_dash_in_target_name() {
- let dirs = parse_directives("target-name=info");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("target-name".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::INFO);
- assert_eq!(dirs[0].in_span, None);
- }
-
- #[test]
- fn parse_directives_with_dash_in_span_name() {
- // Reproduces https://github.com/tokio-rs/tracing/issues/1367
-
- let dirs = parse_directives("target[span-name]=info");
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("target".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::INFO);
- assert_eq!(dirs[0].in_span, Some("span-name".to_string()));
- }
-
- #[test]
- fn parse_directives_with_special_characters_in_span_name() {
- let span_name = "!\"#$%&'()*+-./:;<=>?@^_`|~[}";
-
- let dirs = parse_directives(format!("target[{}]=info", span_name));
- assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs);
- assert_eq!(dirs[0].target, Some("target".to_string()));
- assert_eq!(dirs[0].level, LevelFilter::INFO);
- assert_eq!(dirs[0].in_span, Some(span_name.to_string()));
- }
-
- #[test]
- fn parse_directives_with_invalid_span_chars() {
- let invalid_span_name = "]{";
-
- let dirs = parse_directives(format!("target[{}]=info", invalid_span_name));
- assert_eq!(dirs.len(), 0, "\nparsed: {:#?}", dirs);
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/env/field.rs b/vendor/tracing-subscriber/src/filter/env/field.rs
deleted file mode 100644
index 1394fd04a..000000000
--- a/vendor/tracing-subscriber/src/filter/env/field.rs
+++ /dev/null
@@ -1,626 +0,0 @@
-use matchers::Pattern;
-use std::{
- cmp::Ordering,
- error::Error,
- fmt::{self, Write},
- str::FromStr,
- sync::{
- atomic::{AtomicBool, Ordering::*},
- Arc,
- },
-};
-
-use super::{FieldMap, LevelFilter};
-use tracing_core::field::{Field, Visit};
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub(crate) struct Match {
- pub(crate) name: String, // TODO: allow match patterns for names?
- pub(crate) value: Option<ValueMatch>,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub(crate) struct CallsiteMatch {
- pub(crate) fields: FieldMap<ValueMatch>,
- pub(crate) level: LevelFilter,
-}
-
-#[derive(Debug)]
-pub(crate) struct SpanMatch {
- fields: FieldMap<(ValueMatch, AtomicBool)>,
- level: LevelFilter,
- has_matched: AtomicBool,
-}
-
-pub(crate) struct MatchVisitor<'a> {
- inner: &'a SpanMatch,
-}
-
-#[derive(Debug, Clone)]
-pub(crate) enum ValueMatch {
- /// Matches a specific `bool` value.
- Bool(bool),
- /// Matches a specific `f64` value.
- F64(f64),
- /// Matches a specific `u64` value.
- U64(u64),
- /// Matches a specific `i64` value.
- I64(i64),
- /// Matches any `NaN` `f64` value.
- NaN,
- /// Matches any field whose `fmt::Debug` output is equal to a fixed string.
- Debug(MatchDebug),
- /// Matches any field whose `fmt::Debug` output matches a regular expression
- /// pattern.
- Pat(Box<MatchPattern>),
-}
-
-impl Eq for ValueMatch {}
-
-impl PartialEq for ValueMatch {
- fn eq(&self, other: &Self) -> bool {
- use ValueMatch::*;
- match (self, other) {
- (Bool(a), Bool(b)) => a.eq(b),
- (F64(a), F64(b)) => {
- debug_assert!(!a.is_nan());
- debug_assert!(!b.is_nan());
-
- a.eq(b)
- }
- (U64(a), U64(b)) => a.eq(b),
- (I64(a), I64(b)) => a.eq(b),
- (NaN, NaN) => true,
- (Pat(a), Pat(b)) => a.eq(b),
- _ => false,
- }
- }
-}
-
-impl Ord for ValueMatch {
- fn cmp(&self, other: &Self) -> Ordering {
- use ValueMatch::*;
- match (self, other) {
- (Bool(this), Bool(that)) => this.cmp(that),
- (Bool(_), _) => Ordering::Less,
-
- (F64(this), F64(that)) => this
- .partial_cmp(that)
- .expect("`ValueMatch::F64` may not contain `NaN` values"),
- (F64(_), Bool(_)) => Ordering::Greater,
- (F64(_), _) => Ordering::Less,
-
- (NaN, NaN) => Ordering::Equal,
- (NaN, Bool(_)) | (NaN, F64(_)) => Ordering::Greater,
- (NaN, _) => Ordering::Less,
-
- (U64(this), U64(that)) => this.cmp(that),
- (U64(_), Bool(_)) | (U64(_), F64(_)) | (U64(_), NaN) => Ordering::Greater,
- (U64(_), _) => Ordering::Less,
-
- (I64(this), I64(that)) => this.cmp(that),
- (I64(_), Bool(_)) | (I64(_), F64(_)) | (I64(_), NaN) | (I64(_), U64(_)) => {
- Ordering::Greater
- }
- (I64(_), _) => Ordering::Less,
-
- (Pat(this), Pat(that)) => this.cmp(that),
- (Pat(_), _) => Ordering::Greater,
-
- (Debug(this), Debug(that)) => this.cmp(that),
- (Debug(_), _) => Ordering::Greater,
- }
- }
-}
-
-impl PartialOrd for ValueMatch {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-/// Matches a field's `fmt::Debug` output against a regular expression pattern.
-///
-/// This is used for matching all non-literal field value filters when regular
-/// expressions are enabled.
-#[derive(Debug, Clone)]
-pub(crate) struct MatchPattern {
- pub(crate) matcher: Pattern,
- pattern: Arc<str>,
-}
-
-/// Matches a field's `fmt::Debug` output against a fixed string pattern.
-///
-/// This is used for matching all non-literal field value filters when regular
-/// expressions are disabled.
-#[derive(Debug, Clone)]
-pub(crate) struct MatchDebug {
- pattern: Arc<str>,
-}
-
-/// Indicates that a field name specified in a filter directive was invalid.
-#[derive(Clone, Debug)]
-#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))]
-pub struct BadName {
- name: String,
-}
-
-// === impl Match ===
-
-impl Match {
- pub(crate) fn has_value(&self) -> bool {
- self.value.is_some()
- }
-
- // TODO: reference count these strings?
- pub(crate) fn name(&self) -> String {
- self.name.clone()
- }
-
- pub(crate) fn parse(s: &str, regex: bool) -> Result<Self, Box<dyn Error + Send + Sync>> {
- let mut parts = s.split('=');
- let name = parts
- .next()
- .ok_or_else(|| BadName {
- name: "".to_string(),
- })?
- // TODO: validate field name
- .to_string();
- let value = parts
- .next()
- .map(|part| match regex {
- true => ValueMatch::parse_regex(part),
- false => Ok(ValueMatch::parse_non_regex(part)),
- })
- .transpose()?;
- Ok(Match { name, value })
- }
-}
-
-impl fmt::Display for Match {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&self.name, f)?;
- if let Some(ref value) = self.value {
- write!(f, "={}", value)?;
- }
- Ok(())
- }
-}
-
-impl Ord for Match {
- fn cmp(&self, other: &Self) -> Ordering {
- // Ordering for `Match` directives is based first on _whether_ a value
- // is matched or not. This is semantically meaningful --- we would
- // prefer to check directives that match values first as they are more
- // specific.
- let has_value = match (self.value.as_ref(), other.value.as_ref()) {
- (Some(_), None) => Ordering::Greater,
- (None, Some(_)) => Ordering::Less,
- _ => Ordering::Equal,
- };
- // If both directives match a value, we fall back to the field names in
- // length + lexicographic ordering, and if these are equal as well, we
- // compare the match directives.
- //
- // This ordering is no longer semantically meaningful but is necessary
- // so that the directives can be stored in the `BTreeMap` in a defined
- // order.
- has_value
- .then_with(|| self.name.cmp(&other.name))
- .then_with(|| self.value.cmp(&other.value))
- }
-}
-
-impl PartialOrd for Match {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-// === impl ValueMatch ===
-
-fn value_match_f64(v: f64) -> ValueMatch {
- if v.is_nan() {
- ValueMatch::NaN
- } else {
- ValueMatch::F64(v)
- }
-}
-
-impl ValueMatch {
- /// Parse a `ValueMatch` that will match `fmt::Debug` fields using regular
- /// expressions.
- ///
- /// This returns an error if the string didn't contain a valid `bool`,
- /// `u64`, `i64`, or `f64` literal, and couldn't be parsed as a regular
- /// expression.
- fn parse_regex(s: &str) -> Result<Self, matchers::Error> {
- s.parse::<bool>()
- .map(ValueMatch::Bool)
- .or_else(|_| s.parse::<u64>().map(ValueMatch::U64))
- .or_else(|_| s.parse::<i64>().map(ValueMatch::I64))
- .or_else(|_| s.parse::<f64>().map(value_match_f64))
- .or_else(|_| {
- s.parse::<MatchPattern>()
- .map(|p| ValueMatch::Pat(Box::new(p)))
- })
- }
-
- /// Parse a `ValueMatch` that will match `fmt::Debug` against a fixed
- /// string.
- ///
- /// This does *not* return an error, because any string that isn't a valid
- /// `bool`, `u64`, `i64`, or `f64` literal is treated as expected
- /// `fmt::Debug` output.
- fn parse_non_regex(s: &str) -> Self {
- s.parse::<bool>()
- .map(ValueMatch::Bool)
- .or_else(|_| s.parse::<u64>().map(ValueMatch::U64))
- .or_else(|_| s.parse::<i64>().map(ValueMatch::I64))
- .or_else(|_| s.parse::<f64>().map(value_match_f64))
- .unwrap_or_else(|_| ValueMatch::Debug(MatchDebug::new(s)))
- }
-}
-
-impl fmt::Display for ValueMatch {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ValueMatch::Bool(ref inner) => fmt::Display::fmt(inner, f),
- ValueMatch::F64(ref inner) => fmt::Display::fmt(inner, f),
- ValueMatch::NaN => fmt::Display::fmt(&std::f64::NAN, f),
- ValueMatch::I64(ref inner) => fmt::Display::fmt(inner, f),
- ValueMatch::U64(ref inner) => fmt::Display::fmt(inner, f),
- ValueMatch::Debug(ref inner) => fmt::Display::fmt(inner, f),
- ValueMatch::Pat(ref inner) => fmt::Display::fmt(inner, f),
- }
- }
-}
-
-// === impl MatchPattern ===
-
-impl FromStr for MatchPattern {
- type Err = matchers::Error;
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- let matcher = s.parse::<Pattern>()?;
- Ok(Self {
- matcher,
- pattern: s.to_owned().into(),
- })
- }
-}
-
-impl fmt::Display for MatchPattern {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&*self.pattern, f)
- }
-}
-
-impl AsRef<str> for MatchPattern {
- #[inline]
- fn as_ref(&self) -> &str {
- self.pattern.as_ref()
- }
-}
-
-impl MatchPattern {
- #[inline]
- fn str_matches(&self, s: &impl AsRef<str>) -> bool {
- self.matcher.matches(s)
- }
-
- #[inline]
- fn debug_matches(&self, d: &impl fmt::Debug) -> bool {
- self.matcher.debug_matches(d)
- }
-
- pub(super) fn into_debug_match(self) -> MatchDebug {
- MatchDebug {
- pattern: self.pattern,
- }
- }
-}
-
-impl PartialEq for MatchPattern {
- #[inline]
- fn eq(&self, other: &Self) -> bool {
- self.pattern == other.pattern
- }
-}
-
-impl Eq for MatchPattern {}
-
-impl PartialOrd for MatchPattern {
- #[inline]
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.pattern.cmp(&other.pattern))
- }
-}
-
-impl Ord for MatchPattern {
- #[inline]
- fn cmp(&self, other: &Self) -> Ordering {
- self.pattern.cmp(&other.pattern)
- }
-}
-
-// === impl MatchDebug ===
-
-impl MatchDebug {
- fn new(s: &str) -> Self {
- Self {
- pattern: s.to_owned().into(),
- }
- }
-
- #[inline]
- fn debug_matches(&self, d: &impl fmt::Debug) -> bool {
- // Naively, we would probably match a value's `fmt::Debug` output by
- // formatting it to a string, and then checking if the string is equal
- // to the expected pattern. However, this would require allocating every
- // time we want to match a field value against a `Debug` matcher, which
- // can be avoided.
- //
- // Instead, we implement `fmt::Write` for a type that, rather than
- // actually _writing_ the strings to something, matches them against the
- // expected pattern, and returns an error if the pattern does not match.
- struct Matcher<'a> {
- pattern: &'a str,
- }
-
- impl fmt::Write for Matcher<'_> {
- fn write_str(&mut self, s: &str) -> fmt::Result {
- // If the string is longer than the remaining expected string,
- // we know it won't match, so bail.
- if s.len() > self.pattern.len() {
- return Err(fmt::Error);
- }
-
- // If the expected string begins with the string that was
- // written, we are still potentially a match. Advance the
- // position in the expected pattern to chop off the matched
- // output, and continue.
- if self.pattern.starts_with(s) {
- self.pattern = &self.pattern[s.len()..];
- return Ok(());
- }
-
- // Otherwise, the expected string doesn't include the string
- // that was written at the current position, so the `fmt::Debug`
- // output doesn't match! Return an error signalling that this
- // doesn't match.
- Err(fmt::Error)
- }
- }
- let mut matcher = Matcher {
- pattern: &self.pattern,
- };
-
- // Try to "write" the value's `fmt::Debug` output to a `Matcher`. This
- // returns an error if the `fmt::Debug` implementation wrote any
- // characters that did not match the expected pattern.
- write!(matcher, "{:?}", d).is_ok()
- }
-}
-
-impl fmt::Display for MatchDebug {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&*self.pattern, f)
- }
-}
-
-impl AsRef<str> for MatchDebug {
- #[inline]
- fn as_ref(&self) -> &str {
- self.pattern.as_ref()
- }
-}
-
-impl PartialEq for MatchDebug {
- #[inline]
- fn eq(&self, other: &Self) -> bool {
- self.pattern == other.pattern
- }
-}
-
-impl Eq for MatchDebug {}
-
-impl PartialOrd for MatchDebug {
- #[inline]
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.pattern.cmp(&other.pattern))
- }
-}
-
-impl Ord for MatchDebug {
- #[inline]
- fn cmp(&self, other: &Self) -> Ordering {
- self.pattern.cmp(&other.pattern)
- }
-}
-
-// === impl BadName ===
-
-impl Error for BadName {}
-
-impl fmt::Display for BadName {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "invalid field name `{}`", self.name)
- }
-}
-
-impl CallsiteMatch {
- pub(crate) fn to_span_match(&self) -> SpanMatch {
- let fields = self
- .fields
- .iter()
- .map(|(k, v)| (k.clone(), (v.clone(), AtomicBool::new(false))))
- .collect();
- SpanMatch {
- fields,
- level: self.level,
- has_matched: AtomicBool::new(false),
- }
- }
-}
-
-impl SpanMatch {
- pub(crate) fn visitor(&self) -> MatchVisitor<'_> {
- MatchVisitor { inner: self }
- }
-
- #[inline]
- pub(crate) fn is_matched(&self) -> bool {
- if self.has_matched.load(Acquire) {
- return true;
- }
- self.is_matched_slow()
- }
-
- #[inline(never)]
- fn is_matched_slow(&self) -> bool {
- let matched = self
- .fields
- .values()
- .all(|(_, matched)| matched.load(Acquire));
- if matched {
- self.has_matched.store(true, Release);
- }
- matched
- }
-
- #[inline]
- pub(crate) fn filter(&self) -> Option<LevelFilter> {
- if self.is_matched() {
- Some(self.level)
- } else {
- None
- }
- }
-}
-
-impl<'a> Visit for MatchVisitor<'a> {
- fn record_f64(&mut self, field: &Field, value: f64) {
- match self.inner.fields.get(field) {
- Some((ValueMatch::NaN, ref matched)) if value.is_nan() => {
- matched.store(true, Release);
- }
- Some((ValueMatch::F64(ref e), ref matched))
- if (value - *e).abs() < std::f64::EPSILON =>
- {
- matched.store(true, Release);
- }
- _ => {}
- }
- }
-
- fn record_i64(&mut self, field: &Field, value: i64) {
- use std::convert::TryInto;
-
- match self.inner.fields.get(field) {
- Some((ValueMatch::I64(ref e), ref matched)) if value == *e => {
- matched.store(true, Release);
- }
- Some((ValueMatch::U64(ref e), ref matched)) if Ok(value) == (*e).try_into() => {
- matched.store(true, Release);
- }
- _ => {}
- }
- }
-
- fn record_u64(&mut self, field: &Field, value: u64) {
- match self.inner.fields.get(field) {
- Some((ValueMatch::U64(ref e), ref matched)) if value == *e => {
- matched.store(true, Release);
- }
- _ => {}
- }
- }
-
- fn record_bool(&mut self, field: &Field, value: bool) {
- match self.inner.fields.get(field) {
- Some((ValueMatch::Bool(ref e), ref matched)) if value == *e => {
- matched.store(true, Release);
- }
- _ => {}
- }
- }
-
- fn record_str(&mut self, field: &Field, value: &str) {
- match self.inner.fields.get(field) {
- Some((ValueMatch::Pat(ref e), ref matched)) if e.str_matches(&value) => {
- matched.store(true, Release);
- }
- Some((ValueMatch::Debug(ref e), ref matched)) if e.debug_matches(&value) => {
- matched.store(true, Release)
- }
- _ => {}
- }
- }
-
- fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
- match self.inner.fields.get(field) {
- Some((ValueMatch::Pat(ref e), ref matched)) if e.debug_matches(&value) => {
- matched.store(true, Release);
- }
- Some((ValueMatch::Debug(ref e), ref matched)) if e.debug_matches(&value) => {
- matched.store(true, Release)
- }
- _ => {}
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[derive(Debug)]
- #[allow(dead_code)]
- struct MyStruct {
- answer: usize,
- question: &'static str,
- }
-
- #[test]
- fn debug_struct_match() {
- let my_struct = MyStruct {
- answer: 42,
- question: "life, the universe, and everything",
- };
-
- let pattern = "MyStruct { answer: 42, question: \"life, the universe, and everything\" }";
-
- assert_eq!(
- format!("{:?}", my_struct),
- pattern,
- "`MyStruct`'s `Debug` impl doesn't output the expected string"
- );
-
- let matcher = MatchDebug {
- pattern: pattern.into(),
- };
- assert!(matcher.debug_matches(&my_struct))
- }
-
- #[test]
- fn debug_struct_not_match() {
- let my_struct = MyStruct {
- answer: 42,
- question: "what shall we have for lunch?",
- };
-
- let pattern = "MyStruct { answer: 42, question: \"life, the universe, and everything\" }";
-
- assert_eq!(
- format!("{:?}", my_struct),
- "MyStruct { answer: 42, question: \"what shall we have for lunch?\" }",
- "`MyStruct`'s `Debug` impl doesn't output the expected string"
- );
-
- let matcher = MatchDebug {
- pattern: pattern.into(),
- };
- assert!(!matcher.debug_matches(&my_struct))
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/env/mod.rs b/vendor/tracing-subscriber/src/filter/env/mod.rs
deleted file mode 100644
index 81a9ae2bd..000000000
--- a/vendor/tracing-subscriber/src/filter/env/mod.rs
+++ /dev/null
@@ -1,991 +0,0 @@
-//! A `Layer` that enables or disables spans and events based on a set of
-//! filtering directives.
-
-// these are publicly re-exported, but the compiler doesn't realize
-// that for some reason.
-#[allow(unreachable_pub)]
-pub use self::{builder::Builder, directive::Directive, field::BadName as BadFieldName};
-mod builder;
-mod directive;
-mod field;
-
-use crate::{
- filter::LevelFilter,
- layer::{Context, Layer},
- sync::RwLock,
-};
-use directive::ParseError;
-use std::{cell::RefCell, collections::HashMap, env, error::Error, fmt, str::FromStr};
-use thread_local::ThreadLocal;
-use tracing_core::{
- callsite,
- field::Field,
- span,
- subscriber::{Interest, Subscriber},
- Metadata,
-};
-
-/// A [`Layer`] which filters spans and events based on a set of filter
-/// directives.
-///
-/// `EnvFilter` implements both the [`Layer`](#impl-Layer<S>) and [`Filter`] traits, so it may
-/// be used for both [global filtering][global] and [per-layer filtering][plf],
-/// respectively. See [the documentation on filtering with `Layer`s][filtering]
-/// for details.
-///
-/// The [`Targets`] type implements a similar form of filtering, but without the
-/// ability to dynamically enable events based on the current span context, and
-/// without filtering on field values. When these features are not required,
-/// [`Targets`] provides a lighter-weight alternative to [`EnvFilter`].
-///
-/// # Directives
-///
-/// A filter consists of one or more comma-separated directives which match on [`Span`]s and [`Event`]s.
-/// Each directive may have a corresponding maximum verbosity [`level`] which
-/// enables (e.g., _selects for_) spans and events that match. Like `log`,
-/// `tracing` considers less exclusive levels (like `trace` or `info`) to be more
-/// verbose than more exclusive levels (like `error` or `warn`).
-///
-/// The directive syntax is similar to that of [`env_logger`]'s. At a high level, the syntax for directives
-/// consists of several parts:
-///
-/// ```text
-/// target[span{field=value}]=level
-/// ```
-///
-/// Each component (`target`, `span`, `field`, `value`, and `level`) will be covered in turn.
-///
-/// - `target` matches the event or span's target. In general, this is the module path and/or crate name.
-/// Examples of targets `h2`, `tokio::net`, or `tide::server`. For more information on targets,
-/// please refer to [`Metadata`]'s documentation.
-/// - `span` matches on the span's name. If a `span` directive is provided alongside a `target`,
-/// the `span` directive will match on spans _within_ the `target`.
-/// - `field` matches on [fields] within spans. Field names can also be supplied without a `value`
-/// and will match on any [`Span`] or [`Event`] that has a field with that name.
-/// For example: `[span{field=\"value\"}]=debug`, `[{field}]=trace`.
-/// - `value` matches on the value of a span's field. If a value is a numeric literal or a bool,
-/// it will match _only_ on that value. Otherwise, this filter matches the
-/// [`std::fmt::Debug`] output from the value.
-/// - `level` sets a maximum verbosity level accepted by this directive.
-///
-/// When a field value directive (`[{<FIELD NAME>=<FIELD_VALUE>}]=...`) matches a
-/// value's [`std::fmt::Debug`] output (i.e., the field value in the directive
-/// is not a `bool`, `i64`, `u64`, or `f64` literal), the matched pattern may be
-/// interpreted as either a regular expression or as the precise expected
-/// output of the field's [`std::fmt::Debug`] implementation. By default, these
-/// filters are interpreted as regular expressions, but this can be disabled
-/// using the [`Builder::with_regex`] builder method to use precise matching
-/// instead.
-///
-/// When field value filters are interpreted as regular expressions, the
-/// [`regex-automata` crate's regular expression syntax][re-syntax] is
-/// supported.
-///
-/// **Note**: When filters are constructed from potentially untrusted inputs,
-/// [disabling regular expression matching](Builder::with_regex) is strongly
-/// recommended.
-///
-/// ## Usage Notes
-///
-/// - The portion of the directive which is included within the square brackets is `tracing`-specific.
-/// - Any portion of the directive can be omitted.
-/// - The sole exception are the `field` and `value` directives. If a `value` is provided,
-/// a `field` must _also_ be provided. However, the converse does not hold, as fields can
-/// be matched without a value.
-/// - If only a level is provided, it will set the maximum level for all `Span`s and `Event`s
-/// that are not enabled by other filters.
-/// - A directive without a level will enable anything that it matches. This is equivalent to `=trace`.
-/// - When a crate has a dash in its name, the default target for events will be the
-/// crate's module path as it appears in Rust. This means every dash will be replaced
-/// with an underscore.
-/// - A dash in a target will only appear when being specified explicitly:
-/// `tracing::info!(target: "target-name", ...);`
-///
-/// ## Example Syntax
-///
-/// - `tokio::net=info` will enable all spans or events that:
-/// - have the `tokio::net` target,
-/// - at the level `info` or above.
-/// - `warn,tokio::net=info` will enable all spans and events that:
-/// - are at the level `warn` or above, *or*
-/// - have the `tokio::net` target at the level `info` or above.
-/// - `my_crate[span_a]=trace` will enable all spans and events that:
-/// - are within the `span_a` span or named `span_a` _if_ `span_a` has the target `my_crate`,
-/// - at the level `trace` or above.
-/// - `[span_b{name=\"bob\"}]` will enable all spans or event that:
-/// - have _any_ target,
-/// - are inside a span named `span_b`,
-/// - which has a field named `name` with value `bob`,
-/// - at _any_ level.
-///
-/// # Examples
-///
-/// Parsing an `EnvFilter` from the [default environment
-/// variable](EnvFilter::from_default_env) (`RUST_LOG`):
-///
-/// ```
-/// use tracing_subscriber::{EnvFilter, fmt, prelude::*};
-///
-/// tracing_subscriber::registry()
-/// .with(fmt::layer())
-/// .with(EnvFilter::from_default_env())
-/// .init();
-/// ```
-///
-/// Parsing an `EnvFilter` [from a user-provided environment
-/// variable](EnvFilter::from_env):
-///
-/// ```
-/// use tracing_subscriber::{EnvFilter, fmt, prelude::*};
-///
-/// tracing_subscriber::registry()
-/// .with(fmt::layer())
-/// .with(EnvFilter::from_env("MYAPP_LOG"))
-/// .init();
-/// ```
-///
-/// Using `EnvFilter` as a [per-layer filter][plf] to filter only a single
-/// [`Layer`]:
-///
-/// ```
-/// use tracing_subscriber::{EnvFilter, fmt, prelude::*};
-///
-/// // Parse an `EnvFilter` configuration from the `RUST_LOG`
-/// // environment variable.
-/// let filter = EnvFilter::from_default_env();
-///
-/// // Apply the filter to this layer *only*.
-/// let filtered_layer = fmt::layer().with_filter(filter);
-///
-/// // Some other layer, whose output we don't want to filter.
-/// let unfiltered_layer = // ...
-/// # fmt::layer();
-///
-/// tracing_subscriber::registry()
-/// .with(filtered_layer)
-/// .with(unfiltered_layer)
-/// .init();
-/// ```
-/// # Constructing `EnvFilter`s
-///
-/// An `EnvFilter` is be constructed by parsing a string containing one or more
-/// directives. The [`EnvFilter::new`] constructor parses an `EnvFilter` from a
-/// string, ignoring any invalid directives, while [`EnvFilter::try_new`]
-/// returns an error if invalid directives are encountered. Similarly, the
-/// [`EnvFilter::from_env`] and [`EnvFilter::try_from_env`] constructors parse
-/// an `EnvFilter` from the value of the provided environment variable, with
-/// lossy and strict validation, respectively.
-///
-/// A [builder](EnvFilter::builder) interface is available to set additional
-/// configuration options prior to parsing an `EnvFilter`. See the [`Builder`
-/// type's documentation](Builder) for details on the options that can be
-/// configured using the builder.
-///
-/// [`Span`]: tracing_core::span
-/// [fields]: tracing_core::Field
-/// [`Event`]: tracing_core::Event
-/// [`level`]: tracing_core::Level
-/// [`Metadata`]: tracing_core::Metadata
-/// [`Targets`]: crate::filter::Targets
-/// [`env_logger`]: https://crates.io/crates/env_logger
-/// [`Filter`]: #impl-Filter<S>
-/// [global]: crate::layer#global-filtering
-/// [plf]: crate::layer#per-layer-filtering
-/// [filtering]: crate::layer#filtering-with-layers
-#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))]
-#[derive(Debug)]
-pub struct EnvFilter {
- statics: directive::Statics,
- dynamics: directive::Dynamics,
- has_dynamics: bool,
- by_id: RwLock<HashMap<span::Id, directive::SpanMatcher>>,
- by_cs: RwLock<HashMap<callsite::Identifier, directive::CallsiteMatcher>>,
- scope: ThreadLocal<RefCell<Vec<LevelFilter>>>,
- regex: bool,
-}
-
-type FieldMap<T> = HashMap<Field, T>;
-
-/// Indicates that an error occurred while parsing a `EnvFilter` from an
-/// environment variable.
-#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))]
-#[derive(Debug)]
-pub struct FromEnvError {
- kind: ErrorKind,
-}
-
-#[derive(Debug)]
-enum ErrorKind {
- Parse(ParseError),
- Env(env::VarError),
-}
-
-impl EnvFilter {
- /// `RUST_LOG` is the default environment variable used by
- /// [`EnvFilter::from_default_env`] and [`EnvFilter::try_from_default_env`].
- ///
- /// [`EnvFilter::from_default_env`]: EnvFilter::from_default_env()
- /// [`EnvFilter::try_from_default_env`]: EnvFilter::try_from_default_env()
- pub const DEFAULT_ENV: &'static str = "RUST_LOG";
-
- // === constructors, etc ===
-
- /// Returns a [builder] that can be used to configure a new [`EnvFilter`]
- /// instance.
- ///
- /// The [`Builder`] type is used to set additional configurations, such as
- /// [whether regular expressions are enabled](Builder::with_regex) or [the
- /// default directive](Builder::with_default_directive) before parsing an
- /// [`EnvFilter`] from a string or environment variable.
- ///
- /// [builder]: https://rust-unofficial.github.io/patterns/patterns/creational/builder.html
- pub fn builder() -> Builder {
- Builder::default()
- }
-
- /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment
- /// variable, ignoring any invalid filter directives.
- ///
- /// If the environment variable is empty or not set, or if it contains only
- /// invalid directives, a default directive enabling the [`ERROR`] level is
- /// added.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// # fn docs() -> EnvFilter {
- /// EnvFilter::builder()
- /// .with_default_directive(LevelFilter::ERROR.into())
- /// .from_env_lossy()
- /// # }
- /// ```
- ///
- /// [`ERROR`]: tracing::Level::ERROR
- pub fn from_default_env() -> Self {
- Self::builder()
- .with_default_directive(LevelFilter::ERROR.into())
- .from_env_lossy()
- }
-
- /// Returns a new `EnvFilter` from the value of the given environment
- /// variable, ignoring any invalid filter directives.
- ///
- /// If the environment variable is empty or not set, or if it contains only
- /// invalid directives, a default directive enabling the [`ERROR`] level is
- /// added.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// # fn docs() -> EnvFilter {
- /// # let env = "";
- /// EnvFilter::builder()
- /// .with_default_directive(LevelFilter::ERROR.into())
- /// .with_env_var(env)
- /// .from_env_lossy()
- /// # }
- /// ```
- ///
- /// [`ERROR`]: tracing::Level::ERROR
- pub fn from_env<A: AsRef<str>>(env: A) -> Self {
- Self::builder()
- .with_default_directive(LevelFilter::ERROR.into())
- .with_env_var(env.as_ref())
- .from_env_lossy()
- }
-
- /// Returns a new `EnvFilter` from the directives in the given string,
- /// ignoring any that are invalid.
- ///
- /// If the string is empty or contains only invalid directives, a default
- /// directive enabling the [`ERROR`] level is added.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// # fn docs() -> EnvFilter {
- /// # let directives = "";
- /// EnvFilter::builder()
- /// .with_default_directive(LevelFilter::ERROR.into())
- /// .parse_lossy(directives)
- /// # }
- /// ```
- ///
- /// [`ERROR`]: tracing::Level::ERROR
- pub fn new<S: AsRef<str>>(directives: S) -> Self {
- Self::builder()
- .with_default_directive(LevelFilter::ERROR.into())
- .parse_lossy(directives)
- }
-
- /// Returns a new `EnvFilter` from the directives in the given string,
- /// or an error if any are invalid.
- ///
- /// If the string is empty, a default directive enabling the [`ERROR`] level
- /// is added.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- ///
- /// # fn docs() -> Result<EnvFilter, tracing_subscriber::filter::ParseError> {
- /// # let directives = "";
- /// EnvFilter::builder()
- /// .with_default_directive(LevelFilter::ERROR.into())
- /// .parse(directives)
- /// # }
- /// ```
- ///
- /// [`ERROR`]: tracing::Level::ERROR
- pub fn try_new<S: AsRef<str>>(dirs: S) -> Result<Self, directive::ParseError> {
- Self::builder().parse(dirs)
- }
-
- /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment
- /// variable, or an error if the environment variable is unset or contains
- /// any invalid filter directives.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::EnvFilter;
- ///
- /// # fn docs() -> Result<EnvFilter, tracing_subscriber::filter::FromEnvError> {
- /// EnvFilter::builder().try_from_env()
- /// # }
- /// ```
- pub fn try_from_default_env() -> Result<Self, FromEnvError> {
- Self::builder().try_from_env()
- }
-
- /// Returns a new `EnvFilter` from the value of the given environment
- /// variable, or an error if the environment variable is unset or contains
- /// any invalid filter directives.
- ///
- /// To set additional configuration options prior to parsing the filter, use
- /// the [`Builder`] type instead.
- ///
- /// This function is equivalent to the following:
- ///
- /// ```rust
- /// use tracing_subscriber::EnvFilter;
- ///
- /// # fn docs() -> Result<EnvFilter, tracing_subscriber::filter::FromEnvError> {
- /// # let env = "";
- /// EnvFilter::builder().with_env_var(env).try_from_env()
- /// # }
- /// ```
- pub fn try_from_env<A: AsRef<str>>(env: A) -> Result<Self, FromEnvError> {
- Self::builder().with_env_var(env.as_ref()).try_from_env()
- }
-
- /// Add a filtering directive to this `EnvFilter`.
- ///
- /// The added directive will be used in addition to any previously set
- /// directives, either added using this method or provided when the filter
- /// is constructed.
- ///
- /// Filters may be created from [`LevelFilter`] or [`Level`], which will
- /// enable all traces at or below a certain verbosity level, or
- /// parsed from a string specifying a directive.
- ///
- /// If a filter directive is inserted that matches exactly the same spans
- /// and events as a previous filter, but sets a different level for those
- /// spans and events, the previous directive is overwritten.
- ///
- /// [`LevelFilter`]: super::LevelFilter
- /// [`Level`]: tracing_core::Level
- ///
- /// # Examples
- ///
- /// From [`LevelFilter`]:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- /// let mut filter = EnvFilter::from_default_env()
- /// .add_directive(LevelFilter::INFO.into());
- /// ```
- ///
- /// Or from [`Level`]:
- ///
- /// ```rust
- /// # use tracing_subscriber::filter::{EnvFilter, LevelFilter};
- /// # use tracing::Level;
- /// let mut filter = EnvFilter::from_default_env()
- /// .add_directive(Level::INFO.into());
- /// ```
- ///
- /// Parsed from a string:
- ///
- /// ```rust
- /// use tracing_subscriber::filter::{EnvFilter, Directive};
- ///
- /// # fn try_mk_filter() -> Result<(), Box<dyn ::std::error::Error>> {
- /// let mut filter = EnvFilter::try_from_default_env()?
- /// .add_directive("my_crate::module=trace".parse()?)
- /// .add_directive("my_crate::my_other_module::something=info".parse()?);
- /// # Ok(())
- /// # }
- /// ```
- /// In the above example, substitute `my_crate`, `module`, etc. with the
- /// name your target crate/module is imported with. This might be
- /// different from the package name in Cargo.toml (`-` is replaced by `_`).
- /// Example, if the package name in your Cargo.toml is `MY-FANCY-LIB`, then
- /// the corresponding Rust identifier would be `MY_FANCY_LIB`:
- pub fn add_directive(mut self, mut directive: Directive) -> Self {
- if !self.regex {
- directive.deregexify();
- }
- if let Some(stat) = directive.to_static() {
- self.statics.add(stat)
- } else {
- self.has_dynamics = true;
- self.dynamics.add(directive);
- }
- self
- }
-
- // === filtering methods ===
-
- /// Returns `true` if this `EnvFilter` would enable the provided `metadata`
- /// in the current context.
- ///
- /// This is equivalent to calling the [`Layer::enabled`] or
- /// [`Filter::enabled`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- pub fn enabled<S>(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool {
- let level = metadata.level();
-
- // is it possible for a dynamic filter directive to enable this event?
- // if not, we can avoid the thread loca'l access + iterating over the
- // spans in the current scope.
- if self.has_dynamics && self.dynamics.max_level >= *level {
- if metadata.is_span() {
- // If the metadata is a span, see if we care about its callsite.
- let enabled_by_cs = self
- .by_cs
- .read()
- .ok()
- .map(|by_cs| by_cs.contains_key(&metadata.callsite()))
- .unwrap_or(false);
- if enabled_by_cs {
- return true;
- }
- }
-
- let enabled_by_scope = {
- let scope = self.scope.get_or_default().borrow();
- for filter in &*scope {
- if filter >= level {
- return true;
- }
- }
- false
- };
- if enabled_by_scope {
- return true;
- }
- }
-
- // is it possible for a static filter directive to enable this event?
- if self.statics.max_level >= *level {
- // Otherwise, fall back to checking if the callsite is
- // statically enabled.
- return self.statics.enabled(metadata);
- }
-
- false
- }
-
- /// Returns an optional hint of the highest [verbosity level][level] that
- /// this `EnvFilter` will enable.
- ///
- /// This is equivalent to calling the [`Layer::max_level_hint`] or
- /// [`Filter::max_level_hint`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- ///
- /// [level]: tracing_core::metadata::Level
- pub fn max_level_hint(&self) -> Option<LevelFilter> {
- if self.dynamics.has_value_filters() {
- // If we perform any filtering on span field *values*, we will
- // enable *all* spans, because their field values are not known
- // until recording.
- return Some(LevelFilter::TRACE);
- }
- std::cmp::max(
- self.statics.max_level.into(),
- self.dynamics.max_level.into(),
- )
- }
-
- /// Informs the filter that a new span was created.
- ///
- /// This is equivalent to calling the [`Layer::on_new_span`] or
- /// [`Filter::on_new_span`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- pub fn on_new_span<S>(&self, attrs: &span::Attributes<'_>, id: &span::Id, _: Context<'_, S>) {
- let by_cs = try_lock!(self.by_cs.read());
- if let Some(cs) = by_cs.get(&attrs.metadata().callsite()) {
- let span = cs.to_span_match(attrs);
- try_lock!(self.by_id.write()).insert(id.clone(), span);
- }
- }
-
- /// Informs the filter that the span with the provided `id` was entered.
- ///
- /// This is equivalent to calling the [`Layer::on_enter`] or
- /// [`Filter::on_enter`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- pub fn on_enter<S>(&self, id: &span::Id, _: Context<'_, S>) {
- // XXX: This is where _we_ could push IDs to the stack instead, and use
- // that to allow changing the filter while a span is already entered.
- // But that might be much less efficient...
- if let Some(span) = try_lock!(self.by_id.read()).get(id) {
- self.scope.get_or_default().borrow_mut().push(span.level());
- }
- }
-
- /// Informs the filter that the span with the provided `id` was exited.
- ///
- /// This is equivalent to calling the [`Layer::on_exit`] or
- /// [`Filter::on_exit`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- pub fn on_exit<S>(&self, id: &span::Id, _: Context<'_, S>) {
- if self.cares_about_span(id) {
- self.scope.get_or_default().borrow_mut().pop();
- }
- }
-
- /// Informs the filter that the span with the provided `id` was closed.
- ///
- /// This is equivalent to calling the [`Layer::on_close`] or
- /// [`Filter::on_close`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope.
- pub fn on_close<S>(&self, id: span::Id, _: Context<'_, S>) {
- // If we don't need to acquire a write lock, avoid doing so.
- if !self.cares_about_span(&id) {
- return;
- }
-
- let mut spans = try_lock!(self.by_id.write());
- spans.remove(&id);
- }
-
- /// Informs the filter that the span with the provided `id` recorded the
- /// provided field `values`.
- ///
- /// This is equivalent to calling the [`Layer::on_record`] or
- /// [`Filter::on_record`] methods on `EnvFilter`'s implementations of those
- /// traits, but it does not require the trait to be in scope
- pub fn on_record<S>(&self, id: &span::Id, values: &span::Record<'_>, _: Context<'_, S>) {
- if let Some(span) = try_lock!(self.by_id.read()).get(id) {
- span.record_update(values);
- }
- }
-
- fn cares_about_span(&self, span: &span::Id) -> bool {
- let spans = try_lock!(self.by_id.read(), else return false);
- spans.contains_key(span)
- }
-
- fn base_interest(&self) -> Interest {
- if self.has_dynamics {
- Interest::sometimes()
- } else {
- Interest::never()
- }
- }
-
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- if self.has_dynamics && metadata.is_span() {
- // If this metadata describes a span, first, check if there is a
- // dynamic filter that should be constructed for it. If so, it
- // should always be enabled, since it influences filtering.
- if let Some(matcher) = self.dynamics.matcher(metadata) {
- let mut by_cs = try_lock!(self.by_cs.write(), else return self.base_interest());
- by_cs.insert(metadata.callsite(), matcher);
- return Interest::always();
- }
- }
-
- // Otherwise, check if any of our static filters enable this metadata.
- if self.statics.enabled(metadata) {
- Interest::always()
- } else {
- self.base_interest()
- }
- }
-}
-
-impl<S: Subscriber> Layer<S> for EnvFilter {
- #[inline]
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- EnvFilter::register_callsite(self, metadata)
- }
-
- #[inline]
- fn max_level_hint(&self) -> Option<LevelFilter> {
- EnvFilter::max_level_hint(self)
- }
-
- #[inline]
- fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool {
- self.enabled(metadata, ctx)
- }
-
- #[inline]
- fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
- self.on_new_span(attrs, id, ctx)
- }
-
- #[inline]
- fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
- self.on_record(id, values, ctx);
- }
-
- #[inline]
- fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
- self.on_enter(id, ctx);
- }
-
- #[inline]
- fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
- self.on_exit(id, ctx);
- }
-
- #[inline]
- fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
- self.on_close(id, ctx);
- }
-}
-
-feature! {
- #![all(feature = "registry", feature = "std")]
- use crate::layer::Filter;
-
- impl<S> Filter<S> for EnvFilter {
- #[inline]
- fn enabled(&self, meta: &Metadata<'_>, ctx: &Context<'_, S>) -> bool {
- self.enabled(meta, ctx.clone())
- }
-
- #[inline]
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- self.register_callsite(meta)
- }
-
- #[inline]
- fn max_level_hint(&self) -> Option<LevelFilter> {
- EnvFilter::max_level_hint(self)
- }
-
- #[inline]
- fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
- self.on_new_span(attrs, id, ctx)
- }
-
- #[inline]
- fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
- self.on_record(id, values, ctx);
- }
-
- #[inline]
- fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
- self.on_enter(id, ctx);
- }
-
- #[inline]
- fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
- self.on_exit(id, ctx);
- }
-
- #[inline]
- fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
- self.on_close(id, ctx);
- }
- }
-}
-
-impl FromStr for EnvFilter {
- type Err = directive::ParseError;
-
- fn from_str(spec: &str) -> Result<Self, Self::Err> {
- Self::try_new(spec)
- }
-}
-
-impl<S> From<S> for EnvFilter
-where
- S: AsRef<str>,
-{
- fn from(s: S) -> Self {
- Self::new(s)
- }
-}
-
-impl Default for EnvFilter {
- fn default() -> Self {
- Builder::default().from_directives(std::iter::empty())
- }
-}
-
-impl fmt::Display for EnvFilter {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut statics = self.statics.iter();
- let wrote_statics = if let Some(next) = statics.next() {
- fmt::Display::fmt(next, f)?;
- for directive in statics {
- write!(f, ",{}", directive)?;
- }
- true
- } else {
- false
- };
-
- let mut dynamics = self.dynamics.iter();
- if let Some(next) = dynamics.next() {
- if wrote_statics {
- f.write_str(",")?;
- }
- fmt::Display::fmt(next, f)?;
- for directive in dynamics {
- write!(f, ",{}", directive)?;
- }
- }
- Ok(())
- }
-}
-
-// ===== impl FromEnvError =====
-
-impl From<directive::ParseError> for FromEnvError {
- fn from(p: directive::ParseError) -> Self {
- Self {
- kind: ErrorKind::Parse(p),
- }
- }
-}
-
-impl From<env::VarError> for FromEnvError {
- fn from(v: env::VarError) -> Self {
- Self {
- kind: ErrorKind::Env(v),
- }
- }
-}
-
-impl fmt::Display for FromEnvError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.kind {
- ErrorKind::Parse(ref p) => p.fmt(f),
- ErrorKind::Env(ref e) => e.fmt(f),
- }
- }
-}
-
-impl Error for FromEnvError {
- fn source(&self) -> Option<&(dyn Error + 'static)> {
- match self.kind {
- ErrorKind::Parse(ref p) => Some(p),
- ErrorKind::Env(ref e) => Some(e),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use tracing_core::field::FieldSet;
- use tracing_core::*;
-
- struct NoSubscriber;
- impl Subscriber for NoSubscriber {
- #[inline]
- fn register_callsite(&self, _: &'static Metadata<'static>) -> subscriber::Interest {
- subscriber::Interest::always()
- }
- fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
- span::Id::from_u64(0xDEAD)
- }
- fn event(&self, _event: &Event<'_>) {}
- fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
- fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
-
- #[inline]
- fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
- true
- }
- fn enter(&self, _span: &span::Id) {}
- fn exit(&self, _span: &span::Id) {}
- }
-
- struct Cs;
- impl Callsite for Cs {
- fn set_interest(&self, _interest: Interest) {}
- fn metadata(&self) -> &Metadata<'_> {
- unimplemented!()
- }
- }
-
- #[test]
- fn callsite_enabled_no_span_directive() {
- let filter = EnvFilter::new("app=debug").with_subscriber(NoSubscriber);
- static META: &Metadata<'static> = &Metadata::new(
- "mySpan",
- "app",
- Level::TRACE,
- None,
- None,
- None,
- FieldSet::new(&[], identify_callsite!(&Cs)),
- Kind::SPAN,
- );
-
- let interest = filter.register_callsite(META);
- assert!(interest.is_never());
- }
-
- #[test]
- fn callsite_off() {
- let filter = EnvFilter::new("app=off").with_subscriber(NoSubscriber);
- static META: &Metadata<'static> = &Metadata::new(
- "mySpan",
- "app",
- Level::ERROR,
- None,
- None,
- None,
- FieldSet::new(&[], identify_callsite!(&Cs)),
- Kind::SPAN,
- );
-
- let interest = filter.register_callsite(META);
- assert!(interest.is_never());
- }
-
- #[test]
- fn callsite_enabled_includes_span_directive() {
- let filter = EnvFilter::new("app[mySpan]=debug").with_subscriber(NoSubscriber);
- static META: &Metadata<'static> = &Metadata::new(
- "mySpan",
- "app",
- Level::TRACE,
- None,
- None,
- None,
- FieldSet::new(&[], identify_callsite!(&Cs)),
- Kind::SPAN,
- );
-
- let interest = filter.register_callsite(META);
- assert!(interest.is_always());
- }
-
- #[test]
- fn callsite_enabled_includes_span_directive_field() {
- let filter =
- EnvFilter::new("app[mySpan{field=\"value\"}]=debug").with_subscriber(NoSubscriber);
- static META: &Metadata<'static> = &Metadata::new(
- "mySpan",
- "app",
- Level::TRACE,
- None,
- None,
- None,
- FieldSet::new(&["field"], identify_callsite!(&Cs)),
- Kind::SPAN,
- );
-
- let interest = filter.register_callsite(META);
- assert!(interest.is_always());
- }
-
- #[test]
- fn callsite_enabled_includes_span_directive_multiple_fields() {
- let filter = EnvFilter::new("app[mySpan{field=\"value\",field2=2}]=debug")
- .with_subscriber(NoSubscriber);
- static META: &Metadata<'static> = &Metadata::new(
- "mySpan",
- "app",
- Level::TRACE,
- None,
- None,
- None,
- FieldSet::new(&["field"], identify_callsite!(&Cs)),
- Kind::SPAN,
- );
-
- let interest = filter.register_callsite(META);
- assert!(interest.is_never());
- }
-
- #[test]
- fn roundtrip() {
- let f1: EnvFilter =
- "[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug"
- .parse()
- .unwrap();
- let f2: EnvFilter = format!("{}", f1).parse().unwrap();
- assert_eq!(f1.statics, f2.statics);
- assert_eq!(f1.dynamics, f2.dynamics);
- }
-
- #[test]
- fn size_of_filters() {
- fn print_sz(s: &str) {
- let filter = s.parse::<EnvFilter>().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",
- );
-
- print_sz("[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug");
-
- print_sz(
- "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\
- crate2=debug,crate3=trace,crate3::mod2::mod1=off,[span1{foo=1}]=error,\
- [span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug",
- );
- }
-
- #[test]
- fn parse_empty_string() {
- // There is no corresponding test for [`Builder::parse_lossy`] as failed
- // parsing does not produce any observable side effects. If this test fails
- // check that [`Builder::parse_lossy`] is behaving correctly as well.
- assert!(EnvFilter::builder().parse("").is_ok());
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/filter_fn.rs b/vendor/tracing-subscriber/src/filter/filter_fn.rs
deleted file mode 100644
index 332bf860a..000000000
--- a/vendor/tracing-subscriber/src/filter/filter_fn.rs
+++ /dev/null
@@ -1,749 +0,0 @@
-use crate::{
- filter::LevelFilter,
- layer::{Context, Layer},
-};
-use core::{any::type_name, fmt, marker::PhantomData};
-use tracing_core::{Interest, Metadata, Subscriber};
-
-/// A filter implemented by a closure or function pointer that
-/// determines whether a given span or event is enabled, based on its
-/// [`Metadata`].
-///
-/// 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.
-///
-/// [`Metadata`]: tracing_core::Metadata
-/// [`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
-#[derive(Clone)]
-pub struct FilterFn<F = fn(&Metadata<'_>) -> bool> {
- enabled: F,
- max_level_hint: Option<LevelFilter>,
-}
-
-/// A filter implemented by a closure or function pointer that
-/// determines whether a given span or event is enabled _dynamically_,
-/// potentially based on the current [span context].
-///
-/// 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.
-///
-/// [span context]: crate::layer::Context
-/// [`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
-pub struct DynFilterFn<
- S,
- // TODO(eliza): should these just be boxed functions?
- F = fn(&Metadata<'_>, &Context<'_, S>) -> bool,
- R = fn(&'static Metadata<'static>) -> Interest,
-> {
- enabled: F,
- register_callsite: Option<R>,
- max_level_hint: Option<LevelFilter>,
- _s: PhantomData<fn(S)>,
-}
-
-// === impl FilterFn ===
-
-/// Constructs a [`FilterFn`], from a function or closure that returns `true` if
-/// a span or event should be enabled, based on its [`Metadata`].
-///
-/// The returned [`FilterFn`] 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.
-///
-/// This is equivalent to calling [`FilterFn::new`].
-///
-/// [`Metadata`]: tracing_core::Metadata
-/// [`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
-///
-/// # Examples
-///
-/// ```
-/// use tracing_subscriber::{
-/// layer::{Layer, SubscriberExt},
-/// filter,
-/// util::SubscriberInitExt,
-/// };
-///
-/// let my_filter = filter::filter_fn(|metadata| {
-/// // Only enable spans or events with the target "interesting_things"
-/// metadata.target() == "interesting_things"
-/// });
-///
-/// let my_layer = tracing_subscriber::fmt::layer();
-///
-/// tracing_subscriber::registry()
-/// .with(my_layer.with_filter(my_filter))
-/// .init();
-///
-/// // This event will not be enabled.
-/// tracing::warn!("something important but uninteresting happened!");
-///
-/// // This event will be enabled.
-/// tracing::debug!(target: "interesting_things", "an interesting minor detail...");
-/// ```
-pub fn filter_fn<F>(f: F) -> FilterFn<F>
-where
- F: Fn(&Metadata<'_>) -> bool,
-{
- FilterFn::new(f)
-}
-
-/// Constructs a [`DynFilterFn`] from a function or closure that returns `true`
-/// if a span or event should be enabled within a particular [span context][`Context`].
-///
-/// This is equivalent to calling [`DynFilterFn::new`].
-///
-/// Unlike [`filter_fn`], this function takes a closure or function pointer
-/// taking the [`Metadata`] for a span or event *and* the current [`Context`].
-/// This means that a [`DynFilterFn`] can choose whether to enable spans or
-/// events based on information about the _current_ span (or its parents).
-///
-/// If this is *not* necessary, use [`filter_fn`] instead.
-///
-/// The returned [`DynFilterFn`] 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.
-///
-/// # Examples
-///
-/// ```
-/// use tracing_subscriber::{
-/// layer::{Layer, SubscriberExt},
-/// filter,
-/// util::SubscriberInitExt,
-/// };
-///
-/// // Only enable spans or events within a span named "interesting_span".
-/// let my_filter = filter::dynamic_filter_fn(|metadata, cx| {
-/// // If this *is* "interesting_span", make sure to enable it.
-/// if metadata.is_span() && metadata.name() == "interesting_span" {
-/// return true;
-/// }
-///
-/// // Otherwise, are we in an interesting span?
-/// if let Some(current_span) = cx.lookup_current() {
-/// return current_span.name() == "interesting_span";
-/// }
-///
-/// false
-/// });
-///
-/// let my_layer = tracing_subscriber::fmt::layer();
-///
-/// tracing_subscriber::registry()
-/// .with(my_layer.with_filter(my_filter))
-/// .init();
-///
-/// // This event will not be enabled.
-/// tracing::info!("something happened");
-///
-/// tracing::info_span!("interesting_span").in_scope(|| {
-/// // This event will be enabled.
-/// tracing::debug!("something else happened");
-/// });
-/// ```
-///
-/// [`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
-/// [`Context`]: crate::layer::Context
-/// [`Metadata`]: tracing_core::Metadata
-pub fn dynamic_filter_fn<S, F>(f: F) -> DynFilterFn<S, F>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
-{
- DynFilterFn::new(f)
-}
-
-impl<F> FilterFn<F>
-where
- F: Fn(&Metadata<'_>) -> bool,
-{
- /// Constructs a [`FilterFn`] from a function or closure that returns `true`
- /// if a span or event should be enabled, based on its [`Metadata`].
- ///
- /// If determining whether a span or event should be enabled also requires
- /// information about the current span context, use [`DynFilterFn`] instead.
- ///
- /// See the [documentation on per-layer filtering][plf] for details on using
- /// [`Filter`]s.
- ///
- /// [`Filter`]: crate::layer::Filter
- /// [plf]: crate::layer#per-layer-filtering
- /// [`Metadata`]: tracing_core::Metadata
- ///
- /// # Examples
- ///
- /// ```
- /// use tracing_subscriber::{
- /// layer::{Layer, SubscriberExt},
- /// filter::FilterFn,
- /// util::SubscriberInitExt,
- /// };
- ///
- /// let my_filter = FilterFn::new(|metadata| {
- /// // Only enable spans or events with the target "interesting_things"
- /// metadata.target() == "interesting_things"
- /// });
- ///
- /// let my_layer = tracing_subscriber::fmt::layer();
- ///
- /// tracing_subscriber::registry()
- /// .with(my_layer.with_filter(my_filter))
- /// .init();
- ///
- /// // This event will not be enabled.
- /// tracing::warn!("something important but uninteresting happened!");
- ///
- /// // This event will be enabled.
- /// tracing::debug!(target: "interesting_things", "an interesting minor detail...");
- /// ```
- pub fn new(enabled: F) -> Self {
- Self {
- enabled,
- max_level_hint: None,
- }
- }
-
- /// Sets the highest verbosity [`Level`] the filter function will enable.
- ///
- /// The value passed to this method will be returned by this `FilterFn`'s
- /// [`Filter::max_level_hint`] method.
- ///
- /// If the provided function will not enable all levels, it is recommended
- /// to call this method to configure it with the most verbose level it will
- /// enable.
- ///
- /// # Examples
- ///
- /// ```
- /// use tracing_subscriber::{
- /// layer::{Layer, SubscriberExt},
- /// filter::{filter_fn, LevelFilter},
- /// util::SubscriberInitExt,
- /// };
- /// use tracing_core::Level;
- ///
- /// let my_filter = filter_fn(|metadata| {
- /// // Only enable spans or events with targets starting with `my_crate`
- /// // and levels at or below `INFO`.
- /// metadata.level() <= &Level::INFO && metadata.target().starts_with("my_crate")
- /// })
- /// // Since the filter closure will only enable the `INFO` level and
- /// // below, set the max level hint
- /// .with_max_level_hint(LevelFilter::INFO);
- ///
- /// let my_layer = tracing_subscriber::fmt::layer();
- ///
- /// tracing_subscriber::registry()
- /// .with(my_layer.with_filter(my_filter))
- /// .init();
- /// ```
- ///
- /// [`Level`]: tracing_core::Level
- /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint
- pub fn with_max_level_hint(self, max_level_hint: impl Into<LevelFilter>) -> Self {
- Self {
- max_level_hint: Some(max_level_hint.into()),
- ..self
- }
- }
-
- #[inline]
- pub(in crate::filter) fn is_enabled(&self, metadata: &Metadata<'_>) -> bool {
- let enabled = (self.enabled)(metadata);
- debug_assert!(
- !enabled || self.is_below_max_level(metadata),
- "FilterFn<{}> claimed it would only enable {:?} and below, \
- but it enabled metadata with the {:?} level\nmetadata={:#?}",
- type_name::<F>(),
- self.max_level_hint.unwrap(),
- metadata.level(),
- metadata,
- );
-
- enabled
- }
-
- #[inline]
- pub(in crate::filter) fn is_callsite_enabled(
- &self,
- metadata: &'static Metadata<'static>,
- ) -> Interest {
- // Because `self.enabled` takes a `Metadata` only (and no `Context`
- // parameter), we can reasonably assume its results are cachable, and
- // just return `Interest::always`/`Interest::never`.
- if (self.enabled)(metadata) {
- debug_assert!(
- self.is_below_max_level(metadata),
- "FilterFn<{}> claimed it was only interested in {:?} and below, \
- but it enabled metadata with the {:?} level\nmetadata={:#?}",
- type_name::<F>(),
- self.max_level_hint.unwrap(),
- metadata.level(),
- metadata,
- );
- return Interest::always();
- }
-
- Interest::never()
- }
-
- fn is_below_max_level(&self, metadata: &Metadata<'_>) -> bool {
- self.max_level_hint
- .as_ref()
- .map(|hint| metadata.level() <= hint)
- .unwrap_or(true)
- }
-}
-
-impl<S, F> Layer<S> for FilterFn<F>
-where
- F: Fn(&Metadata<'_>) -> bool + 'static,
- S: Subscriber,
-{
- fn enabled(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool {
- self.is_enabled(metadata)
- }
-
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- self.is_callsite_enabled(metadata)
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.max_level_hint
- }
-}
-
-impl<F> From<F> for FilterFn<F>
-where
- F: Fn(&Metadata<'_>) -> bool,
-{
- fn from(enabled: F) -> Self {
- Self::new(enabled)
- }
-}
-
-impl<F> fmt::Debug for FilterFn<F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FilterFn")
- .field("enabled", &format_args!("{}", type_name::<F>()))
- .field("max_level_hint", &self.max_level_hint)
- .finish()
- }
-}
-
-// === impl DynFilterFn ==
-
-impl<S, F> DynFilterFn<S, F>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
-{
- /// Constructs a [`Filter`] from a function or closure that returns `true`
- /// if a span or event should be enabled in the current [span
- /// context][`Context`].
- ///
- /// Unlike [`FilterFn`], a `DynFilterFn` is constructed from a closure or
- /// function pointer that takes both the [`Metadata`] for a span or event
- /// *and* the current [`Context`]. This means that a [`DynFilterFn`] can
- /// choose whether to enable spans or events based on information about the
- /// _current_ span (or its parents).
- ///
- /// If this is *not* necessary, use [`FilterFn`] instead.
- ///
- /// See the [documentation on per-layer filtering][plf] for details on using
- /// [`Filter`]s.
- ///
- /// [`Filter`]: crate::layer::Filter
- /// [plf]: crate::layer#per-layer-filtering
- /// [`Context`]: crate::layer::Context
- /// [`Metadata`]: tracing_core::Metadata
- ///
- /// # Examples
- ///
- /// ```
- /// use tracing_subscriber::{
- /// layer::{Layer, SubscriberExt},
- /// filter::DynFilterFn,
- /// util::SubscriberInitExt,
- /// };
- ///
- /// // Only enable spans or events within a span named "interesting_span".
- /// let my_filter = DynFilterFn::new(|metadata, cx| {
- /// // If this *is* "interesting_span", make sure to enable it.
- /// if metadata.is_span() && metadata.name() == "interesting_span" {
- /// return true;
- /// }
- ///
- /// // Otherwise, are we in an interesting span?
- /// if let Some(current_span) = cx.lookup_current() {
- /// return current_span.name() == "interesting_span";
- /// }
- ///
- /// false
- /// });
- ///
- /// let my_layer = tracing_subscriber::fmt::layer();
- ///
- /// tracing_subscriber::registry()
- /// .with(my_layer.with_filter(my_filter))
- /// .init();
- ///
- /// // This event will not be enabled.
- /// tracing::info!("something happened");
- ///
- /// tracing::info_span!("interesting_span").in_scope(|| {
- /// // This event will be enabled.
- /// tracing::debug!("something else happened");
- /// });
- /// ```
- pub fn new(enabled: F) -> Self {
- Self {
- enabled,
- register_callsite: None,
- max_level_hint: None,
- _s: PhantomData,
- }
- }
-}
-
-impl<S, F, R> DynFilterFn<S, F, R>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
-{
- /// Sets the highest verbosity [`Level`] the filter function will enable.
- ///
- /// The value passed to this method will be returned by this `DynFilterFn`'s
- /// [`Filter::max_level_hint`] method.
- ///
- /// If the provided function will not enable all levels, it is recommended
- /// to call this method to configure it with the most verbose level it will
- /// enable.
- ///
- /// # Examples
- ///
- /// ```
- /// use tracing_subscriber::{
- /// layer::{Layer, SubscriberExt},
- /// filter::{DynFilterFn, LevelFilter},
- /// util::SubscriberInitExt,
- /// };
- /// use tracing_core::Level;
- ///
- /// // Only enable spans or events with levels at or below `INFO`, if
- /// // we are inside a span called "interesting_span".
- /// let my_filter = DynFilterFn::new(|metadata, cx| {
- /// // If the level is greater than INFO, disable it.
- /// if metadata.level() > &Level::INFO {
- /// return false;
- /// }
- ///
- /// // If any span in the current scope is named "interesting_span",
- /// // enable this span or event.
- /// for span in cx.lookup_current().iter().flat_map(|span| span.scope()) {
- /// if span.name() == "interesting_span" {
- /// return true;
- /// }
- /// }
- ///
- /// // Otherwise, disable it.
- /// false
- /// })
- /// // Since the filter closure will only enable the `INFO` level and
- /// // below, set the max level hint
- /// .with_max_level_hint(LevelFilter::INFO);
- ///
- /// let my_layer = tracing_subscriber::fmt::layer();
- ///
- /// tracing_subscriber::registry()
- /// .with(my_layer.with_filter(my_filter))
- /// .init();
- /// ```
- ///
- /// [`Level`]: tracing_core::Level
- /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint
- pub fn with_max_level_hint(self, max_level_hint: impl Into<LevelFilter>) -> Self {
- Self {
- max_level_hint: Some(max_level_hint.into()),
- ..self
- }
- }
-
- /// Adds a function for filtering callsites to this filter.
- ///
- /// When this filter's [`Filter::callsite_enabled`][cse] method is called,
- /// the provided function will be used rather than the default.
- ///
- /// By default, `DynFilterFn` assumes that, because the filter _may_ depend
- /// dynamically on the current [span context], its result should never be
- /// cached. However, some filtering strategies may require dynamic information
- /// from the current span context in *some* cases, but are able to make
- /// static filtering decisions from [`Metadata`] alone in others.
- ///
- /// For example, consider the filter given in the example for
- /// [`DynFilterFn::new`]. That filter enables all spans named
- /// "interesting_span", and any events and spans that occur inside of an
- /// interesting span. Since the span's name is part of its static
- /// [`Metadata`], the "interesting_span" can be enabled in
- /// [`callsite_enabled`][cse]:
- ///
- /// ```
- /// use tracing_subscriber::{
- /// layer::{Layer, SubscriberExt},
- /// filter::DynFilterFn,
- /// util::SubscriberInitExt,
- /// };
- /// use tracing_core::subscriber::Interest;
- ///
- /// // Only enable spans or events within a span named "interesting_span".
- /// let my_filter = DynFilterFn::new(|metadata, cx| {
- /// // If this *is* "interesting_span", make sure to enable it.
- /// if metadata.is_span() && metadata.name() == "interesting_span" {
- /// return true;
- /// }
- ///
- /// // Otherwise, are we in an interesting span?
- /// if let Some(current_span) = cx.lookup_current() {
- /// return current_span.name() == "interesting_span";
- /// }
- ///
- /// false
- /// }).with_callsite_filter(|metadata| {
- /// // If this is an "interesting_span", we know we will always
- /// // enable it.
- /// if metadata.is_span() && metadata.name() == "interesting_span" {
- /// return Interest::always();
- /// }
- ///
- /// // Otherwise, it depends on whether or not we're in an interesting
- /// // span. You'll have to ask us again for each span/event!
- /// Interest::sometimes()
- /// });
- ///
- /// let my_layer = tracing_subscriber::fmt::layer();
- ///
- /// tracing_subscriber::registry()
- /// .with(my_layer.with_filter(my_filter))
- /// .init();
- /// ```
- ///
- /// [cse]: crate::layer::Filter::callsite_enabled
- /// [`enabled`]: crate::layer::Filter::enabled
- /// [`Metadata`]: tracing_core::Metadata
- /// [span context]: crate::layer::Context
- pub fn with_callsite_filter<R2>(self, callsite_enabled: R2) -> DynFilterFn<S, F, R2>
- where
- R2: Fn(&'static Metadata<'static>) -> Interest,
- {
- let register_callsite = Some(callsite_enabled);
- let DynFilterFn {
- enabled,
- max_level_hint,
- _s,
- ..
- } = self;
- DynFilterFn {
- enabled,
- register_callsite,
- max_level_hint,
- _s,
- }
- }
-
- fn default_callsite_enabled(&self, metadata: &Metadata<'_>) -> Interest {
- // If it's below the configured max level, assume that `enabled` will
- // never enable it...
- if !is_below_max_level(&self.max_level_hint, metadata) {
- debug_assert!(
- !(self.enabled)(metadata, &Context::none()),
- "DynFilterFn<{}> claimed it would only enable {:?} and below, \
- but it enabled metadata with the {:?} level\nmetadata={:#?}",
- type_name::<F>(),
- self.max_level_hint.unwrap(),
- metadata.level(),
- metadata,
- );
- return Interest::never();
- }
-
- // Otherwise, since this `enabled` function is dynamic and depends on
- // the current context, we don't know whether this span or event will be
- // enabled or not. Ask again every time it's recorded!
- Interest::sometimes()
- }
-}
-
-impl<S, F, R> DynFilterFn<S, F, R>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
- R: Fn(&'static Metadata<'static>) -> Interest,
-{
- #[inline]
- fn is_enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- let enabled = (self.enabled)(metadata, cx);
- debug_assert!(
- !enabled || is_below_max_level(&self.max_level_hint, metadata),
- "DynFilterFn<{}> claimed it would only enable {:?} and below, \
- but it enabled metadata with the {:?} level\nmetadata={:#?}",
- type_name::<F>(),
- self.max_level_hint.unwrap(),
- metadata.level(),
- metadata,
- );
-
- enabled
- }
-
- #[inline]
- fn is_callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest {
- let interest = self
- .register_callsite
- .as_ref()
- .map(|callsite_enabled| callsite_enabled(metadata))
- .unwrap_or_else(|| self.default_callsite_enabled(metadata));
- debug_assert!(
- interest.is_never() || is_below_max_level(&self.max_level_hint, metadata),
- "DynFilterFn<{}, {}> claimed it was only interested in {:?} and below, \
- but it enabled metadata with the {:?} level\nmetadata={:#?}",
- type_name::<F>(),
- type_name::<R>(),
- self.max_level_hint.unwrap(),
- metadata.level(),
- metadata,
- );
-
- interest
- }
-}
-
-impl<S, F, R> Layer<S> for DynFilterFn<S, F, R>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool + 'static,
- R: Fn(&'static Metadata<'static>) -> Interest + 'static,
- S: Subscriber,
-{
- fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool {
- self.is_enabled(metadata, &cx)
- }
-
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- self.is_callsite_enabled(metadata)
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.max_level_hint
- }
-}
-
-impl<S, F, R> fmt::Debug for DynFilterFn<S, F, R> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut s = f.debug_struct("DynFilterFn");
- s.field("enabled", &format_args!("{}", type_name::<F>()));
- if self.register_callsite.is_some() {
- s.field(
- "register_callsite",
- &format_args!("Some({})", type_name::<R>()),
- );
- } else {
- s.field("register_callsite", &format_args!("None"));
- }
-
- s.field("max_level_hint", &self.max_level_hint).finish()
- }
-}
-
-impl<S, F, R> Clone for DynFilterFn<S, F, R>
-where
- F: Clone,
- R: Clone,
-{
- fn clone(&self) -> Self {
- Self {
- enabled: self.enabled.clone(),
- register_callsite: self.register_callsite.clone(),
- max_level_hint: self.max_level_hint,
- _s: PhantomData,
- }
- }
-}
-
-impl<F, S> From<F> for DynFilterFn<S, F>
-where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
-{
- fn from(f: F) -> Self {
- Self::new(f)
- }
-}
-
-// === PLF impls ===
-
-feature! {
- #![all(feature = "registry", feature = "std")]
- use crate::layer::Filter;
-
- impl<S, F> Filter<S> for FilterFn<F>
- where
- F: Fn(&Metadata<'_>) -> bool,
- {
- fn enabled(&self, metadata: &Metadata<'_>, _: &Context<'_, S>) -> bool {
- self.is_enabled(metadata)
- }
-
- fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest {
- self.is_callsite_enabled(metadata)
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.max_level_hint
- }
- }
-
- impl<S, F, R> Filter<S> for DynFilterFn<S, F, R>
- where
- F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool,
- R: Fn(&'static Metadata<'static>) -> Interest,
- {
- fn enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- self.is_enabled(metadata, cx)
- }
-
- fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest {
- self.is_callsite_enabled(metadata)
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.max_level_hint
- }
- }
-}
-
-fn is_below_max_level(hint: &Option<LevelFilter>, metadata: &Metadata<'_>) -> bool {
- hint.as_ref()
- .map(|hint| metadata.level() <= hint)
- .unwrap_or(true)
-}
diff --git a/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs b/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs
deleted file mode 100644
index e79de2087..000000000
--- a/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs
+++ /dev/null
@@ -1,469 +0,0 @@
-//! Filter combinators
-use crate::layer::{Context, Filter};
-use std::{cmp, fmt, marker::PhantomData};
-use tracing_core::{
- span::{Attributes, Id, Record},
- subscriber::Interest,
- LevelFilter, Metadata,
-};
-
-/// Combines two [`Filter`]s so that spans and events are enabled if and only if
-/// *both* filters return `true`.
-///
-/// This type is typically returned by the [`FilterExt::and`] method. See that
-/// method's documentation for details.
-///
-/// [`Filter`]: crate::layer::Filter
-/// [`FilterExt::and`]: crate::filter::FilterExt::and
-pub struct And<A, B, S> {
- a: A,
- b: B,
- _s: PhantomData<fn(S)>,
-}
-
-/// Combines two [`Filter`]s so that spans and events are enabled if *either* filter
-/// returns `true`.
-///
-/// This type is typically returned by the [`FilterExt::or`] method. See that
-/// method's documentation for details.
-///
-/// [`Filter`]: crate::layer::Filter
-/// [`FilterExt::or`]: crate::filter::FilterExt::or
-pub struct Or<A, B, S> {
- a: A,
- b: B,
- _s: PhantomData<fn(S)>,
-}
-
-/// Inverts the result of a [`Filter`].
-///
-/// If the wrapped filter would enable a span or event, it will be disabled. If
-/// it would disable a span or event, that span or event will be enabled.
-///
-/// This type is typically returned by the [`FilterExt::or`] method. See that
-/// method's documentation for details.
-///
-/// [`Filter`]: crate::layer::Filter
-/// [`FilterExt::or`]: crate::filter::FilterExt::or
-pub struct Not<A, S> {
- a: A,
- _s: PhantomData<fn(S)>,
-}
-
-// === impl And ===
-
-impl<A, B, S> And<A, B, S>
-where
- A: Filter<S>,
- B: Filter<S>,
-{
- /// Combines two [`Filter`]s so that spans and events are enabled if and only if
- /// *both* filters return `true`.
- ///
- /// # Examples
- ///
- /// Enabling spans or events if they have both a particular target *and* are
- /// above a certain level:
- ///
- /// ```ignore
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, combinator::And},
- /// prelude::*,
- /// };
- ///
- /// // Enables spans and events with targets starting with `interesting_target`:
- /// let target_filter = filter_fn(|meta| {
- /// meta.target().starts_with("interesting_target")
- /// });
- ///
- /// // Enables spans and events with levels `INFO` and below:
- /// let level_filter = LevelFilter::INFO;
- ///
- /// // Combine the two filters together so that a span or event is only enabled
- /// // if *both* filters would enable it:
- /// let filter = And::new(level_filter, target_filter);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- ///
- /// // This event will *not* be enabled:
- /// tracing::info!("an event with an uninteresting target");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!(target: "interesting_target", "a very interesting event");
- ///
- /// // This event will *not* be enabled:
- /// tracing::debug!(target: "interesting_target", "interesting debug event...");
- /// ```
- ///
- /// [`Filter`]: crate::layer::Filter
- pub(crate) fn new(a: A, b: B) -> Self {
- Self {
- a,
- b,
- _s: PhantomData,
- }
- }
-}
-
-impl<A, B, S> Filter<S> for And<A, B, S>
-where
- A: Filter<S>,
- B: Filter<S>,
-{
- #[inline]
- fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- self.a.enabled(meta, cx) && self.b.enabled(meta, cx)
- }
-
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- let a = self.a.callsite_enabled(meta);
- if a.is_never() {
- return a;
- }
-
- let b = self.b.callsite_enabled(meta);
-
- if !b.is_always() {
- return b;
- }
-
- a
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- // If either hint is `None`, return `None`. Otherwise, return the most restrictive.
- cmp::min(self.a.max_level_hint(), self.b.max_level_hint())
- }
-
- #[inline]
- fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
- self.a.on_new_span(attrs, id, ctx.clone());
- self.b.on_new_span(attrs, id, ctx)
- }
-
- #[inline]
- fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) {
- self.a.on_record(id, values, ctx.clone());
- self.b.on_record(id, values, ctx);
- }
-
- #[inline]
- fn on_enter(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_enter(id, ctx.clone());
- self.b.on_enter(id, ctx);
- }
-
- #[inline]
- fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_exit(id, ctx.clone());
- self.b.on_exit(id, ctx);
- }
-
- #[inline]
- fn on_close(&self, id: Id, ctx: Context<'_, S>) {
- self.a.on_close(id.clone(), ctx.clone());
- self.b.on_close(id, ctx);
- }
-}
-
-impl<A, B, S> Clone for And<A, B, S>
-where
- A: Clone,
- B: Clone,
-{
- fn clone(&self) -> Self {
- Self {
- a: self.a.clone(),
- b: self.b.clone(),
- _s: PhantomData,
- }
- }
-}
-
-impl<A, B, S> fmt::Debug for And<A, B, S>
-where
- A: fmt::Debug,
- B: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("And")
- .field("a", &self.a)
- .field("b", &self.b)
- .finish()
- }
-}
-
-// === impl Or ===
-
-impl<A, B, S> Or<A, B, S>
-where
- A: Filter<S>,
- B: Filter<S>,
-{
- /// Combines two [`Filter`]s so that spans and events are enabled if *either* filter
- /// returns `true`.
- ///
- /// # Examples
- ///
- /// Enabling spans and events at the `INFO` level and above, and all spans
- /// and events with a particular target:
- ///
- /// ```ignore
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, combinator::Or},
- /// prelude::*,
- /// };
- ///
- /// // Enables spans and events with targets starting with `interesting_target`:
- /// let target_filter = filter_fn(|meta| {
- /// meta.target().starts_with("interesting_target")
- /// });
- ///
- /// // Enables spans and events with levels `INFO` and below:
- /// let level_filter = LevelFilter::INFO;
- ///
- /// // Combine the two filters together so that a span or event is enabled
- /// // if it is at INFO or lower, or if it has a target starting with
- /// // `interesting_target`.
- /// let filter = Or::new(level_filter, target_filter);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- ///
- /// // This event will *not* be enabled:
- /// tracing::debug!("an uninteresting event");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!("an uninteresting INFO event");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!(target: "interesting_target", "a very interesting event");
- ///
- /// // This event *will* be enabled:
- /// tracing::debug!(target: "interesting_target", "interesting debug event...");
- /// ```
- ///
- /// Enabling a higher level for a particular target by using `Or` in
- /// conjunction with the [`And`] combinator:
- ///
- /// ```ignore
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, combinator},
- /// prelude::*,
- /// };
- ///
- /// // This filter will enable spans and events with targets beginning with
- /// // `my_crate`:
- /// let my_crate = filter_fn(|meta| {
- /// meta.target().starts_with("my_crate")
- /// });
- ///
- /// // Combine the `my_crate` filter with a `LevelFilter` to produce a filter
- /// // that will enable the `INFO` level and lower for spans and events with
- /// // `my_crate` targets:
- /// let filter = combinator::And::new(my_crate, LevelFilter::INFO);
- ///
- /// // If a span or event *doesn't* have a target beginning with
- /// // `my_crate`, enable it if it has the `WARN` level or lower:
- /// // let filter = combinator::Or::new(filter, LevelFilter::WARN);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- /// ```
- ///
- /// [`Filter`]: crate::layer::Filter
- pub(crate) fn new(a: A, b: B) -> Self {
- Self {
- a,
- b,
- _s: PhantomData,
- }
- }
-}
-
-impl<A, B, S> Filter<S> for Or<A, B, S>
-where
- A: Filter<S>,
- B: Filter<S>,
-{
- #[inline]
- fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- self.a.enabled(meta, cx) || self.b.enabled(meta, cx)
- }
-
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- let a = self.a.callsite_enabled(meta);
- let b = self.b.callsite_enabled(meta);
-
- // If either filter will always enable the span or event, return `always`.
- if a.is_always() || b.is_always() {
- return Interest::always();
- }
-
- // Okay, if either filter will sometimes enable the span or event,
- // return `sometimes`.
- if a.is_sometimes() || b.is_sometimes() {
- return Interest::sometimes();
- }
-
- debug_assert!(
- a.is_never() && b.is_never(),
- "if neither filter was `always` or `sometimes`, both must be `never` (a={:?}; b={:?})",
- a,
- b,
- );
- Interest::never()
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- // If either hint is `None`, return `None`. Otherwise, return the less restrictive.
- Some(cmp::max(self.a.max_level_hint()?, self.b.max_level_hint()?))
- }
-
- #[inline]
- fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
- self.a.on_new_span(attrs, id, ctx.clone());
- self.b.on_new_span(attrs, id, ctx)
- }
-
- #[inline]
- fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) {
- self.a.on_record(id, values, ctx.clone());
- self.b.on_record(id, values, ctx);
- }
-
- #[inline]
- fn on_enter(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_enter(id, ctx.clone());
- self.b.on_enter(id, ctx);
- }
-
- #[inline]
- fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_exit(id, ctx.clone());
- self.b.on_exit(id, ctx);
- }
-
- #[inline]
- fn on_close(&self, id: Id, ctx: Context<'_, S>) {
- self.a.on_close(id.clone(), ctx.clone());
- self.b.on_close(id, ctx);
- }
-}
-
-impl<A, B, S> Clone for Or<A, B, S>
-where
- A: Clone,
- B: Clone,
-{
- fn clone(&self) -> Self {
- Self {
- a: self.a.clone(),
- b: self.b.clone(),
- _s: PhantomData,
- }
- }
-}
-
-impl<A, B, S> fmt::Debug for Or<A, B, S>
-where
- A: fmt::Debug,
- B: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Or")
- .field("a", &self.a)
- .field("b", &self.b)
- .finish()
- }
-}
-
-// === impl Not ===
-
-impl<A, S> Not<A, S>
-where
- A: Filter<S>,
-{
- /// Inverts the result of a [`Filter`].
- ///
- /// If the wrapped filter would enable a span or event, it will be disabled. If
- /// it would disable a span or event, that span or event will be enabled.
- ///
- /// [`Filter`]: crate::layer::Filter
- pub(crate) fn new(a: A) -> Self {
- Self { a, _s: PhantomData }
- }
-}
-
-impl<A, S> Filter<S> for Not<A, S>
-where
- A: Filter<S>,
-{
- #[inline]
- fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- !self.a.enabled(meta, cx)
- }
-
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- match self.a.callsite_enabled(meta) {
- i if i.is_always() => Interest::never(),
- i if i.is_never() => Interest::always(),
- _ => Interest::sometimes(),
- }
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- // TODO(eliza): figure this out???
- None
- }
-
- #[inline]
- fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
- self.a.on_new_span(attrs, id, ctx);
- }
-
- #[inline]
- fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) {
- self.a.on_record(id, values, ctx.clone());
- }
-
- #[inline]
- fn on_enter(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_enter(id, ctx);
- }
-
- #[inline]
- fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
- self.a.on_exit(id, ctx);
- }
-
- #[inline]
- fn on_close(&self, id: Id, ctx: Context<'_, S>) {
- self.a.on_close(id, ctx);
- }
-}
-
-impl<A, S> Clone for Not<A, S>
-where
- A: Clone,
-{
- fn clone(&self) -> Self {
- Self {
- a: self.a.clone(),
- _s: PhantomData,
- }
- }
-}
-
-impl<A, S> fmt::Debug for Not<A, S>
-where
- A: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("Not").field(&self.a).finish()
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs b/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs
deleted file mode 100644
index 8949cfb5a..000000000
--- a/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs
+++ /dev/null
@@ -1,1135 +0,0 @@
-//! ## Per-Layer Filtering
-//!
-//! Per-layer filters permit individual `Layer`s to have their own filter
-//! configurations without interfering with other `Layer`s.
-//!
-//! This module is not public; the public APIs defined in this module are
-//! re-exported in the top-level `filter` module. Therefore, this documentation
-//! primarily concerns the internal implementation details. For the user-facing
-//! public API documentation, see the individual public types in this module, as
-//! well as the, see the `Layer` trait documentation's [per-layer filtering
-//! section]][1].
-//!
-//! ## How does per-layer filtering work?
-//!
-//! As described in the API documentation, the [`Filter`] trait defines a
-//! filtering strategy for a per-layer filter. We expect there will be a variety
-//! of implementations of [`Filter`], both in `tracing-subscriber` and in user
-//! code.
-//!
-//! To actually *use* a [`Filter`] implementation, it is combined with a
-//! [`Layer`] by the [`Filtered`] struct defined in this module. [`Filtered`]
-//! implements [`Layer`] by calling into the wrapped [`Layer`], or not, based on
-//! the filtering strategy. While there will be a variety of types that implement
-//! [`Filter`], all actual *uses* of per-layer filtering will occur through the
-//! [`Filtered`] struct. Therefore, most of the implementation details live
-//! there.
-//!
-//! [1]: crate::layer#per-layer-filtering
-//! [`Filter`]: crate::layer::Filter
-use crate::{
- filter::LevelFilter,
- layer::{self, Context, Layer},
- registry,
-};
-use std::{
- any::TypeId,
- cell::{Cell, RefCell},
- fmt,
- marker::PhantomData,
- ops::Deref,
- sync::Arc,
- thread_local,
-};
-use tracing_core::{
- span,
- subscriber::{Interest, Subscriber},
- Event, Metadata,
-};
-pub mod combinator;
-
-/// A [`Layer`] that wraps an inner [`Layer`] and adds a [`Filter`] which
-/// controls what spans and events are enabled for that layer.
-///
-/// This is returned by the [`Layer::with_filter`] method. See the
-/// [documentation on per-layer filtering][plf] for details.
-///
-/// [`Filter`]: crate::layer::Filter
-/// [plf]: crate::layer#per-layer-filtering
-#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
-#[derive(Clone)]
-pub struct Filtered<L, F, S> {
- filter: F,
- layer: L,
- id: MagicPlfDowncastMarker,
- _s: PhantomData<fn(S)>,
-}
-
-/// Uniquely identifies an individual [`Filter`] instance in the context of
-/// a [`Subscriber`].
-///
-/// When adding a [`Filtered`] [`Layer`] to a [`Subscriber`], the [`Subscriber`]
-/// generates a `FilterId` for that [`Filtered`] layer. The [`Filtered`] layer
-/// will then use the generated ID to query whether a particular span was
-/// previously enabled by that layer's [`Filter`].
-///
-/// **Note**: Currently, the [`Registry`] type provided by this crate is the
-/// **only** [`Subscriber`] implementation capable of participating in per-layer
-/// filtering. Therefore, the `FilterId` type cannot currently be constructed by
-/// code outside of `tracing-subscriber`. In the future, new APIs will be added to `tracing-subscriber` to
-/// allow non-Registry [`Subscriber`]s to also participate in per-layer
-/// filtering. When those APIs are added, subscribers will be responsible
-/// for generating and assigning `FilterId`s.
-///
-/// [`Filter`]: crate::layer::Filter
-/// [`Subscriber`]: tracing_core::Subscriber
-/// [`Layer`]: crate::layer::Layer
-/// [`Registry`]: crate::registry::Registry
-#[cfg(feature = "registry")]
-#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
-#[derive(Copy, Clone)]
-pub struct FilterId(u64);
-
-/// A bitmap tracking which [`FilterId`]s have enabled a given span or
-/// event.
-///
-/// This is currently a private type that's used exclusively by the
-/// [`Registry`]. However, in the future, this may become a public API, in order
-/// to allow user subscribers to host [`Filter`]s.
-///
-/// [`Registry`]: crate::Registry
-/// [`Filter`]: crate::layer::Filter
-#[derive(Default, Copy, Clone, Eq, PartialEq)]
-pub(crate) struct FilterMap {
- bits: u64,
-}
-
-/// The current state of `enabled` calls to per-layer filters on this
-/// thread.
-///
-/// When `Filtered::enabled` is called, the filter will set the bit
-/// corresponding to its ID if the filter will disable the event/span being
-/// filtered. When the event or span is recorded, the per-layer filter will
-/// check its bit to determine if it disabled that event or span, and skip
-/// forwarding the event or span to the inner layer if the bit is set. Once
-/// a span or event has been skipped by a per-layer filter, it unsets its
-/// bit, so that the `FilterMap` has been cleared for the next set of
-/// `enabled` calls.
-///
-/// FilterState is also read by the `Registry`, for two reasons:
-///
-/// 1. When filtering a span, the Registry must store the `FilterMap`
-/// generated by `Filtered::enabled` calls for that span as part of the
-/// span's per-span data. This allows `Filtered` layers to determine
-/// whether they had previously disabled a given span, and avoid showing it
-/// to the wrapped layer if it was disabled.
-///
-/// This allows `Filtered` layers to also filter out the spans they
-/// disable from span traversals (such as iterating over parents, etc).
-/// 2. If all the bits are set, then every per-layer filter has decided it
-/// doesn't want to enable that span or event. In that case, the
-/// `Registry`'s `enabled` method will return `false`, so that
-/// recording a span or event can be skipped entirely.
-#[derive(Debug)]
-pub(crate) struct FilterState {
- enabled: Cell<FilterMap>,
- // TODO(eliza): `Interest`s should _probably_ be `Copy`. The only reason
- // they're not is our Obsessive Commitment to Forwards-Compatibility. If
- // this changes in tracing-core`, we can make this a `Cell` rather than
- // `RefCell`...
- interest: RefCell<Option<Interest>>,
-
- #[cfg(debug_assertions)]
- counters: DebugCounters,
-}
-
-/// Extra counters added to `FilterState` used only to make debug assertions.
-#[cfg(debug_assertions)]
-#[derive(Debug, Default)]
-struct DebugCounters {
- /// How many per-layer filters have participated in the current `enabled`
- /// call?
- in_filter_pass: Cell<usize>,
-
- /// How many per-layer filters have participated in the current `register_callsite`
- /// call?
- in_interest_pass: Cell<usize>,
-}
-
-thread_local! {
- pub(crate) static FILTERING: FilterState = FilterState::new();
-}
-
-/// Extension trait adding [combinators] for combining [`Filter`].
-///
-/// [combinators]: crate::filter::combinator
-/// [`Filter`]: crate::layer::Filter
-pub trait FilterExt<S>: layer::Filter<S> {
- /// Combines this [`Filter`] with another [`Filter`] s so that spans and
- /// events are enabled if and only if *both* filters return `true`.
- ///
- /// # Examples
- ///
- /// Enabling spans or events if they have both a particular target *and* are
- /// above a certain level:
- ///
- /// ```
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, FilterExt},
- /// prelude::*,
- /// };
- ///
- /// // Enables spans and events with targets starting with `interesting_target`:
- /// let target_filter = filter_fn(|meta| {
- /// meta.target().starts_with("interesting_target")
- /// });
- ///
- /// // Enables spans and events with levels `INFO` and below:
- /// let level_filter = LevelFilter::INFO;
- ///
- /// // Combine the two filters together, returning a filter that only enables
- /// // spans and events that *both* filters will enable:
- /// let filter = target_filter.and(level_filter);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- ///
- /// // This event will *not* be enabled:
- /// tracing::info!("an event with an uninteresting target");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!(target: "interesting_target", "a very interesting event");
- ///
- /// // This event will *not* be enabled:
- /// tracing::debug!(target: "interesting_target", "interesting debug event...");
- /// ```
- ///
- /// [`Filter`]: crate::layer::Filter
- fn and<B>(self, other: B) -> combinator::And<Self, B, S>
- where
- Self: Sized,
- B: layer::Filter<S>,
- {
- combinator::And::new(self, other)
- }
-
- /// Combines two [`Filter`]s so that spans and events are enabled if *either* filter
- /// returns `true`.
- ///
- /// # Examples
- ///
- /// Enabling spans and events at the `INFO` level and above, and all spans
- /// and events with a particular target:
- /// ```
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, FilterExt},
- /// prelude::*,
- /// };
- ///
- /// // Enables spans and events with targets starting with `interesting_target`:
- /// let target_filter = filter_fn(|meta| {
- /// meta.target().starts_with("interesting_target")
- /// });
- ///
- /// // Enables spans and events with levels `INFO` and below:
- /// let level_filter = LevelFilter::INFO;
- ///
- /// // Combine the two filters together so that a span or event is enabled
- /// // if it is at INFO or lower, or if it has a target starting with
- /// // `interesting_target`.
- /// let filter = level_filter.or(target_filter);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- ///
- /// // This event will *not* be enabled:
- /// tracing::debug!("an uninteresting event");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!("an uninteresting INFO event");
- ///
- /// // This event *will* be enabled:
- /// tracing::info!(target: "interesting_target", "a very interesting event");
- ///
- /// // This event *will* be enabled:
- /// tracing::debug!(target: "interesting_target", "interesting debug event...");
- /// ```
- ///
- /// Enabling a higher level for a particular target by using `or` in
- /// conjunction with the [`and`] combinator:
- ///
- /// ```
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, FilterExt},
- /// prelude::*,
- /// };
- ///
- /// // This filter will enable spans and events with targets beginning with
- /// // `my_crate`:
- /// let my_crate = filter_fn(|meta| {
- /// meta.target().starts_with("my_crate")
- /// });
- ///
- /// let filter = my_crate
- /// // Combine the `my_crate` filter with a `LevelFilter` to produce a
- /// // filter that will enable the `INFO` level and lower for spans and
- /// // events with `my_crate` targets:
- /// .and(LevelFilter::INFO)
- /// // If a span or event *doesn't* have a target beginning with
- /// // `my_crate`, enable it if it has the `WARN` level or lower:
- /// .or(LevelFilter::WARN);
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- /// ```
- ///
- /// [`Filter`]: crate::layer::Filter
- /// [`and`]: FilterExt::and
- fn or<B>(self, other: B) -> combinator::Or<Self, B, S>
- where
- Self: Sized,
- B: layer::Filter<S>,
- {
- combinator::Or::new(self, other)
- }
-
- /// Inverts `self`, returning a filter that enables spans and events only if
- /// `self` would *not* enable them.
- fn not(self) -> combinator::Not<Self, S>
- where
- Self: Sized,
- {
- combinator::Not::new(self)
- }
-
- /// [Boxes] `self`, erasing its concrete type.
- ///
- /// This is equivalent to calling [`Box::new`], but in method form, so that
- /// it can be used when chaining combinator methods.
- ///
- /// # Examples
- ///
- /// When different combinations of filters are used conditionally, they may
- /// have different types. For example, the following code won't compile,
- /// since the `if` and `else` clause produce filters of different types:
- ///
- /// ```compile_fail
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, FilterExt},
- /// prelude::*,
- /// };
- ///
- /// let enable_bar_target: bool = // ...
- /// # false;
- ///
- /// let filter = if enable_bar_target {
- /// filter_fn(|meta| meta.target().starts_with("foo"))
- /// // If `enable_bar_target` is true, add a `filter_fn` enabling
- /// // spans and events with the target `bar`:
- /// .or(filter_fn(|meta| meta.target().starts_with("bar")))
- /// .and(LevelFilter::INFO)
- /// } else {
- /// filter_fn(|meta| meta.target().starts_with("foo"))
- /// .and(LevelFilter::INFO)
- /// };
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- /// ```
- ///
- /// By using `boxed`, the types of the two different branches can be erased,
- /// so the assignment to the `filter` variable is valid (as both branches
- /// have the type `Box<dyn Filter<S> + Send + Sync + 'static>`). The
- /// following code *does* compile:
- ///
- /// ```
- /// use tracing_subscriber::{
- /// filter::{filter_fn, LevelFilter, FilterExt},
- /// prelude::*,
- /// };
- ///
- /// let enable_bar_target: bool = // ...
- /// # false;
- ///
- /// let filter = if enable_bar_target {
- /// filter_fn(|meta| meta.target().starts_with("foo"))
- /// .or(filter_fn(|meta| meta.target().starts_with("bar")))
- /// .and(LevelFilter::INFO)
- /// // Boxing the filter erases its type, so both branches now
- /// // have the same type.
- /// .boxed()
- /// } else {
- /// filter_fn(|meta| meta.target().starts_with("foo"))
- /// .and(LevelFilter::INFO)
- /// .boxed()
- /// };
- ///
- /// tracing_subscriber::registry()
- /// .with(tracing_subscriber::fmt::layer().with_filter(filter))
- /// .init();
- /// ```
- ///
- /// [Boxes]: std::boxed
- /// [`Box::new`]: std::boxed::Box::new
- fn boxed(self) -> Box<dyn layer::Filter<S> + Send + Sync + 'static>
- where
- Self: Sized + Send + Sync + 'static,
- {
- Box::new(self)
- }
-}
-
-// === impl Filter ===
-
-#[cfg(feature = "registry")]
-#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
-impl<S> layer::Filter<S> for LevelFilter {
- fn enabled(&self, meta: &Metadata<'_>, _: &Context<'_, S>) -> bool {
- meta.level() <= self
- }
-
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- if meta.level() <= self {
- Interest::always()
- } else {
- Interest::never()
- }
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- Some(*self)
- }
-}
-
-macro_rules! filter_impl_body {
- () => {
- #[inline]
- fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool {
- self.deref().enabled(meta, cx)
- }
-
- #[inline]
- fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest {
- self.deref().callsite_enabled(meta)
- }
-
- #[inline]
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.deref().max_level_hint()
- }
- };
-}
-
-#[cfg(feature = "registry")]
-#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
-impl<S> layer::Filter<S> for Arc<dyn layer::Filter<S> + Send + Sync + 'static> {
- filter_impl_body!();
-}
-
-#[cfg(feature = "registry")]
-#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
-impl<S> layer::Filter<S> for Box<dyn layer::Filter<S> + Send + Sync + 'static> {
- filter_impl_body!();
-}
-
-// === impl Filtered ===
-
-impl<L, F, S> Filtered<L, F, S> {
- /// Wraps the provided [`Layer`] so that it is filtered by the given
- /// [`Filter`].
- ///
- /// This is equivalent to calling the [`Layer::with_filter`] method.
- ///
- /// See the [documentation on per-layer filtering][plf] for details.
- ///
- /// [`Filter`]: crate::layer::Filter
- /// [plf]: crate::layer#per-layer-filtering
- pub fn new(layer: L, filter: F) -> Self {
- Self {
- layer,
- filter,
- id: MagicPlfDowncastMarker(FilterId::disabled()),
- _s: PhantomData,
- }
- }
-
- #[inline(always)]
- fn id(&self) -> FilterId {
- debug_assert!(
- !self.id.0.is_disabled(),
- "a `Filtered` layer was used, but it had no `FilterId`; \
- was it registered with the subscriber?"
- );
- self.id.0
- }
-
- fn did_enable(&self, f: impl FnOnce()) {
- FILTERING.with(|filtering| filtering.did_enable(self.id(), f))
- }
-
- /// Borrows the [`Filter`](crate::layer::Filter) used by this layer.
- pub fn filter(&self) -> &F {
- &self.filter
- }
-
- /// Mutably borrows the [`Filter`](crate::layer::Filter) used by this layer.
- ///
- /// When this layer can be mutably borrowed, this may be used to mutate the filter.
- /// Generally, this will primarily be used with the
- /// [`reload::Handle::modify`](crate::reload::Handle::modify) method.
- ///
- /// # Examples
- ///
- /// ```
- /// # use tracing::info;
- /// # use tracing_subscriber::{filter,fmt,reload,Registry,prelude::*};
- /// # fn main() {
- /// let filtered_layer = fmt::Layer::default().with_filter(filter::LevelFilter::WARN);
- /// let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer);
- /// #
- /// # // specifying the Registry type is required
- /// # let _: &reload::Handle<filter::Filtered<fmt::Layer<Registry>,
- /// # filter::LevelFilter, Registry>,Registry>
- /// # = &reload_handle;
- /// #
- /// info!("This will be ignored");
- /// reload_handle.modify(|layer| *layer.filter_mut() = filter::LevelFilter::INFO);
- /// info!("This will be logged");
- /// # }
- /// ```
- pub fn filter_mut(&mut self) -> &mut F {
- &mut self.filter
- }
-
- /// Borrows the inner [`Layer`] wrapped by this `Filtered` layer.
- pub fn inner(&self) -> &L {
- &self.layer
- }
-
- /// Mutably borrows the inner [`Layer`] wrapped by this `Filtered` layer.
- ///
- /// This method is primarily expected to be used with the
- /// [`reload::Handle::modify`](crate::reload::Handle::modify) method.
- ///
- /// # Examples
- ///
- /// ```
- /// # use tracing::info;
- /// # use tracing_subscriber::{filter,fmt,reload,Registry,prelude::*};
- /// # fn non_blocking<T: std::io::Write>(writer: T) -> (fn() -> std::io::Stdout) {
- /// # std::io::stdout
- /// # }
- /// # fn main() {
- /// let filtered_layer = fmt::layer().with_writer(non_blocking(std::io::stderr())).with_filter(filter::LevelFilter::INFO);
- /// let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer);
- /// #
- /// # // specifying the Registry type is required
- /// # let _: &reload::Handle<filter::Filtered<fmt::Layer<Registry, _, _, fn() -> std::io::Stdout>,
- /// # filter::LevelFilter, Registry>, Registry>
- /// # = &reload_handle;
- /// #
- /// info!("This will be logged to stderr");
- /// reload_handle.modify(|layer| *layer.inner_mut().writer_mut() = non_blocking(std::io::stdout()));
- /// info!("This will be logged to stdout");
- /// # }
- /// ```
- ///
- /// [subscriber]: Subscribe
- pub fn inner_mut(&mut self) -> &mut L {
- &mut self.layer
- }
-}
-
-impl<S, L, F> Layer<S> for Filtered<L, F, S>
-where
- S: Subscriber + for<'span> registry::LookupSpan<'span> + 'static,
- F: layer::Filter<S> + 'static,
- L: Layer<S>,
-{
- fn on_layer(&mut self, subscriber: &mut S) {
- self.id = MagicPlfDowncastMarker(subscriber.register_filter());
- self.layer.on_layer(subscriber);
- }
-
- // TODO(eliza): can we figure out a nice way to make the `Filtered` layer
- // not call `is_enabled_for` in hooks that the inner layer doesn't actually
- // have real implementations of? probably not...
- //
- // it would be cool if there was some wild rust reflection way of checking
- // if a trait impl has the default impl of a trait method or not, but that's
- // almsot certainly impossible...right?
-
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- let interest = self.filter.callsite_enabled(metadata);
-
- // If the filter didn't disable the callsite, allow the inner layer to
- // register it — since `register_callsite` is also used for purposes
- // such as reserving/caching per-callsite data, we want the inner layer
- // to be able to perform any other registration steps. However, we'll
- // ignore its `Interest`.
- if !interest.is_never() {
- self.layer.register_callsite(metadata);
- }
-
- // Add our `Interest` to the current sum of per-layer filter `Interest`s
- // for this callsite.
- FILTERING.with(|filtering| filtering.add_interest(interest));
-
- // don't short circuit! if the stack consists entirely of `Layer`s with
- // per-layer filters, the `Registry` will return the actual `Interest`
- // value that's the sum of all the `register_callsite` calls to those
- // per-layer filters. if we returned an actual `never` interest here, a
- // `Layered` layer would short-circuit and not allow any `Filtered`
- // layers below us if _they_ are interested in the callsite.
- Interest::always()
- }
-
- fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool {
- let cx = cx.with_filter(self.id());
- let enabled = self.filter.enabled(metadata, &cx);
- FILTERING.with(|filtering| filtering.set(self.id(), enabled));
-
- if enabled {
- // If the filter enabled this metadata, ask the wrapped layer if
- // _it_ wants it --- it might have a global filter.
- self.layer.enabled(metadata, cx)
- } else {
- // Otherwise, return `true`. The _per-layer_ filter disabled this
- // metadata, but returning `false` in `Layer::enabled` will
- // short-circuit and globally disable the span or event. This is
- // *not* what we want for per-layer filters, as other layers may
- // still want this event. Returning `true` here means we'll continue
- // asking the next layer in the stack.
- //
- // Once all per-layer filters have been evaluated, the `Registry`
- // at the root of the stack will return `false` from its `enabled`
- // method if *every* per-layer filter disabled this metadata.
- // Otherwise, the individual per-layer filters will skip the next
- // `new_span` or `on_event` call for their layer if *they* disabled
- // the span or event, but it was not globally disabled.
- true
- }
- }
-
- fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, cx: Context<'_, S>) {
- self.did_enable(|| {
- let cx = cx.with_filter(self.id());
- self.filter.on_new_span(attrs, id, cx.clone());
- self.layer.on_new_span(attrs, id, cx);
- })
- }
-
- #[doc(hidden)]
- fn max_level_hint(&self) -> Option<LevelFilter> {
- self.filter.max_level_hint()
- }
-
- fn on_record(&self, span: &span::Id, values: &span::Record<'_>, cx: Context<'_, S>) {
- if let Some(cx) = cx.if_enabled_for(span, self.id()) {
- self.filter.on_record(span, values, cx.clone());
- self.layer.on_record(span, values, cx)
- }
- }
-
- fn on_follows_from(&self, span: &span::Id, follows: &span::Id, cx: Context<'_, S>) {
- // only call `on_follows_from` if both spans are enabled by us
- if cx.is_enabled_for(span, self.id()) && cx.is_enabled_for(follows, self.id()) {
- self.layer
- .on_follows_from(span, follows, cx.with_filter(self.id()))
- }
- }
-
- fn on_event(&self, event: &Event<'_>, cx: Context<'_, S>) {
- self.did_enable(|| {
- self.layer.on_event(event, cx.with_filter(self.id()));
- })
- }
-
- fn on_enter(&self, id: &span::Id, cx: Context<'_, S>) {
- if let Some(cx) = cx.if_enabled_for(id, self.id()) {
- self.filter.on_enter(id, cx.clone());
- self.layer.on_enter(id, cx);
- }
- }
-
- fn on_exit(&self, id: &span::Id, cx: Context<'_, S>) {
- if let Some(cx) = cx.if_enabled_for(id, self.id()) {
- self.filter.on_exit(id, cx.clone());
- self.layer.on_exit(id, cx);
- }
- }
-
- fn on_close(&self, id: span::Id, cx: Context<'_, S>) {
- if let Some(cx) = cx.if_enabled_for(&id, self.id()) {
- self.filter.on_close(id.clone(), cx.clone());
- self.layer.on_close(id, cx);
- }
- }
-
- // XXX(eliza): the existence of this method still makes me sad...
- fn on_id_change(&self, old: &span::Id, new: &span::Id, cx: Context<'_, S>) {
- if let Some(cx) = cx.if_enabled_for(old, self.id()) {
- self.layer.on_id_change(old, new, cx)
- }
- }
-
- #[doc(hidden)]
- #[inline]
- unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
- match id {
- id if id == TypeId::of::<Self>() => Some(self as *const _ as *const ()),
- id if id == TypeId::of::<L>() => Some(&self.layer as *const _ as *const ()),
- id if id == TypeId::of::<F>() => Some(&self.filter as *const _ as *const ()),
- id if id == TypeId::of::<MagicPlfDowncastMarker>() => {
- Some(&self.id as *const _ as *const ())
- }
- _ => self.layer.downcast_raw(id),
- }
- }
-}
-
-impl<F, L, S> fmt::Debug for Filtered<F, L, S>
-where
- F: fmt::Debug,
- L: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Filtered")
- .field("filter", &self.filter)
- .field("layer", &self.layer)
- .field("id", &self.id)
- .finish()
- }
-}
-
-// === impl FilterId ===
-
-impl FilterId {
- const fn disabled() -> Self {
- Self(std::u64::MAX)
- }
-
- /// Returns a `FilterId` that will consider _all_ spans enabled.
- pub(crate) const fn none() -> Self {
- Self(0)
- }
-
- pub(crate) fn new(id: u8) -> Self {
- assert!(id < 64, "filter IDs may not be greater than 64");
- Self(1 << id as usize)
- }
-
- /// Combines two `FilterId`s, returning a new `FilterId` that will match a
- /// [`FilterMap`] where the span was disabled by _either_ this `FilterId`
- /// *or* the combined `FilterId`.
- ///
- /// This method is called by [`Context`]s when adding the `FilterId` of a
- /// [`Filtered`] layer to the context.
- ///
- /// This is necessary for cases where we have a tree of nested [`Filtered`]
- /// layers, like this:
- ///
- /// ```text
- /// Filtered {
- /// filter1,
- /// Layered {
- /// layer1,
- /// Filtered {
- /// filter2,
- /// layer2,
- /// },
- /// }
- /// ```
- ///
- /// We want `layer2` to be affected by both `filter1` _and_ `filter2`.
- /// Without combining `FilterId`s, this works fine when filtering
- /// `on_event`/`new_span`, because the outer `Filtered` layer (`filter1`)
- /// won't call the inner layer's `on_event` or `new_span` callbacks if it
- /// disabled the event/span.
- ///
- /// However, it _doesn't_ work when filtering span lookups and traversals
- /// (e.g. `scope`). This is because the [`Context`] passed to `layer2`
- /// would set its filter ID to the filter ID of `filter2`, and would skip
- /// spans that were disabled by `filter2`. However, what if a span was
- /// disabled by `filter1`? We wouldn't see it in `new_span`, but we _would_
- /// see it in lookups and traversals...which we don't want.
- ///
- /// When a [`Filtered`] layer adds its ID to a [`Context`], it _combines_ it
- /// with any previous filter ID that the context had, rather than replacing
- /// it. That way, `layer2`'s context will check if a span was disabled by
- /// `filter1` _or_ `filter2`. The way we do this, instead of representing
- /// `FilterId`s as a number number that we shift a 1 over by to get a mask,
- /// we just store the actual mask,so we can combine them with a bitwise-OR.
- ///
- /// For example, if we consider the following case (pretending that the
- /// masks are 8 bits instead of 64 just so i don't have to write out a bunch
- /// of extra zeroes):
- ///
- /// - `filter1` has the filter id 1 (`0b0000_0001`)
- /// - `filter2` has the filter id 2 (`0b0000_0010`)
- ///
- /// A span that gets disabled by filter 1 would have the [`FilterMap`] with
- /// bits `0b0000_0001`.
- ///
- /// If the `FilterId` was internally represented as `(bits to shift + 1),
- /// when `layer2`'s [`Context`] checked if it enabled the span, it would
- /// make the mask `0b0000_0010` (`1 << 1`). That bit would not be set in the
- /// [`FilterMap`], so it would see that it _didn't_ disable the span. Which
- /// is *true*, it just doesn't reflect the tree-like shape of the actual
- /// subscriber.
- ///
- /// By having the IDs be masks instead of shifts, though, when the
- /// [`Filtered`] with `filter2` gets the [`Context`] with `filter1`'s filter ID,
- /// instead of replacing it, it ors them together:
- ///
- /// ```ignore
- /// 0b0000_0001 | 0b0000_0010 == 0b0000_0011;
- /// ```
- ///
- /// We then test if the span was disabled by seeing if _any_ bits in the
- /// mask are `1`:
- ///
- /// ```ignore
- /// filtermap & mask != 0;
- /// 0b0000_0001 & 0b0000_0011 != 0;
- /// 0b0000_0001 != 0;
- /// true;
- /// ```
- ///
- /// [`Context`]: crate::layer::Context
- pub(crate) fn and(self, FilterId(other): Self) -> Self {
- // If this mask is disabled, just return the other --- otherwise, we
- // would always see that every span is disabled.
- if self.0 == Self::disabled().0 {
- return Self(other);
- }
-
- Self(self.0 | other)
- }
-
- fn is_disabled(self) -> bool {
- self.0 == Self::disabled().0
- }
-}
-
-impl fmt::Debug for FilterId {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // don't print a giant set of the numbers 0..63 if the filter ID is disabled.
- if self.0 == Self::disabled().0 {
- return f
- .debug_tuple("FilterId")
- .field(&format_args!("DISABLED"))
- .finish();
- }
-
- if f.alternate() {
- f.debug_struct("FilterId")
- .field("ids", &format_args!("{:?}", FmtBitset(self.0)))
- .field("bits", &format_args!("{:b}", self.0))
- .finish()
- } else {
- f.debug_tuple("FilterId").field(&FmtBitset(self.0)).finish()
- }
- }
-}
-
-impl fmt::Binary for FilterId {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("FilterId")
- .field(&format_args!("{:b}", self.0))
- .finish()
- }
-}
-
-// === impl FilterExt ===
-
-impl<F, S> FilterExt<S> for F where F: layer::Filter<S> {}
-
-// === impl FilterMap ===
-
-impl FilterMap {
- pub(crate) fn set(self, FilterId(mask): FilterId, enabled: bool) -> Self {
- if mask == std::u64::MAX {
- return self;
- }
-
- if enabled {
- Self {
- bits: self.bits & (!mask),
- }
- } else {
- Self {
- bits: self.bits | mask,
- }
- }
- }
-
- #[inline]
- pub(crate) fn is_enabled(self, FilterId(mask): FilterId) -> bool {
- self.bits & mask == 0
- }
-
- #[inline]
- pub(crate) fn any_enabled(self) -> bool {
- self.bits != std::u64::MAX
- }
-}
-
-impl fmt::Debug for FilterMap {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let alt = f.alternate();
- let mut s = f.debug_struct("FilterMap");
- s.field("disabled_by", &format_args!("{:?}", &FmtBitset(self.bits)));
-
- if alt {
- s.field("bits", &format_args!("{:b}", self.bits));
- }
-
- s.finish()
- }
-}
-
-impl fmt::Binary for FilterMap {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FilterMap")
- .field("bits", &format_args!("{:b}", self.bits))
- .finish()
- }
-}
-
-// === impl FilterState ===
-
-impl FilterState {
- fn new() -> Self {
- Self {
- enabled: Cell::new(FilterMap::default()),
- interest: RefCell::new(None),
-
- #[cfg(debug_assertions)]
- counters: DebugCounters::default(),
- }
- }
-
- fn set(&self, filter: FilterId, enabled: bool) {
- #[cfg(debug_assertions)]
- {
- let in_current_pass = self.counters.in_filter_pass.get();
- if in_current_pass == 0 {
- debug_assert_eq!(self.enabled.get(), FilterMap::default());
- }
- self.counters.in_filter_pass.set(in_current_pass + 1);
- debug_assert_eq!(
- self.counters.in_interest_pass.get(),
- 0,
- "if we are in or starting a filter pass, we must not be in an interest pass."
- )
- }
-
- self.enabled.set(self.enabled.get().set(filter, enabled))
- }
-
- fn add_interest(&self, interest: Interest) {
- let mut curr_interest = self.interest.borrow_mut();
-
- #[cfg(debug_assertions)]
- {
- let in_current_pass = self.counters.in_interest_pass.get();
- if in_current_pass == 0 {
- debug_assert!(curr_interest.is_none());
- }
- self.counters.in_interest_pass.set(in_current_pass + 1);
- }
-
- if let Some(curr_interest) = curr_interest.as_mut() {
- if (curr_interest.is_always() && !interest.is_always())
- || (curr_interest.is_never() && !interest.is_never())
- {
- *curr_interest = Interest::sometimes();
- }
- // If the two interests are the same, do nothing. If the current
- // interest is `sometimes`, stay sometimes.
- } else {
- *curr_interest = Some(interest);
- }
- }
-
- pub(crate) fn event_enabled() -> bool {
- FILTERING
- .try_with(|this| {
- let enabled = this.enabled.get().any_enabled();
- #[cfg(debug_assertions)]
- {
- if this.counters.in_filter_pass.get() == 0 {
- debug_assert_eq!(this.enabled.get(), FilterMap::default());
- }
-
- // Nothing enabled this event, we won't tick back down the
- // counter in `did_enable`. Reset it.
- if !enabled {
- this.counters.in_filter_pass.set(0);
- }
- }
- enabled
- })
- .unwrap_or(true)
- }
-
- /// Executes a closure if the filter with the provided ID did not disable
- /// the current span/event.
- ///
- /// This is used to implement the `on_event` and `new_span` methods for
- /// `Filtered`.
- fn did_enable(&self, filter: FilterId, f: impl FnOnce()) {
- let map = self.enabled.get();
- if map.is_enabled(filter) {
- // If the filter didn't disable the current span/event, run the
- // callback.
- f();
- } else {
- // Otherwise, if this filter _did_ disable the span or event
- // currently being processed, clear its bit from this thread's
- // `FilterState`. The bit has already been "consumed" by skipping
- // this callback, and we need to ensure that the `FilterMap` for
- // this thread is reset when the *next* `enabled` call occurs.
- self.enabled.set(map.set(filter, true));
- }
- #[cfg(debug_assertions)]
- {
- let in_current_pass = self.counters.in_filter_pass.get();
- if in_current_pass <= 1 {
- debug_assert_eq!(self.enabled.get(), FilterMap::default());
- }
- self.counters
- .in_filter_pass
- .set(in_current_pass.saturating_sub(1));
- debug_assert_eq!(
- self.counters.in_interest_pass.get(),
- 0,
- "if we are in a filter pass, we must not be in an interest pass."
- )
- }
- }
-
- /// Clears the current in-progress filter state.
- ///
- /// This resets the [`FilterMap`] and current [`Interest`] as well as
- /// clearing the debug counters.
- pub(crate) fn clear_enabled() {
- // Drop the `Result` returned by `try_with` --- if we are in the middle
- // a panic and the thread-local has been torn down, that's fine, just
- // ignore it ratehr than panicking.
- let _ = FILTERING.try_with(|filtering| {
- filtering.enabled.set(FilterMap::default());
-
- #[cfg(debug_assertions)]
- filtering.counters.in_filter_pass.set(0);
- });
- }
-
- pub(crate) fn take_interest() -> Option<Interest> {
- FILTERING
- .try_with(|filtering| {
- #[cfg(debug_assertions)]
- {
- if filtering.counters.in_interest_pass.get() == 0 {
- debug_assert!(filtering.interest.try_borrow().ok()?.is_none());
- }
- filtering.counters.in_interest_pass.set(0);
- }
- filtering.interest.try_borrow_mut().ok()?.take()
- })
- .ok()?
- }
-
- pub(crate) fn filter_map(&self) -> FilterMap {
- let map = self.enabled.get();
- #[cfg(debug_assertions)]
- {
- if self.counters.in_filter_pass.get() == 0 {
- debug_assert_eq!(map, FilterMap::default());
- }
- }
-
- map
- }
-}
-/// This is a horrible and bad abuse of the downcasting system to expose
-/// *internally* whether a layer has per-layer filtering, within
-/// `tracing-subscriber`, without exposing a public API for it.
-///
-/// If a `Layer` has per-layer filtering, it will downcast to a
-/// `MagicPlfDowncastMarker`. Since layers which contain other layers permit
-/// downcasting to recurse to their children, this will do the Right Thing with
-/// layers like Reload, Option, etc.
-///
-/// Why is this a wrapper around the `FilterId`, you may ask? Because
-/// downcasting works by returning a pointer, and we don't want to risk
-/// introducing UB by constructing pointers that _don't_ point to a valid
-/// instance of the type they claim to be. In this case, we don't _intend_ for
-/// this pointer to be dereferenced, so it would actually be fine to return one
-/// that isn't a valid pointer...but we can't guarantee that the caller won't
-/// (accidentally) dereference it, so it's better to be safe than sorry. We
-/// could, alternatively, add an additional field to the type that's used only
-/// for returning pointers to as as part of the evil downcasting hack, but I
-/// thought it was nicer to just add a `repr(transparent)` wrapper to the
-/// existing `FilterId` field, since it won't make the struct any bigger.
-///
-/// Don't worry, this isn't on the test. :)
-#[derive(Clone, Copy)]
-#[repr(transparent)]
-struct MagicPlfDowncastMarker(FilterId);
-impl fmt::Debug for MagicPlfDowncastMarker {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Just pretend that `MagicPlfDowncastMarker` doesn't exist for
- // `fmt::Debug` purposes...if no one *sees* it in their `Debug` output,
- // they don't have to know I thought this code would be a good idea.
- fmt::Debug::fmt(&self.0, f)
- }
-}
-
-pub(crate) fn is_plf_downcast_marker(type_id: TypeId) -> bool {
- type_id == TypeId::of::<MagicPlfDowncastMarker>()
-}
-
-/// Does a type implementing `Subscriber` contain any per-layer filters?
-pub(crate) fn subscriber_has_plf<S>(subscriber: &S) -> bool
-where
- S: Subscriber,
-{
- (subscriber as &dyn Subscriber).is::<MagicPlfDowncastMarker>()
-}
-
-/// Does a type implementing `Layer` contain any per-layer filters?
-pub(crate) fn layer_has_plf<L, S>(layer: &L) -> bool
-where
- L: Layer<S>,
- S: Subscriber,
-{
- unsafe {
- // Safety: we're not actually *doing* anything with this pointer --- we
- // only care about the `Option`, which we're turning into a `bool`. So
- // even if the layer decides to be evil and give us some kind of invalid
- // pointer, we don't ever dereference it, so this is always safe.
- layer.downcast_raw(TypeId::of::<MagicPlfDowncastMarker>())
- }
- .is_some()
-}
-
-struct FmtBitset(u64);
-
-impl fmt::Debug for FmtBitset {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut set = f.debug_set();
- for bit in 0..64 {
- // if the `bit`-th bit is set, add it to the debug set
- if self.0 & (1 << bit) != 0 {
- set.entry(&bit);
- }
- }
- set.finish()
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/level.rs b/vendor/tracing-subscriber/src/filter/level.rs
deleted file mode 100644
index 0fa601260..000000000
--- a/vendor/tracing-subscriber/src/filter/level.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use tracing_core::{
- subscriber::{Interest, Subscriber},
- Metadata,
-};
-
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use tracing_core::metadata::{LevelFilter, ParseLevelFilterError as ParseError};
-
-// === impl LevelFilter ===
-
-impl<S: Subscriber> crate::Layer<S> for LevelFilter {
- fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
- if self >= metadata.level() {
- Interest::always()
- } else {
- Interest::never()
- }
- }
-
- fn enabled(&self, metadata: &Metadata<'_>, _: crate::layer::Context<'_, S>) -> bool {
- self >= metadata.level()
- }
-
- fn max_level_hint(&self) -> Option<LevelFilter> {
- Some(*self)
- }
-}
diff --git a/vendor/tracing-subscriber/src/filter/mod.rs b/vendor/tracing-subscriber/src/filter/mod.rs
deleted file mode 100644
index 000a27195..000000000
--- a/vendor/tracing-subscriber/src/filter/mod.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-//! [`Layer`]s that control which spans and events are enabled by the wrapped
-//! subscriber.
-//!
-//! This module contains a number of types that provide implementations of
-//! various strategies for filtering which spans and events are enabled. For
-//! details on filtering spans and events using [`Layer`]s, see the
-//! [`layer` module's documentation].
-//!
-//! [`layer` module's documentation]: crate::layer#filtering-with-layers
-//! [`Layer`]: crate::layer
-mod filter_fn;
-
-feature! {
- #![all(feature = "env-filter", feature = "std")]
- mod env;
- pub use self::env::*;
-}
-
-feature! {
- #![all(feature = "registry", feature = "std")]
- mod layer_filters;
- pub use self::layer_filters::*;
-}
-
-mod level;
-
-pub use self::filter_fn::*;
-pub use self::level::{LevelFilter, ParseError as LevelParseError};
-
-#[cfg(not(all(feature = "registry", feature = "std")))]
-pub(crate) use self::has_plf_stubs::*;
-
-feature! {
- #![any(feature = "std", feature = "alloc")]
- pub mod targets;
- pub use self::targets::Targets;
-
- mod directive;
- pub use self::directive::ParseError;
-}
-
-/// Stub implementations of the per-layer-fitler detection functions for when the
-/// `registry` feature is disabled.
-#[cfg(not(all(feature = "registry", feature = "std")))]
-mod has_plf_stubs {
- pub(crate) fn is_plf_downcast_marker(_: core::any::TypeId) -> bool {
- false
- }
-
- /// Does a type implementing `Subscriber` contain any per-layer filters?
- pub(crate) fn subscriber_has_plf<S>(_: &S) -> bool
- where
- S: tracing_core::Subscriber,
- {
- false
- }
-
- /// Does a type implementing `Layer` contain any per-layer filters?
- pub(crate) fn layer_has_plf<L, S>(_: &L) -> bool
- where
- L: crate::Layer<S>,
- S: tracing_core::Subscriber,
- {
- false
- }
-}
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",
- );
- }
-}