Skip to content

Commit

Permalink
subscriber: Add Filtered and fmt::Subscriber 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::Subscriber::writer`
* `fmt::Subscriber::writer_mut`
* `fmt::Subscriber::set_ansi`
  • Loading branch information
wagenet authored Mar 31, 2022
1 parent a3e7944 commit 7d29447
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
43 changes: 41 additions & 2 deletions tracing-subscriber/src/filter/subscriber_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,7 @@ impl<S, F, C> Filtered<S, F, C> {

/// Mutably borrows the [`Filter`](crate::subscribe::Filter) used by this subscriber.
///
/// When this subscriber can be mutably borrowed, this may be used to mutate the filter.
/// Generally, this will primarily be used with the
/// This method is primarily expected to be used with the
/// [`reload::Handle::modify`](crate::reload::Handle::modify) method.
///
/// # Examples
Expand All @@ -499,6 +498,46 @@ impl<S, F, C> Filtered<S, F, C> {
pub fn filter_mut(&mut self) -> &mut F {
&mut self.filter
}

/// Borrows the inner [subscriber] wrapped by this `Filtered` subscriber.
///
/// [subscriber]: Subscribe
pub fn inner(&self) -> &S {
&self.subscriber
}

/// Mutably borrows the inner [subscriber] wrapped by this `Filtered` subscriber.
///
/// 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_subscriber = fmt::subscriber().with_writer(non_blocking(std::io::stderr())).with_filter(filter::LevelFilter::INFO);
/// let (filtered_subscriber, reload_handle) = reload::Subscriber::new(filtered_subscriber);
/// #
/// # // specifying the Registry type is required
/// # let _: &reload::Handle<filter::Filtered<fmt::Subscriber<Registry, _, _, fn() -> std::io::Stdout>,
/// # filter::LevelFilter, Registry>>
/// # = &reload_handle;
/// #
/// info!("This will be logged to stderr");
/// reload_handle.modify(|subscriber| *subscriber.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 S {
&mut self.subscriber
}
}

impl<C, S, F> Subscribe<C> for Filtered<S, F, C>
Expand Down
50 changes: 50 additions & 0 deletions tracing-subscriber/src/fmt/fmt_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,56 @@ impl<C, N, E, W> Subscriber<C, N, E, W> {
}
}

/// Borrows the [writer] for this subscriber.
///
/// [writer]: MakeWriter
pub fn writer(&self) -> &W {
&self.make_writer
}

/// Mutably borrows the [writer] for this subscriber.
///
/// 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 subscriber = fmt::subscriber().with_writer(non_blocking(std::io::stderr()));
/// let (subscriber, reload_handle) = reload::Subscriber::new(subscriber);
/// #
/// # // specifying the Registry type is required
/// # let _: &reload::Handle<fmt::Subscriber<Registry, _, _, _>> = &reload_handle;
/// #
/// info!("This will be logged to stderr");
/// reload_handle.modify(|subscriber| *subscriber.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 subscriber 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 subscriber to support [`libtest`'s output capturing][capturing] when used in
/// unit tests.
///
Expand Down

0 comments on commit 7d29447

Please sign in to comment.