Skip to content

Example usage for SubscriberBuilder::with_filter_reloading and SubscriberBuilder::reload_handle #2682

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
cbeck88 opened this issue Aug 11, 2023 · 2 comments

Comments

@cbeck88
Copy link

cbeck88 commented Aug 11, 2023

Feature Request

Crates

tracing_subscriber 0.3.17

Motivation

A really common thing that people want to do is, use env_filter, and also have the ability to dynamically reload it to change the logging levels without killing the service. Unfortunately, there are no good examples or documentation that speak to this directly.

There is some discussion in several github issues about Layer reloading: #63
#2101

However, these issues are several years old and it looks like some of the code discussed doesn't work anymore.

The documentation for reload module shows some examples: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/reload/index.html

use tracing_subscriber::{filter, fmt, reload, prelude::*};
let filter = filter::LevelFilter::WARN;
let (filter, reload_handle) = reload::Layer::new(filter);
tracing_subscriber::registry()
  .with(filter)
  .with(fmt::Layer::default())
  .init();
info!("This will be ignored");
reload_handle.modify(|filter| *filter = filter::LevelFilter::INFO);
info!("This will be logged");

With explicit reload::Layer::new(), and calling tracing_subscriber::registry, instead of the easier SubscriberBuilder pattern.
Unfortunately this doesn't actually show how it should work for EnvFilter.

There is also a note:

The Layer implementation is unable to implement downcasting functionality, so certain Layer will fail to downcast if wrapped in a reload::Layer.

If you only want to be able to dynamically change the Filter on a layer, prefer wrapping that Filter in the reload::Layer.

It's not immediately clear to me, as a casual user, if this Note impacts me when trying to do this with EnvFilter. In the example, it looks like we are wrapping the Filter in a reload::Layer. But usually when there is an advisory note like this after an example, that means that what I have to actually do is different from the example. So that is somewhat confusing -- it leads to me to think there must be something I'm missing. But after much digging, it doesn't appear that I am missing anything. As a library user, that leaves me with an uneasy feeling.

In documentation, the "easy" SubscriberBuilder seems to have helpers that deal with this reload layer stuff for me:

https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.SubscriberBuilder.html#method.with_filter_reloading
https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.SubscriberBuilder.html#method.reload_handle

Less helpfully, these methods have no example usage in the documentation, or in the examples/ section.

The terse documentation that exists lends itself to confusion. For instance, why do I call two functions, with_filter_reloading and reload_handle, instead of just one that returns the handle? What happens if I only call one of them? There doesn't appear to be an error return path. What happens? Does it panic? Why isn't that documented? Eventually, by studying the trait bounds in the documentation, one gets the idea that errors are supposed to be prevented statically. But it takes a while of staring at SubscriberBuilder<N, E, crate::reload::Layer<crate::EnvFilter, Formatter<N, E, W>>, W> to figure that out, and a new user isn't in a position to quickly grok all the type parameters.

Overall it doesn't feel as approachable as it could be, especially given that there were special APIs created to support this.

Proposal

  • There should be example usage in the docs for SubscriberBuilder::with_filter_reloading and/or SubsciberBuilder::reload_handle.
  • There should be an example binary in examples/ that shows how creating a SubscriberBuilder and getting and using the reload_handle works. For example it could init a builder, and then it could use std::env::set_var and call the reload handle.
  • The documentation in reload module could mention SubscriberBuilder::reload_handle and friends as a possible alternative.

Alternatives

Do nothing I guess.

@jessekrubin
Copy link

jessekrubin commented Aug 9, 2024

Possibly related -- is there a way to do format-reloading?

@Yongle-Fu
Copy link

#2499

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants