Skip to content

Commit

Permalink
subscriber: add Filtered::filter_mut method
Browse files Browse the repository at this point in the history
 ## 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
#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.
  • Loading branch information
tfreiberg-fastly committed Feb 25, 2022
1 parent 7c00d76 commit 283e773
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
34 changes: 34 additions & 0 deletions tracing-subscriber/src/filter/layer_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,40 @@ impl<L, F, S> Filtered<L, F, S> {
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::Filtered<fmt::Layer<Registry>,
/// # 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<S, L, F> Layer<S> for Filtered<L, F, S>
Expand Down
28 changes: 27 additions & 1 deletion tracing-subscriber/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,33 @@ pub struct Layer<L, S> {
_s: PhantomData<fn(S)>,
}

/// 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::Filtered<fmt::Layer<Registry>,
/// # 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 [`Handle::modify`] method, not via the [`Handle::reload`] method
/// (see <https://github.com/tokio-rs/tracing/issues/1629>)
#[derive(Debug)]
pub struct Handle<L, S> {
inner: Weak<RwLock<L>>,
Expand Down

0 comments on commit 283e773

Please sign in to comment.