Skip to content

Add env-filter-explorer example#3233

Merged
hds merged 2 commits intotokio-rs:masterfrom
joshka:jm/env-filter-explorer
May 15, 2025
Merged

Add env-filter-explorer example#3233
hds merged 2 commits intotokio-rs:masterfrom
joshka:jm/env-filter-explorer

Conversation

@joshka
Copy link
Contributor

@joshka joshka commented Mar 12, 2025

Motivation

On discord, Conrad suggested a website to experiment with env-filter syntax. I think a TUI in tree makes a pretty decent replacement, especially as the output can exactly match the output that a real user might see if they're configuring tracing_subscriber with the default values.

Solution

This example demonstrates how to use the tracing-subscriber crate's
EnvFilter type to filter log messages based on their metadata. The
example provides a text area where users can input an environment filter
string, and displays the log messages that would be captured by that
filter.

There are preset filters that can be selected that show off the syntax.

image

@joshka joshka requested review from a team, davidbarsky and hawkw as code owners March 12, 2025 20:59
Copy link
Contributor

@kaffarell kaffarell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, this is very nice! Did not yet look at the code in-depth but noticed one issue: When the envfilter is empty, no event is displayed (this is not correct, every event should be shown). Same on bogus input, e.g., when writing "abc" every event should be visible.

@joshka
Copy link
Contributor Author

joshka commented Apr 10, 2025

This is the result of calling EnvFilterBuilder::parse(). There's nothing more to it than that.

@hds
Copy link
Contributor

hds commented Apr 11, 2025

EDIT: I think I'm wrong about the implementation of this (but right about the docs), that should probably be fixed.

@kaffarell It depends on the default directive, if none is given then ERROR level is set (see https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#method.new).

(This is different from if the env-filter feature isn't enabled at all and fmt::init() is called, in which case all traces are shown)

Copy link
Contributor

@hds hds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome! If we could avoid reformatting unrelated lines in Cargo.toml that would be good though.

tracing-futures = { version = "0.3", path = "../tracing-futures", features = ["futures-01"] }
tracing-attributes = { path = "../tracing-attributes", version = "0.2"}
tracing-log = { path = "../tracing-log", version = "0.2", features = ["env_logger"] }
tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", features = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if we could avoid reformatting. I think this isn't "standard" TOML formatting, it comes from a specific extension.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I use https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml in most projects and often forget to turn it off when viewing other projects. Apologies.

I removed the wrapping changes, but left the spacing changes as they are consistent with the rest of the file. I hope that's ok. If not I can remove those too.

@hds
Copy link
Contributor

hds commented Apr 11, 2025

OK, I wrote a test for the case as per the documentation, and it fails:

#[test]
fn empty_string() {
    let filter: EnvFilter = ""
        .parse()
        .expect("filter should parse");
    let (collector, finished) = collector::mock()
        .event(expect::event().at_level(Level::ERROR))
        .only()
        .run_with_handle();
    let subscriber = collector.with(filter);

    with_default(subscriber, || {
        tracing::trace!("this should be disabled");
        tracing::debug!("this should be disabled");
        tracing::info!("this should be disabled");
        tracing::warn!("this should be disabled");
        tracing::error!("this shouldn't be disabled");
    });

    finished.assert_finished();
}

But it fails because nothing is received by the collector, it's interpreting an empty string as OFF.

@joshka
Copy link
Contributor Author

joshka commented Apr 11, 2025

Intuitively (to me at least), empty should effectively be a noop, which for a filter probably means just default. That said, I have a vague recollection there's a bit of weirdness where if the envfilter feature is not enabled you get info level logs by default, but it changes to error level if enabled. That also seems a bit counterintuitive. (I may be misremembering and I'm not near my computer for a few days to check)

@kaffarell
Copy link
Contributor

kaffarell commented Apr 11, 2025

This is the result of calling EnvFilterBuilder::parse(). There's nothing more to it than that.

Oh you're right, my bad, I tested with EnvFilter::new().

This behavior is kind weird though. We set a default_directive (with min level ERROR) on the new() method, but nowhere else... I think we should remove the default_directive from the new() method – that will make everything more predictable and easy to use. That will be a breaking change though.

This example demonstrates how to use the `tracing-subscriber` crate's
`EnvFilter` type to filter log messages based on their metadata. The
example provides a text area where users can input an environment filter
string, and displays the log messages that would be captured by that
filter.
@joshka joshka force-pushed the jm/env-filter-explorer branch from 6c229d9 to 532a222 Compare May 14, 2025 18:23
@joshka
Copy link
Contributor Author

joshka commented May 14, 2025

Rebased, removed the inferno dep bump, fixed the manifest formatting.
I'm going to make the flow a bit clearer though before it's ready.

@joshka joshka marked this pull request as draft May 14, 2025 20:44
@joshka joshka marked this pull request as ready for review May 14, 2025 22:13
Copy link
Contributor

@hds hds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Thank you!

@hds hds merged commit 906f00c into tokio-rs:master May 15, 2025
56 checks passed
@joshka joshka deleted the jm/env-filter-explorer branch May 15, 2025 17:33
@hds hds mentioned this pull request May 21, 2025
25 tasks
hds pushed a commit that referenced this pull request May 28, 2025
This example demonstrates how to use the `tracing-subscriber` crate's
`EnvFilter` type to filter log messages based on their metadata. The
example provides a text area where users can input an environment filter
string, and displays the log messages that would be captured by that
filter.
hds pushed a commit that referenced this pull request Jun 3, 2025
This example demonstrates how to use the `tracing-subscriber` crate's
`EnvFilter` type to filter log messages based on their metadata. The
example provides a text area where users can input an environment filter
string, and displays the log messages that would be captured by that
filter.
pruthvikar pushed a commit to getcarv/tracing that referenced this pull request Mar 7, 2026
This example demonstrates how to use the `tracing-subscriber` crate's
`EnvFilter` type to filter log messages based on their metadata. The
example provides a text area where users can input an environment filter
string, and displays the log messages that would be captured by that
filter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants