Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a method to Targets to get the default level #2242

Merged
merged 4 commits into from
Jul 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions tracing-subscriber/src/filter/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,62 @@ impl Targets {
self
}

/// Returns the default level for this filter, if one is set.
///
/// The default level is used to filter any spans or events with targets
/// that do not match any of the configured set of prefixes.
///
hawkw marked this conversation as resolved.
Show resolved Hide resolved
/// The default level can be set for a filter either by using
/// [`with_default`](Self::with_default) or when parsing from a filter string that includes a
/// level without a target (e.g. `"trace"`).
///
/// # Examples
///
/// ```
/// use tracing_subscriber::filter::{LevelFilter, Targets};
///
/// let filter = Targets::new().with_default(LevelFilter::INFO);
/// assert_eq!(filter.default_level(), Some(LevelFilter::INFO));
///
/// let filter: Targets = "info".parse().unwrap();
/// assert_eq!(filter.default_level(), Some(LevelFilter::INFO));
/// ```
///
/// The default level is `None` if no default is set:
///
/// ```
/// use tracing_subscriber::filter::Targets;
///
/// let filter = Targets::new();
/// assert_eq!(filter.default_level(), None);
///
/// let filter: Targets = "my_crate=info".parse().unwrap();
/// assert_eq!(filter.default_level(), None);
/// ```
///
/// Note that an unset default level (`None`) behaves like [`LevelFilter::OFF`] when the filter is
/// used, but it could also be set explicitly which may be useful to distinguish (such as when
/// merging multiple `Targets`).
///
/// ```
/// use tracing_subscriber::filter::{LevelFilter, Targets};
///
/// let filter = Targets::new().with_default(LevelFilter::OFF);
/// assert_eq!(filter.default_level(), Some(LevelFilter::OFF));
///
/// let filter: Targets = "off".parse().unwrap();
/// assert_eq!(filter.default_level(), Some(LevelFilter::OFF));
/// ```
pub fn default_level(&self) -> Option<LevelFilter> {
self.0.directives().into_iter().find_map(|d| {
if d.target.is_none() {
Some(d.level)
} else {
None
}
})
}

/// Returns an iterator over the [target]-[`LevelFilter`] pairs in this filter.
///
/// The order of iteration is undefined.
Expand Down Expand Up @@ -685,6 +741,21 @@ mod tests {
);
}

#[test]
fn targets_default_level() {
let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off");
assert_eq!(filter.default_level(), None);

let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off")
.with_default(LevelFilter::OFF);
assert_eq!(filter.default_level(), Some(LevelFilter::OFF));

let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off")
.with_default(LevelFilter::OFF)
.with_default(LevelFilter::INFO);
assert_eq!(filter.default_level(), Some(LevelFilter::INFO));
}

#[test]
// `println!` is only available with `libstd`.
#[cfg(feature = "std")]
Expand Down