Skip to content

Commit

Permalink
subscriber: implement FIlter for reload::Layer (tokio-rs#2159)
Browse files Browse the repository at this point in the history
## Motivation

The `reload` layer doesn't (and can't) implement downcasting correctly,
which breaks certain `Layer`s which require downcasting (such as
`tracing-opentelemetry`'s `OpenTelemetryLayer`).

## Solution

Most usages of `reload` (including mine) are just to change a `Filter`,
so this PR implements `Filter` on the `reload::Layer` type to allow
users to not need to wrap the whole `Filtered` layer. Another advantage
of this is that the common-case critical sections are shortened

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
  • Loading branch information
2 people authored and kaffarell committed May 22, 2024
1 parent 195c9af commit 7503650
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tracing-subscriber/src/filter/layer_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ impl<L, F, S> Filtered<L, F, S> {
/// #
/// # // specifying the Registry type is required
/// # let _: &reload::Handle<filter::Filtered<fmt::Layer<Registry, _, _, fn() -> std::io::Stdout>,
/// # filter::LevelFilter, Registry>, _>
/// # filter::LevelFilter, Registry>, Registry>
/// # = &reload_handle;
/// #
/// info!("This will be logged to stderr");
Expand Down
60 changes: 60 additions & 0 deletions tracing-subscriber/tests/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,63 @@ fn reload_filter() {
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 1);
})
}

#[test]
#[cfg(feature = "registry")]
fn reload_filter() {
struct NopLayer;
impl<S: Subscriber> tracing_subscriber::Layer<S> for NopLayer {
fn register_callsite(&self, _m: &Metadata<'_>) -> Interest {
Interest::sometimes()
}

fn enabled(&self, _m: &Metadata<'_>, _: layer::Context<'_, S>) -> bool {
true
}
}

static FILTER1_CALLS: AtomicUsize = AtomicUsize::new(0);
static FILTER2_CALLS: AtomicUsize = AtomicUsize::new(0);

enum Filter {
One,
Two,
}

impl<S: Subscriber> tracing_subscriber::layer::Filter<S> for Filter {
fn enabled(&self, m: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool {
println!("ENABLED: {:?}", m);
match self {
Filter::One => FILTER1_CALLS.fetch_add(1, Ordering::SeqCst),
Filter::Two => FILTER2_CALLS.fetch_add(1, Ordering::SeqCst),
};
true
}
}
fn event() {
tracing::trace!("my event");
}

let (filter, handle) = Layer::new(Filter::One);

let dispatcher = tracing_core::Dispatch::new(
tracing_subscriber::registry().with(NopLayer.with_filter(filter)),
);

tracing_core::dispatcher::with_default(&dispatcher, || {
assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 0);
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0);

event();

assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1);
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0);

handle.reload(Filter::Two).expect("should reload");

event();

assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1);
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 1);
})
}

0 comments on commit 7503650

Please # to comment.