From 055fd2566ad666a49c63b16a6d65fa7fd4133f87 Mon Sep 17 00:00:00 2001 From: Timo Freiberg Date: Fri, 25 Feb 2022 15:26:49 +0100 Subject: [PATCH] subscriber: add Filtered::filter_mut method ## Motivation Changing the filter of a Filtered at runtime is currently only possible by replacing it with a new Filtered via the reload::Handle's reload method. This currently doesn't work (see https://github.com/tokio-rs/tracing/issues/1629). While it would be desirable to just make that work, it would only be possible via a breaking change (according to Eliza). Making it possible to change the filter via the handle's modify method and mutating the inner filter is an easy workaround. --- .../src/filter/layer_filters/mod.rs | 34 +++++++++++++++++++ tracing-subscriber/src/reload.rs | 28 ++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/tracing-subscriber/src/filter/layer_filters/mod.rs b/tracing-subscriber/src/filter/layer_filters/mod.rs index d391d31b22..065d8285eb 100644 --- a/tracing-subscriber/src/filter/layer_filters/mod.rs +++ b/tracing-subscriber/src/filter/layer_filters/mod.rs @@ -470,6 +470,40 @@ impl Filtered { 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, reload_handle) = + /// reload::Layer::new(fmt::Layer::default().with_filter(filter::LevelFilter::WARN)); + /// # + /// # // specifying the Registry type is required + /// # let _: &reload::Handle, + /// # 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 + } } impl Layer for Filtered diff --git a/tracing-subscriber/src/reload.rs b/tracing-subscriber/src/reload.rs index b8ec67dfa7..08b7ead609 100644 --- a/tracing-subscriber/src/reload.rs +++ b/tracing-subscriber/src/reload.rs @@ -36,7 +36,33 @@ pub struct Layer { _s: PhantomData, } -/// Allows reloading the state of an associated `Layer`. +/// Allows reloading the state of an associated [`Layer`](crate::layer::Layer). +/// +/// # Examples +/// +/// Reloading a [`Filtered`](crate::filter::Filtered) layer to change the filter at runtime. +/// +/// ``` +/// # use tracing::info; +/// # use tracing_subscriber::{filter,fmt,reload,Registry,prelude::*}; +/// # fn main() { +/// let (filtered_layer, reload_handle) = +/// reload::Layer::new(fmt::Layer::default().with_filter(filter::LevelFilter::WARN)); +/// # +/// # // specifying the Registry type is required +/// # let _: &reload::Handle, +/// # 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"); +/// # } +/// ``` +/// +/// **Warning:** [`Filtered`](crate::filter::Filtered) can currently only be changed +/// at runtime via the [`modify`] method, not via the [`reload`] method +/// (see https://github.com/tokio-rs/tracing/issues/1629) #[derive(Debug)] pub struct Handle { inner: Weak>,