Search code examples
rustrust-tracing

possible to avoid giant Handle type signature using rust tracing library?


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)
}

Solution

  • 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.