diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index 66ca23dc41..bdc72cb496 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -1,4 +1,5 @@ pub(crate) use crate::filter::directive::{FilterVec, ParseError, StaticDirective}; +use crate::filter::env::field::CallsiteMatch; use crate::filter::{ directive::{DirectiveSet, Match}, env::{field, FieldMap}, @@ -33,6 +34,7 @@ pub(crate) type SpanMatcher = MatchSet; pub(crate) struct MatchSet { field_matches: FilterVec, base_level: LevelFilter, + target: Option, } impl Directive { @@ -362,9 +364,19 @@ impl From for Directive { impl Dynamics { pub(crate) fn matcher(&self, metadata: &Metadata<'_>) -> Option { let mut base_level = None; + let mut target = None::; let field_matches = self .directives_for(metadata) .filter_map(|d| { + if let Some(ref matcher_target) = d.target { + match target { + Some(ref inner_target) if inner_target.len() < matcher_target.len() => { + target = Some(matcher_target.clone()) + } + None => target = Some(matcher_target.clone()), + _ => {} + } + } if let Some(f) = d.field_matcher(metadata) { return Some(f); } @@ -381,11 +393,13 @@ impl Dynamics { Some(CallsiteMatcher { field_matches, base_level, + target, }) } else if !field_matches.is_empty() { Some(CallsiteMatcher { field_matches, base_level: base_level.unwrap_or(LevelFilter::OFF), + target, }) } else { None @@ -415,6 +429,7 @@ impl CallsiteMatcher { SpanMatcher { field_matches, base_level: self.base_level, + target: self.target.clone(), } } } @@ -429,6 +444,10 @@ impl SpanMatcher { .unwrap_or(self.base_level) } + pub(crate) fn target(&self) -> Option { + self.target.clone() + } + pub(crate) fn record_update(&self, record: &span::Record<'_>) { for m in &self.field_matches { record.record(&mut m.visitor()) diff --git a/tracing-subscriber/src/filter/env/mod.rs b/tracing-subscriber/src/filter/env/mod.rs index 92f43a1443..f4752021b6 100644 --- a/tracing-subscriber/src/filter/env/mod.rs +++ b/tracing-subscriber/src/filter/env/mod.rs @@ -112,7 +112,7 @@ pub struct EnvFilter { } thread_local! { - static SCOPE: RefCell> = RefCell::new(Vec::new()); + static SCOPE: RefCell)>> = RefCell::new(Vec::new()); } type FieldMap = HashMap; @@ -422,8 +422,13 @@ impl Layer for EnvFilter { } let enabled_by_scope = SCOPE.with(|scope| { - for filter in scope.borrow().iter() { - if filter >= level { + for (filter, target) in scope.borrow().iter() { + if filter >= level + && target + .as_ref() + .map(|target| metadata.target().starts_with(target)) + .unwrap_or(true) + { return true; } } @@ -463,7 +468,7 @@ impl Layer for EnvFilter { // 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) { - SCOPE.with(|scope| scope.borrow_mut().push(span.level())); + SCOPE.with(|scope| scope.borrow_mut().push((span.level(), span.target()))); } }