Skip to content

Commit

Permalink
subscriber: Add Filtered and fmt::Layer accessors (#2034)
Browse files Browse the repository at this point in the history
This adds more modification methods for use with reloading. Replaces
#2032.

## Motivation

I have a `Filtered` layer that I'd like to modify with a reload handle. If
I use `reload` then the filter doesn't work. If I use `modify` with
`filter_mut` I can't update the writer.

## Solution

Adds some additional accessor methods to allow the writer to be modified
in `modify`:

* `Filtered::inner`
* `Filtered::inner_mut`
* `fmt::Layer::writer`
* `fmt::Layer::writer_mut`
* `fmt::Layer::set_ansi`
  • Loading branch information
wagenet authored and hawkw committed Apr 1, 2022
1 parent 9cc9c49 commit bd7755f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
38 changes: 38 additions & 0 deletions tracing-subscriber/src/filter/layer_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,44 @@ impl<L, F, S> Filtered<L, F, S> {
pub fn filter_mut(&mut self) -> &mut F {
&mut self.filter
}

/// Borrows the inner [`Layer`] wrapped by this `Filtered` layer.
pub fn inner(&self) -> &L {
&self.layer
}

/// Mutably borrows the inner [`Layer`] wrapped by this `Filtered` layer.
///
/// This method is primarily expected to 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 non_blocking<T: std::io::Write>(writer: T) -> (fn() -> std::io::Stdout) {
/// # std::io::stdout
/// # }
/// # fn main() {
/// let filtered_layer = fmt::layer().with_writer(non_blocking(std::io::stderr())).with_filter(filter::LevelFilter::INFO);
/// let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer);
/// #
/// # // specifying the Registry type is required
/// # let _: &reload::Handle<filter::Filtered<fmt::Layer<Registry, _, _, fn() -> std::io::Stdout>,
/// # filter::LevelFilter, Registry>, _>
/// # = &reload_handle;
/// #
/// info!("This will be logged to stderr");
/// reload_handle.modify(|layer| *layer.inner_mut().writer_mut() = non_blocking(std::io::stdout()));
/// info!("This will be logged to stdout");
/// # }
/// ```
///
/// [subscriber]: Subscribe
pub fn inner_mut(&mut self) -> &mut L {
&mut self.layer
}
}

impl<S, L, F> Layer<S> for Filtered<L, F, S>
Expand Down
52 changes: 51 additions & 1 deletion tracing-subscriber/src/fmt/fmt_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,57 @@ impl<S, N, E, W> Layer<S, N, E, W> {
}
}

/// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in
/// Borrows the [writer] for this [`Layer`].
///
/// [writer]: MakeWriter
pub fn writer(&self) -> &W {
&self.make_writer
}

/// Mutably borrows the [writer] for this [`Layer`].
///
/// This method is primarily expected to be used with the
/// [`reload::Handle::modify`](crate::reload::Handle::modify) method.
///
/// # Examples
///
/// ```
/// # use tracing::info;
/// # use tracing_subscriber::{fmt,reload,Registry,prelude::*};
/// # fn non_blocking<T: std::io::Write>(writer: T) -> (fn() -> std::io::Stdout) {
/// # std::io::stdout
/// # }
/// # fn main() {
/// let layer = fmt::layer().with_writer(non_blocking(std::io::stderr()));
/// let (layer, reload_handle) = reload::Layer::new(layer);
/// #
/// # // specifying the Registry type is required
/// # let _: &reload::Handle<fmt::Layer<Registry, _, _, _>, Registry> = &reload_handle;
/// #
/// info!("This will be logged to stderr");
/// reload_handle.modify(|layer| *layer.writer_mut() = non_blocking(std::io::stdout()));
/// info!("This will be logged to stdout");
/// # }
/// ```
///
/// [writer]: MakeWriter
pub fn writer_mut(&mut self) -> &mut W {
&mut self.make_writer
}

/// Sets whether this layer should use ANSI terminal formatting
/// escape codes (such as colors).
///
/// This method is primarily expected to be used with the
/// [`reload::Handle::modify`](crate::reload::Handle::modify) method when changing
/// the writer.
#[cfg(feature = "ansi")]
#[cfg_attr(docsrs, doc(cfg(feature = "ansi")))]
pub fn set_ansi(&mut self, ansi: bool) {
self.is_ansi = ansi;
}

/// Configures the layer to support [`libtest`'s output capturing][capturing] when used in
/// unit tests.
///
/// See [`TestWriter`] for additional details.
Expand Down

0 comments on commit bd7755f

Please sign in to comment.