tracing icon indicating copy to clipboard operation
tracing copied to clipboard

Manually creating a `Directive` for a specific target

Open ten3roberts opened this issue 2 years ago • 4 comments

Feature Request

The ability to manually create a Directive with a target.

It is currently only possible to construct a Directive without a specific target using From<Level>

Crates

  • tracing_subscriber

Motivation

This would allow adding more specific filtering directives to the EnvFilter programmatically, to for example silence chatty crates.

Using Targets is not possible as it only provides a subset of the EnvFilter functionality, as well as not ordering the directives by specificity, using the EnvFilter is preferable.

Proposal

Directive::new().with_target("my_crate");

Alternatives

Using the more limited Targets which allow for add_directive(target, level:

let filter = Targets::new();
filter.extend([("my_crate", Level::INFO]);

if let Ok(env_filter) = std::env::var("RUST_LOG").unwrap_or_default().parse::<tracing_subscriber::filter::Targets>() {
    filter.extend(env_filter.iter());
}

eprintln!("Using filter: {filter:?}");

This doesn't work for RUST_LOG=info since iter only returns for Some(targets), so "general" directives will be missed.

Doing it the other way:

    let mut filter = std::env::var("RUST_LOG").unwrap_or_default().parse::<tracing_subscriber::filter::Targets>().unwrap_or_default();
    filter.extend(([("my_crate", Level::INFO]);

does not work with RUST_LOG="my_crate=debug since the my_crate=info will be ordered before my_crate=debug in the DirectiveSet due to stable sorting.

ten3roberts avatar Mar 14 '23 13:03 ten3roberts

Additionally:

Is there a way to add a directive before the env, as adding them afterwards override, even the existing directive (from env) is more verbose?

Short exerpt from env_logger which perfectly replicates the desired behavior.

        let mut builder = env_logger::builder();
        builder.filter_level(LevelFilter::Info);

        for (level, modules) in MODULES {
            for module in *modules {
                builder.filter_module(module, *level);
            }
        }

        builder.parse_default_env().try_init()?;

ten3roberts avatar Mar 14 '23 13:03 ten3roberts

Would a PR be appreciated?

ten3roberts avatar May 03 '23 07:05 ten3roberts

Would a PR be appreciated?

I would be happy to merge a pull request for programmatically creating directives --- this has been discussed previously a bit in https://github.com/tokio-rs/tracing/issues/404, so you may want to look at that issue as well.

There is also a builder API for env_filter

Additionally:

Is there a way to add a directive before the env, as adding them afterwards override, even the existing directive (from env) is more verbose?

There is already a builder API for EnvFilter, which is used to pre-configure parsing options. We could add the capability to add directives to this builder as well, replicating the env_logger functionality you'd like. I'd be happy to merge a PR for that as well.

hawkw avatar May 03 '23 20:05 hawkw

Alright, that sounds like a good idea

ten3roberts avatar May 04 '23 07:05 ten3roberts