-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Impl filter for EnvFilter #1983
Impl filter for EnvFilter #1983
Conversation
I'm not sure about this implementation (especially if |
Can you share the way you've been testing this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a glance, this seems correct. I'd like to figure out why it's not working for you in your tests.
Ideally, can we add integration tests for EnvFilter
's Filter
implementation? We can probably do that by copying these tests: https://github.com/tokio-rs/tracing/blob/v0.1.x/tracing-subscriber/tests/filter.rs and modifying the subscriber to use a mock Layer
wrapped in Filtered
, rather than using a mock Subscriber
. The layer filter tests show how the mock layers are used:
tracing/tracing-subscriber/tests/layer_filters/main.rs
Lines 16 to 38 in f701166
let (trace_layer, trace_handle) = layer::named("trace") | |
.event(event::mock().at_level(Level::TRACE)) | |
.event(event::mock().at_level(Level::DEBUG)) | |
.event(event::mock().at_level(Level::INFO)) | |
.done() | |
.run_with_handle(); | |
let (debug_layer, debug_handle) = layer::named("debug") | |
.event(event::mock().at_level(Level::DEBUG)) | |
.event(event::mock().at_level(Level::INFO)) | |
.done() | |
.run_with_handle(); | |
let (info_layer, info_handle) = layer::named("info") | |
.event(event::mock().at_level(Level::INFO)) | |
.done() | |
.run_with_handle(); | |
let _subscriber = tracing_subscriber::registry() | |
.with(trace_layer.with_filter(LevelFilter::TRACE)) | |
.with(debug_layer.with_filter(LevelFilter::DEBUG)) | |
.with(info_layer.with_filter(LevelFilter::INFO)) | |
.set_default(); |
self.on_new_span(attrs, id) | ||
} | ||
|
||
#[inline] | ||
fn on_enter(&self, id: &span::Id, _: Context<'_, S>) { | ||
self.on_enter(id); | ||
} | ||
|
||
#[inline] | ||
fn on_exit(&self, id: &span::Id, _: Context<'_, S>) { | ||
self.on_exit(id); | ||
} | ||
|
||
#[inline] | ||
fn on_close(&self, id: span::Id, _: Context<'_, S>) { | ||
self.on_close(id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took me a minute to realize that these are not actually recursive because the context isn't passed through. Looks correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I think I'd also be on board with writing all the delegating calls like EnvFilter::method(self, ...)
for consistency
Co-authored-by: Eliza Weisman <[email protected]>
The test is here: https://github.com/tfreiberg-fastly/tracing-envfilter-bug/blob/main/src/main.rs
|
This link is 404 |
Oops, created as private by accident - public now |
I ported the tests to use EnvFilter as a Filter, and had to change the mock configuration for I had to add Also, I'm confused that the first two events in "uncool_span" aren't in both "uncool_span" and "cool_span", is that correct? .in_scope(vec![span::mock().named("uncool_span")])` but like that it fails: .in_scope(vec![span::mock().named("uncool_span"), span::mock().named("cool_span")]) ) |
I think that's just be a difference in behavior between the mock tracing/tracing-subscriber/tests/support.rs Lines 234 to 265 in c6c8097
on the other hand, the test Subscriber implementation doesn't make assertions about the event's expected scope, only the immediate parent span: tracing/tracing/tests/support/event.rs Lines 86 to 118 in 5287e7d
We may want to change this behavior, but I think that, ideally, we would have a way to differentiate between "asserting that there are NO spans in scope" and "not caring about what spans are in scope" --- I believe some of the other per-layer filtering tests actually depend on an empty |
Analogous to the layer::named(...) function, this abbreviates span::mock().named(...)
Alright, that makes sense. I totally agree with your ideas about the different kinds of assertions. I've added another test that currently fails - it seems to fail differently than this one, I am a bit confused about the situation tbh. Alright I read through the "cares about metadata" code and phew, I didn't know that spans aren't recorded if the span target doesn't match the directive. I think I saw a discussion about that in discord once... eh, I guess I'll sleep on it and look at the test with fresh eyes tomorrow :) |
Thanks for adding the failing tests, I'll take a closer look at the code and see if I can figure out what's up! |
...oh, the test is wrong. The directive |
The span is not entered by the layer because it's filtered out
yeah, that seriously confused me 😬 thanks for the explanation! |
## Motivation Filtering by span and field requires using `EnvFilter` rather than `Targets`. Per-subscriber filtering requires the `Filter` trait, which `EnvFilter` does not implement. ## Solution Implement the `Filter` trait for `EnvFilter`. PR #1973 adds additiional methods to the `Filter` trait, which are necessary for `EnvFilter` to implement dynamic span filtering. Now that those methods are added, we can provide a `Filter` impl for `EnvFilter`. In addition, we changed the globally-scoped `thread_local!` macro to use a `ThreadLocal` struct as a field, so that multiple `EnvFilter`s used as per-subscriber filters don't share a single span scope. Fixes #1868 Follow-up on #1973 Co-authored-by: Eliza Weisman <[email protected]>
## Motivation Filtering by span and field requires using `EnvFilter` rather than `Targets`. Per-subscriber filtering requires the `Filter` trait, which `EnvFilter` does not implement. ## Solution Implement the `Filter` trait for `EnvFilter`. PR #1973 adds additiional methods to the `Filter` trait, which are necessary for `EnvFilter` to implement dynamic span filtering. Now that those methods are added, we can provide a `Filter` impl for `EnvFilter`. In addition, we changed the globally-scoped `thread_local!` macro to use a `ThreadLocal` struct as a field, so that multiple `EnvFilter`s used as per-subscriber filters don't share a single span scope. Fixes #1868 Follow-up on #1973 Co-authored-by: Eliza Weisman <[email protected]>
## Motivation Filtering by span and field requires using `EnvFilter` rather than `Targets`. Per-subscriber filtering requires the `Filter` trait, which `EnvFilter` does not implement. ## Solution Implement the `Filter` trait for `EnvFilter`. PR #1973 adds additiional methods to the `Filter` trait, which are necessary for `EnvFilter` to implement dynamic span filtering. Now that those methods are added, we can provide a `Filter` impl for `EnvFilter`. In addition, we changed the globally-scoped `thread_local!` macro to use a `ThreadLocal` struct as a field, so that multiple `EnvFilter`s used as per-subscriber filters don't share a single span scope. Fixes #1868 Follow-up on #1973 Co-authored-by: Eliza Weisman <[email protected]>
) ## Motivation Currently, the `Filtered` type's `Subscribe` impl accidentally calls the inner `Filter`'s `on_enter` hook in the `on_exit` hook. This is...obviously wrong, lol, and means that filters like `EnvFilter` will never consider spans to have exited, breaking filtering behavior. @tfreiberg-fastly originally noticed this bug (see #1983 (comment)), but I wanted to make the change separately from PR #1983 so that we can fix it on the main branch without waiting for #1983 to merge first. ## Solution This branch, uh, you know... fixes that.
## Motivation Filtering by span and field requires using `EnvFilter` rather than `Targets`. Per-subscriber filtering requires the `Filter` trait, which `EnvFilter` does not implement. ## Solution Implement the `Filter` trait for `EnvFilter`. PR #1973 adds additiional methods to the `Filter` trait, which are necessary for `EnvFilter` to implement dynamic span filtering. Now that those methods are added, we can provide a `Filter` impl for `EnvFilter`. In addition, we changed the globally-scoped `thread_local!` macro to use a `ThreadLocal` struct as a field, so that multiple `EnvFilter`s used as per-subscriber filters don't share a single span scope. Fixes #1868 Follow-up on #1973 Co-authored-by: Eliza Weisman <[email protected]>
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([#2035]) - Several documentation fixes and improvements ([#1972], [#1971], [#2023], [#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [#1983]: #1983 [#1973]: #1973 [#2017]: #2017 [#2031]: #2031 [#1959]: #1959 [#2034]: #2034 [#2027]: #2027 [#2026]: #2026 [#2035]: #2035 [#1972]: #1972 [#1971]: #1971 [#2023]: #2023
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([#2035]) - Several documentation fixes and improvements ([#1972], [#1971], [#2023], [#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [#1983]: #1983 [#1973]: #1973 [#2017]: #2017 [#2031]: #2031 [#1959]: #1959 [#2034]: #2034 [#2027]: #2027 [#2026]: #2026 [#2035]: #2035 [#1972]: #1972 [#1971]: #1971 [#2023]: #2023
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([#2035]) - Several documentation fixes and improvements ([#1972], [#1971], [#2023], [#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [#1983]: #1983 [#1973]: #1973 [#2017]: #2017 [#2031]: #2031 [#1959]: #1959 [#2034]: #2034 [#2027]: #2027 [#2026]: #2026 [#2035]: #2035 [#1972]: #1972 [#1971]: #1971 [#2023]: #2023
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([#2035]) - Several documentation fixes and improvements ([#1972], [#1971], [#2023], [#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [#1983]: #1983 [#1973]: #1973 [#2017]: #2017 [#2031]: #2031 [#1959]: #1959 [#2034]: #2034 [#2027]: #2027 [#2026]: #2026 [#2035]: #2035 [#1972]: #1972 [#1971]: #1971 [#2023]: #2023
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([#2035]) - Several documentation fixes and improvements ([#1972], [#1971], [#2023], [#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([#2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [#1983]: #1983 [#1973]: #1973 [#2017]: #2017 [#2031]: #2031 [#1959]: #1959 [#2034]: #2034 [#2027]: #2027 [#2026]: #2026 [#2035]: #2035 [#1972]: #1972 [#1971]: #1971 [#2023]: #2023 [#2025]: #2025 [#2029]: #2029
Just FYI, I don't think it really requires any action, just taking this into account would be fine. TLDR: it turns out adding a new trait impl in Our code lives in a private repo, so I can provide you with only a snippet: This code compiled fine for us with use tracing::*;
use tracing_subscriber::Layer;
// A quirk of tracing-subscriber is that `EnvFilter` is itself a `Layer` impl which filters
// events that match the env filter. Unfortunately these act as global filters, not filters
// specific to each layer, so we have to use this `with_filter` combinator instead
struct EnvFilterAsLayerFilter(tracing_subscriber::EnvFilter);
impl<S: tracing::Subscriber> tracing_subscriber::layer::Filter<S> for EnvFilterAsLayerFilter {
fn enabled(
&self,
meta: &Metadata<'_>,
cx: &tracing_subscriber::layer::Context<'_, S>,
) -> bool {
self.0.enabled(meta, cx.clone())
}
}
let console_layer = tracing_subscriber::fmt::Layer::new()
.json()
.with_writer(std::io::stderr)
.with_filter(EnvFilterAsLayerFilter(console_filter)); The compile error is the following one:
|
Oh, sorry for that :/ In case you haven't already found that out: to keep using the same functionality with minimal changes, you can use both Also, you don't have to use this wrapper anymore, Still, sorry to cause additional work. |
Sure, I understand, that wasn't difficult to fix on our side, and the patch made the code cleaner anyway, thanks for the contribution though! =) |
@Veetaha hmm, the breaking change is certainly unfortunate, I hadn't considered that. Normally, we would consider yanking 0.3.10, publishing a new release with the accidentally breaking change removed, and saving this change for an 0.4. However, in this case, removing the |
This falls under known allowed method resolution breakage. (When the methods have the same content, it would be nice if they could actually be the same item, and not have a conflict...) There is a way to manually prevent an ambiguity error, though: add an inherent impl. |
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Subscribe` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Subscribe` are in scope, the method resolution is ambiguous. See #1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash.
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Subscribe` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Subscribe` are in scope, the method resolution is ambiguous. See #1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash.
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Subscribe` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Subscribe` are in scope, the method resolution is ambiguous. See #1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash. Signed-off-by: Eliza Weisman <[email protected]>
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Layer` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Layer` are in scope, the method resolution is ambiguous. See #1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash. Signed-off-by: Eliza Weisman <[email protected]>
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Layer` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Layer` are in scope, the method resolution is ambiguous. See #1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash. Signed-off-by: Eliza Weisman <[email protected]>
…018) ## Motivation Currently, the `Filtered` type's `Subscribe` impl accidentally calls the inner `Filter`'s `on_enter` hook in the `on_exit` hook. This is...obviously wrong, lol, and means that filters like `EnvFilter` will never consider spans to have exited, breaking filtering behavior. @tfreiberg-fastly originally noticed this bug (see tokio-rs/tracing#1983 (comment)), but I wanted to make the change separately from PR #1983 so that we can fix it on the main branch without waiting for #1983 to merge first. ## Solution This branch, uh, you know... fixes that.
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Subscribe` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Subscribe` are in scope, the method resolution is ambiguous. See tokio-rs/tracing#1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash. Signed-off-by: Eliza Weisman <[email protected]>
…kio-rs#2018) ## Motivation Currently, the `Filtered` type's `Layer` impl accidentally calls the inner `Filter`'s `on_enter` hook in the `on_exit` hook. This is...obviously wrong, lol, and means that filters like `EnvFilter` will never consider spans to have exited, breaking filtering behavior. @tfreiberg-fastly originally noticed this bug (see tokio-rs#1983 (comment)), but I wanted to make the change separately from PR tokio-rs#1983 so that we can fix it on the main branch without waiting for tokio-rs#1983 to merge first. ## Solution This branch, uh, you know... fixes that.
Filtering by span and field requires using `EnvFilter` rather than `Targets`. Per-layer filtering requires the `Filter` trait, which `EnvFilter` does not implement. Implement the `Filter` trait for `EnvFilter`. PR tokio-rs#1973 adds additiional methods to the `Filter` trait, which are necessary for `EnvFilter` to implement dynamic span filtering. Now that those methods are added, we can provide a `Filter` impl for `EnvFilter`. In addition, we changed the globally-scoped `thread_local!` macro to use a `ThreadLocal` struct as a field, so that multiple `EnvFilter`s used as per-layer filters don't share a single span scope. Fixes tokio-rs#1868 Follow-up on tokio-rs#1973 Co-authored-by: Eliza Weisman <[email protected]>
# 0.3.10 (Apr 1, 2022) This release adds several new features, including a `Filter` implementation and new builder API for `EnvFilter`, support for using a `Vec<L> where L: Layer` as a `Layer`, and a number of smaller API improvements to make working with dynamic and reloadable layers easier. ### Added - **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with per-layer filtering ([tokio-rs#1983]) - **registry**: `Filter::on_new_span`, `Filter::on_enter`, `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to allow `Filter`s to track span states internally ([tokio-rs#1973], [tokio-rs#2017], [tokio-rs#2031]) - **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors ([tokio-rs#1959]) - **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow the wrapped `Layer` ([tokio-rs#2034]) - **layer**: Implement `Layer` for `Vec<L: Layer>`, to allow composing together a dynamically sized list of `Layer`s ([tokio-rs#2027]) - **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier ([tokio-rs#2026]) - **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([tokio-rs#2034]) - **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting configuration at runtime ([tokio-rs#2034]) - **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to parsing it ([tokio-rs#2035]) - Several documentation fixes and improvements ([tokio-rs#1972], [tokio-rs#1971], [tokio-rs#2023], [tokio-rs#2023]) ### Fixed - **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type parameter's auto traits ([tokio-rs#2025]) - **env-filter**: Fixed missing help text when the `ansi` feature is disabled ([tokio-rs#2029]) Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for contributing to this release! [tokio-rs#1983]: tokio-rs#1983 [tokio-rs#1973]: tokio-rs#1973 [tokio-rs#2017]: tokio-rs#2017 [tokio-rs#2031]: tokio-rs#2031 [tokio-rs#1959]: tokio-rs#1959 [tokio-rs#2034]: tokio-rs#2034 [tokio-rs#2027]: tokio-rs#2027 [tokio-rs#2026]: tokio-rs#2026 [tokio-rs#2035]: tokio-rs#2035 [tokio-rs#1972]: tokio-rs#1972 [tokio-rs#1971]: tokio-rs#1971 [tokio-rs#2023]: tokio-rs#2023 [tokio-rs#2025]: tokio-rs#2025 [tokio-rs#2029]: tokio-rs#2029
## Motivation Currently, there is a potential namespace resolution issue when calling `EnvFilter` methods that have the same name in the `Filter` and `Layer` traits (such as `enabled` and `max_level_hint`). When both `Filter` and `Layer` are in scope, the method resolution is ambiguous. See tokio-rs#1983 (comment) ## Solution This commit solves the problem by making the inherent method versions of these methods public. When the traits are in scope, name resolution will always select the inherent method prefer`entially, preventing the name clash. Signed-off-by: Eliza Weisman <[email protected]>
Fixes #1868
Follow-up on #1973
Motivation
Filtering by span and field requires using EnvFilter. Per-layer filtering requires the Filter trait.
Solution
Implement the Filter trait for EnvFilter