1

I have a function that initializes a tracing subscriber, and returns a reloading Handle so that I can dynamically control the log level. The type signature works but is a nightmare (I copy-pasted it in from a compiler error message). Is there a better way to pass around this handle? The example in the tracing docs never names the type https://docs.rs/tracing-subscriber/latest/tracing_subscriber/reload/index.html

fn init_tracing() -> (
    DefaultGuard,
    tracing_subscriber::reload::Handle<
        tracing::level_filters::LevelFilter,
        tracing_subscriber::FmtSubscriber<
            tracing_subscriber::fmt::format::DefaultFields,
            tracing_subscriber::fmt::format::Format<
                tracing_subscriber::fmt::format::Full,
                (),
            >,
            tracing::level_filters::LevelFilter,
            tracing_subscriber::fmt::TestWriter,
        >,
    >,
) {
    let filter = filter::LevelFilter::INFO;
    let (filter, reload_handle) = reload::Layer::new(filter);
    let g = subscriber::set_default(
        fmt()
            .without_time()
            .with_max_level(Level::TRACE)
            .with_span_events(FmtSpan::ENTER)
            .with_target(false)
            .with_test_writer()
            .finish()
            .with(filter),
    );
    (g, reload_handle)
}
ajp
  • 1,723
  • 14
  • 22
  • 1
    Bringing types in-scope instead of specifying the full path would be a good first step. You can try something like `Handle` to condense it even further. – kmdreko Jun 19 '23 at 18:28
  • @kmdreko Bringing types into scope is not always a good idea. For example, I would do that here for `LevelFilter` because it's obvious what it is, but not for `reload::Handle` because `Handle` can mean anything. If this is a logging-specific module, then I might bring `tracing_subscriber::reload` into the scope, and specify it as `reload::Handle`. – Chayim Friedman Jun 19 '23 at 18:35
  • @kmdreko that doesn't seem to work - the `Layer` trait requires type parameters – ajp Jun 19 '23 at 21:01
  • @ajp That's what I get for half-@$$ing my suggestions, which is fine because Chayim is right that the actual `L` type is needed anyway in order to practically use the handle. I do recommend `impl Subscriber` over `impl Sized` simply because it is more descriptive to anyone reading your code, even if the constraint isn't actually needed; `impl Sized` just looks weird :) – kmdreko Jun 19 '23 at 21:28

1 Answers1

0

Since there is nothing you can do with the subscriber parameter of reload::Handle anyway, and it is there just because the type needs it, you can abstract it away:

fn init_tracing() -> (
    DefaultGuard,
    tracing_subscriber::reload::Handle<tracing::level_filters::LevelFilter, impl Sized>,
) {
    // ...
}

You cannot abstract away the filter, sadly, since you need to know its type to modify it.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77