Skip to content

Commit

Permalink
subscriber: add Targets::would_enable (#1903
Browse files Browse the repository at this point in the history
## Motivation

As discussed on discord, this API + `Targets` being `: Clone` makes it
easier to solve the original problem I had tried to solve in
#1889.

My plan on how to use this is in
https://github.com/MaterializeInc/materialize/issues/10441 if you are
interested!

## Solution

I considered doing some macro magic to create a `Metadata` with a
callsite and empty fields and everything, to be able to called
`DirectiveSet::enabled`, but it felt cleaner and easier to reason about
the special-case-ness (`Targets` never having field filters) using a new
set of methods that do a similar thing.

For testing I opted for just a doc-test, let me know if thats fine!
  • Loading branch information
guswynn authored and hawkw committed Mar 23, 2022
1 parent b327fc1 commit 13d5e86
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
34 changes: 33 additions & 1 deletion tracing-subscriber/src/filter/directive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloc::{
vec::{self, Vec},
};
use core::{cmp::Ordering, fmt, iter::FromIterator, slice, str::FromStr};
use tracing_core::Metadata;
use tracing_core::{Level, Metadata};
/// Indicates that a string could not be parsed as a filtering directive.
#[derive(Debug)]
pub struct ParseError {
Expand Down Expand Up @@ -142,6 +142,22 @@ impl DirectiveSet<StaticDirective> {
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 ===
Expand All @@ -158,6 +174,22 @@ impl StaticDirective {
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 {
Expand Down
31 changes: 30 additions & 1 deletion tracing-subscriber/src/filter/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use core::{
slice,
str::FromStr,
};
use tracing_core::{Collect, Interest, Metadata};
use tracing_core::{Collect, Interest, Level, Metadata};

/// A filter that enables or disables spans and events based on their [target]
/// and [level].
Expand Down Expand Up @@ -313,6 +313,35 @@ impl Targets {
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
Expand Down

0 comments on commit 13d5e86

Please sign in to comment.