-
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
ensure the None-layer doesn't override the max-level erroneously #2321
Conversation
1eaa072
to
aed92ac
Compare
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.
overall, this looks good --- i had some tiny nitpicks about the comments.
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.
okay, this basically looks good to me --- i had a few very small nitpicks but they're not particularly important.
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.
left suggestions for potential docs changes, as i'd like to get this one merged soon.
tracing-subscriber/tests/option.rs
Outdated
/// Test that the `None` max level hint only applies if its the only layer | ||
#[test] | ||
fn doesnt_override_none() { | ||
// None means the other layer takes control | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(None)) | ||
.with(None::<LevelFilter>); | ||
assert_eq!(subscriber.max_level_hint(), None); | ||
|
||
// The `None`-returning layer still wins | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(None)) | ||
.with(Some(LevelFilter::ERROR)); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::ERROR)); | ||
|
||
// Check that we aren't doing anything truly wrong | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(Some(LevelFilter::DEBUG))) | ||
.with(None::<LevelFilter>); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); | ||
|
||
// Test that per-subscriber filters aren't affected | ||
|
||
// One layer is None so it "wins" | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(None)) | ||
.with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)); | ||
assert_eq!(subscriber.max_level_hint(), None); | ||
|
||
// The max-levels wins | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(Some(LevelFilter::INFO))) | ||
.with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); | ||
|
||
// Test filter on the other layer | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(Some(LevelFilter::INFO)).with_filter(LevelFilter::DEBUG)) | ||
.with(None::<LevelFilter>); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(None).with_filter(LevelFilter::DEBUG)) | ||
.with(None::<LevelFilter>); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); | ||
|
||
// The `OFF` from `None` over overridden. | ||
let subscriber = tracing_subscriber::registry() | ||
.with(BasicLayer(Some(LevelFilter::INFO))) | ||
.with(None::<LevelFilter>); | ||
assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::INFO)); | ||
} |
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.
i notice all these tests order the layers so that we have another layer, and then a None
. we should probably also have tests that the same cases work when the None
layer is on the inside (e.g., Registry
, None
, BasicLayer
instead of Registry
, BasicLayer
, None
)?
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.
this should make these a little easier to debug
## Motivation Currently, when using the `Layer` impl for `Option<S: Layer<...>>`, the `Layer::max_level_hint` returns `Some(LevelFilter::OFF)`. This was intended to allow totally disabling output in the case where a `Subscriber` is composed entirely of `None` `Layer`s. However, when other `Layer`s *do* exist but return `None` from their `max_level_hint` implementations to indicate that they don't care what the max level is, the presence of a single `None` layer will globally disable everything, which is not the wanted behavior. Fixes #2265 ## Solution This branch introduces a special downcast marker that can be used to detect when a `Layer` in a `Layered` is `None`. This allows the `pick_level_hint` method to short-circuit when a `Layer` implementation which is `None` returns `Some(LevelFilter::OFF)` from its `max_level_hint` if the other half of the `Layered` is not `None`. The tests I added should be pretty thorough! Additionally, the downcast marker is special-cased in the `reload` `Layer`. Normally, this `Layer` doesn't support downcasting, but it can in the case of the special marker value. Co-authored-by: Eliza Weisman <eliza@buoyant.io>
## Motivation Currently, when using the `Layer` impl for `Option<S: Layer<...>>`, the `Layer::max_level_hint` returns `Some(LevelFilter::OFF)`. This was intended to allow totally disabling output in the case where a `Subscriber` is composed entirely of `None` `Layer`s. However, when other `Layer`s *do* exist but return `None` from their `max_level_hint` implementations to indicate that they don't care what the max level is, the presence of a single `None` layer will globally disable everything, which is not the wanted behavior. Fixes #2265 ## Solution This branch introduces a special downcast marker that can be used to detect when a `Layer` in a `Layered` is `None`. This allows the `pick_level_hint` method to short-circuit when a `Layer` implementation which is `None` returns `Some(LevelFilter::OFF)` from its `max_level_hint` if the other half of the `Layered` is not `None`. The tests I added should be pretty thorough! Additionally, the downcast marker is special-cased in the `reload` `Layer`. Normally, this `Layer` doesn't support downcasting, but it can in the case of the special marker value. Co-authored-by: Eliza Weisman <eliza@buoyant.io>
# 0.3.16 (October 6, 2022) This release of `tracing-subscriber` fixes a regression introduced in [v0.3.15][subscriber-0.3.15] where `Option::None`'s `Layer` implementation would set the max level hint to `OFF`. In addition, it adds several new APIs, including the `Filter::event_enabled` method for filtering events based on fields values, and the ability to log internal errors that occur when writing a log line. This release also replaces the dependency on the unmaintained [`ansi-term`] crate with the [`nu-ansi-term`] crate, resolving an *informational* security advisory ([RUSTSEC-2021-0139] for [`ansi-term`]'s maintainance status. This increases the minimum supported Rust version (MSRV) to Rust 1.50+, although the crate should still compile for the previous MSRV of Rust 1.49+ when the `ansi` feature is not enabled. ### Fixed - **layer**: `Option::None`'s `Layer` impl always setting the `max_level_hint` to `LevelFilter::OFF` (#2321) - Compilation with `-Z minimal versions` (#2246) - **env-filter**: Clarify that disabled level warnings are emitted by `tracing-subscriber` (#2285) ### Added - **fmt**: Log internal errors to `stderr` if writing a log line fails (#2102) - **fmt**: `FmtLayer::log_internal_errors` and `FmtSubscriber::log_internal_errors` methods for configuring whether internal writer errors are printed to `stderr` (#2102) - **fmt**: `#[must_use]` attributes on builders to warn if a `Subscriber` is configured but not set as the default subscriber (#2239) - **filter**: `Filter::event_enabled` method for filtering an event based on its fields (#2245, #2251) - **filter**: `Targets::default_level` accessor (#2242) ### Changed - **ansi**: Replaced dependency on unmaintained `ansi-term` crate with `nu-ansi-term` ((#2287, fixes informational advisory [RUSTSEC-2021-0139]) - `tracing-core`: updated to [0.1.30][core-0.1.30] - Minimum Supported Rust Version (MSRV) increased to Rust 1.50+ (when the `ansi`) feature flag is enabled (#2287) ### Documented - **fmt**: Correct inaccuracies in `fmt::init` documentation (#2224) - **filter**: Fix incorrect doc link in `filter::Not` combinator (#2249) Thanks to new contributors @cgbur, @DesmondWillowbrook, @RalfJung, and @poliorcetics, as well as returning contributors @CAD97, @connec, @jswrenn, @guswynn, and @bryangarza, for contributing to this release! [nu-ansi-term]: https://github.com/nushell/nu-ansi-term [ansi_term]: https://github.com/ogham/rust-ansi-term [RUSTSEC-2021-0139]: https://rustsec.org/advisories/RUSTSEC-2021-0139.html [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [subscriber-0.3.15]: https://github.com/tokio-rs/tracing/releases/tag/tracing-subscriber-0.3.15
# 0.3.16 (October 6, 2022) This release of `tracing-subscriber` fixes a regression introduced in [v0.3.15][subscriber-0.3.15] where `Option::None`'s `Layer` implementation would set the max level hint to `OFF`. In addition, it adds several new APIs, including the `Filter::event_enabled` method for filtering events based on fields values, and the ability to log internal errors that occur when writing a log line. This release also replaces the dependency on the unmaintained [`ansi-term`] crate with the [`nu-ansi-term`] crate, resolving an *informational* security advisory ([RUSTSEC-2021-0139] for [`ansi-term`]'s maintainance status. This increases the minimum supported Rust version (MSRV) to Rust 1.50+, although the crate should still compile for the previous MSRV of Rust 1.49+ when the `ansi` feature is not enabled. ### Fixed - **layer**: `Option::None`'s `Layer` impl always setting the `max_level_hint` to `LevelFilter::OFF` (#2321) - Compilation with `-Z minimal versions` (#2246) - **env-filter**: Clarify that disabled level warnings are emitted by `tracing-subscriber` (#2285) ### Added - **fmt**: Log internal errors to `stderr` if writing a log line fails (#2102) - **fmt**: `FmtLayer::log_internal_errors` and `FmtSubscriber::log_internal_errors` methods for configuring whether internal writer errors are printed to `stderr` (#2102) - **fmt**: `#[must_use]` attributes on builders to warn if a `Subscriber` is configured but not set as the default subscriber (#2239) - **filter**: `Filter::event_enabled` method for filtering an event based on its fields (#2245, #2251) - **filter**: `Targets::default_level` accessor (#2242) ### Changed - **ansi**: Replaced dependency on unmaintained `ansi-term` crate with `nu-ansi-term` ((#2287, fixes informational advisory [RUSTSEC-2021-0139]) - `tracing-core`: updated to [0.1.30][core-0.1.30] - Minimum Supported Rust Version (MSRV) increased to Rust 1.50+ (when the `ansi`) feature flag is enabled (#2287) ### Documented - **fmt**: Correct inaccuracies in `fmt::init` documentation (#2224) - **filter**: Fix incorrect doc link in `filter::Not` combinator (#2249) Thanks to new contributors @cgbur, @DesmondWillowbrook, @RalfJung, and @poliorcetics, as well as returning contributors @CAD97, @connec, @jswrenn, @guswynn, and @bryangarza, for contributing to this release! [nu-ansi-term]: https://github.com/nushell/nu-ansi-term [ansi_term]: https://github.com/ogham/rust-ansi-term [RUSTSEC-2021-0139]: https://rustsec.org/advisories/RUSTSEC-2021-0139.html [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [subscriber-0.3.15]: https://github.com/tokio-rs/tracing/releases/tag/tracing-subscriber-0.3.15
# 0.3.16 (October 6, 2022) This release of `tracing-subscriber` fixes a regression introduced in [v0.3.15][subscriber-0.3.15] where `Option::None`'s `Layer` implementation would set the max level hint to `OFF`. In addition, it adds several new APIs, including the `Filter::event_enabled` method for filtering events based on fields values, and the ability to log internal errors that occur when writing a log line. This release also replaces the dependency on the unmaintained [`ansi-term`] crate with the [`nu-ansi-term`] crate, resolving an *informational* security advisory ([RUSTSEC-2021-0139] for [`ansi-term`]'s maintainance status. This increases the minimum supported Rust version (MSRV) to Rust 1.50+, although the crate should still compile for the previous MSRV of Rust 1.49+ when the `ansi` feature is not enabled. ### Fixed - **layer**: `Option::None`'s `Layer` impl always setting the `max_level_hint` to `LevelFilter::OFF` (#2321) - Compilation with `-Z minimal versions` (#2246) - **env-filter**: Clarify that disabled level warnings are emitted by `tracing-subscriber` (#2285) ### Added - **fmt**: Log internal errors to `stderr` if writing a log line fails (#2102) - **fmt**: `FmtLayer::log_internal_errors` and `FmtSubscriber::log_internal_errors` methods for configuring whether internal writer errors are printed to `stderr` (#2102) - **fmt**: `#[must_use]` attributes on builders to warn if a `Subscriber` is configured but not set as the default subscriber (#2239) - **filter**: `Filter::event_enabled` method for filtering an event based on its fields (#2245, #2251) - **filter**: `Targets::default_level` accessor (#2242) ### Changed - **ansi**: Replaced dependency on unmaintained `ansi-term` crate with `nu-ansi-term` ((#2287, fixes informational advisory [RUSTSEC-2021-0139]) - `tracing-core`: updated to [0.1.30][core-0.1.30] - Minimum Supported Rust Version (MSRV) increased to Rust 1.50+ (when the `ansi`) feature flag is enabled (#2287) ### Documented - **fmt**: Correct inaccuracies in `fmt::init` documentation (#2224) - **filter**: Fix incorrect doc link in `filter::Not` combinator (#2249) Thanks to new contributors @cgbur, @DesmondWillowbrook, @RalfJung, and @poliorcetics, as well as returning contributors @CAD97, @connec, @jswrenn, @guswynn, and @bryangarza, for contributing to this release! [nu-ansi-term]: https://github.com/nushell/nu-ansi-term [ansi_term]: https://github.com/ogham/rust-ansi-term [RUSTSEC-2021-0139]: https://rustsec.org/advisories/RUSTSEC-2021-0139.html [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [subscriber-0.3.15]: https://github.com/tokio-rs/tracing/releases/tag/tracing-subscriber-0.3.15
…s#2321) ## Motivation Currently, when using the `Layer` impl for `Option<S: Layer<...>>`, the `Layer::max_level_hint` returns `Some(LevelFilter::OFF)`. This was intended to allow totally disabling output in the case where a `Subscriber` is composed entirely of `None` `Layer`s. However, when other `Layer`s *do* exist but return `None` from their `max_level_hint` implementations to indicate that they don't care what the max level is, the presence of a single `None` layer will globally disable everything, which is not the wanted behavior. Fixes tokio-rs#2265 ## Solution This branch introduces a special downcast marker that can be used to detect when a `Layer` in a `Layered` is `None`. This allows the `pick_level_hint` method to short-circuit when a `Layer` implementation which is `None` returns `Some(LevelFilter::OFF)` from its `max_level_hint` if the other half of the `Layered` is not `None`. The tests I added should be pretty thorough! Additionally, the downcast marker is special-cased in the `reload` `Layer`. Normally, this `Layer` doesn't support downcasting, but it can in the case of the special marker value. Co-authored-by: Eliza Weisman <eliza@buoyant.io>
# 0.3.16 (October 6, 2022) This release of `tracing-subscriber` fixes a regression introduced in [v0.3.15][subscriber-0.3.15] where `Option::None`'s `Layer` implementation would set the max level hint to `OFF`. In addition, it adds several new APIs, including the `Filter::event_enabled` method for filtering events based on fields values, and the ability to log internal errors that occur when writing a log line. This release also replaces the dependency on the unmaintained [`ansi-term`] crate with the [`nu-ansi-term`] crate, resolving an *informational* security advisory ([RUSTSEC-2021-0139] for [`ansi-term`]'s maintainance status. This increases the minimum supported Rust version (MSRV) to Rust 1.50+, although the crate should still compile for the previous MSRV of Rust 1.49+ when the `ansi` feature is not enabled. ### Fixed - **layer**: `Option::None`'s `Layer` impl always setting the `max_level_hint` to `LevelFilter::OFF` (tokio-rs#2321) - Compilation with `-Z minimal versions` (tokio-rs#2246) - **env-filter**: Clarify that disabled level warnings are emitted by `tracing-subscriber` (tokio-rs#2285) ### Added - **fmt**: Log internal errors to `stderr` if writing a log line fails (tokio-rs#2102) - **fmt**: `FmtLayer::log_internal_errors` and `FmtSubscriber::log_internal_errors` methods for configuring whether internal writer errors are printed to `stderr` (tokio-rs#2102) - **fmt**: `#[must_use]` attributes on builders to warn if a `Subscriber` is configured but not set as the default subscriber (tokio-rs#2239) - **filter**: `Filter::event_enabled` method for filtering an event based on its fields (tokio-rs#2245, tokio-rs#2251) - **filter**: `Targets::default_level` accessor (tokio-rs#2242) ### Changed - **ansi**: Replaced dependency on unmaintained `ansi-term` crate with `nu-ansi-term` ((tokio-rs#2287, fixes informational advisory [RUSTSEC-2021-0139]) - `tracing-core`: updated to [0.1.30][core-0.1.30] - Minimum Supported Rust Version (MSRV) increased to Rust 1.50+ (when the `ansi`) feature flag is enabled (tokio-rs#2287) ### Documented - **fmt**: Correct inaccuracies in `fmt::init` documentation (tokio-rs#2224) - **filter**: Fix incorrect doc link in `filter::Not` combinator (tokio-rs#2249) Thanks to new contributors @cgbur, @DesmondWillowbrook, @RalfJung, and @poliorcetics, as well as returning contributors @CAD97, @connec, @jswrenn, @guswynn, and @bryangarza, for contributing to this release! [nu-ansi-term]: https://github.com/nushell/nu-ansi-term [ansi_term]: https://github.com/ogham/rust-ansi-term [RUSTSEC-2021-0139]: https://rustsec.org/advisories/RUSTSEC-2021-0139.html [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [subscriber-0.3.15]: https://github.com/tokio-rs/tracing/releases/tag/tracing-subscriber-0.3.15
Motivation
Fixes #2265
Solution
Make a special downcast that marks when the layer is a
None
, which allows us to do the short-circuit we want. The tests I added should be pretty thorough!Additionally, make sure this downcast works through the
reload subscriber