-
Notifications
You must be signed in to change notification settings - Fork 844
Add Subscribe::event_enabled to conditionally dis/enable events based on fields #2008
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
Conversation
|
I'm on board with adding this. I think it makes sense to add the ability to filter out an event after its fields are recorded, people have definitely asked for this in the past. In addition to the use-case of filtering based on fields, it would also help with something else I've heard some demand for --- rate limiting event instances based on their fields, so that an event is rate-limited only if it's recorded multiple times with the same field values. The one thing I would note that's important to document is that this method is going to behave differently from
I think this makes sense, as it would also allow us to add this API without a breaking change. Since we don't really expect user code to call |
22dc571 to
ad609d5
Compare
|
This now uses a design where events are separately checked for The one downside I see to this design is that there might be a layer which could fuse some work between This PR is now ready for review to merge. |
|
Interesting alternative solution: just add EDIT: wait, no, |
ad609d5 to
fde00c9
Compare
|
Rebased. I'd appreciate if this could move forward, as it has implications for my tracing-filter work. |
hawkw
left a comment
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'd definitely like to move forward with this change, as well!
The current API proposal seems good to me --- @davidbarsky, want to weigh in?
I think the next step will be actually implementing the intended behavior (i.e. actually calling event_enabled and skipping events based on it). IMO, the current API design seems good and we can go ahead and start on actually implementing it.
We may also want to consider adding similar functionality to Filter, to allow a per-subscriber filter to disable recording an event for its attached subscriber based on field values, but that can be done in a follow-up change.
Whoops, that was there in ad609d5 but got lost in the rebase 😅 It should be back now! I also added some trait-level docs that should help clarify the relationship between the three filtering methods. |
6968e3c to
40db607
Compare
hawkw
left a comment
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.
One thing that I think we need to figure out is that, unlike enabled, the event_enabled method is order-dependent. If a subscriber returns false in event_enabled, any subscribers above it in the stack will still have recorded the event.
Ideally, I think we would want to change this to behave like enabled does, which it looks like we've made a partial attempt to do: the implementation of event_enabled for Layered is non-order-dependent...when a Layered consists of two Subscribers. However, in most cases, a Layered consists of a Subscriber and a Collector, which may itself be a Layered.
Since we don't have an event_enabled method for Collect, Layered's Collect implementation doesn't continue asking the rest of the stack before returning true or false, so the non-order-dependent behavior only exists when subscribers are composed individually before being layered onto a Collector.
This seems unfortunate. We should try to have consistent behavior here.
I think that if we want to make event_enabled non-order-dependent, we would need to also add an event_enabled method to the Collect trait. This could have a default impl that returns true, so it wouldn't be a breaking change to add this in v0.1.x. This would allow the Collect impl for Layered to behave the same as the Subscribe impl for Layered.
Alternatively, we could just decide that we are okay with order-dependent behavior for event_enabled, and change the Subscribe impl for Layered to match. However, this seems not great, because it's inconsistent with all the rest of the filtering methods...
|
Honestly, I just hadn't realized that it was still order-dependent; the point of I'm not super happy with the docs -- it's kind of weird to talk about The other thing that should be added is a test that this commit fixes, but I'm completely unsure how to go about structuring such a test. |
d9591bd to
53ed1dc
Compare
hawkw
left a comment
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, the code change change looks good to me, thanks for working on this! i had some minor suggestions for the documentation, but once those are addressed, i'll be very happy to merge this!
| /// | ||
| /// # Enabling interest | ||
| /// | ||
| /// Whenever an tracing event (or span) is emitted, it goes through a number of |
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.
might be nice if "event" and "span" linked to the tracing docs, but it's not a big deal --- people reading this documentation probably know what those are by now.
|
also, @davidbarsky, do you also want to take a look at the docs change in this PR? no pressure either way! |
|
i think you got most of concerns :) |
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
e065edb to
f5f1758
Compare
hawkw
left a comment
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 looks good to me overall. i left a couple last suggestions, but i'm happy to merge the PR regardless.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
hawkw
left a comment
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.
thanks for the additional tests, this looks good to me!
|
Ugh, the CI failure is unrelated and is due to another crate's dependency changing its MSRV: https://github.com/tokio-rs/tracing/runs/6990243761?check_suite_focus=true I'll fix that separately. |
## Motivation Allow filter layers to filter on the contents of events (see #2007). ## Solution This branch adds a new `Subscriber::event_enabled` method, taking an `Event` and returning `bool`. This is called before the `Subscriber::event` method, and if it returns `false`, `Subscriber::event` is not called. For simple subscriber (e.g. not using `Layer`s), the `event_enabled` method is not particulary necessary, as the subscriber can just skip the `event` call. However, this branch also adds a new `Layer::event_enabled` method, with the signature: ```rust fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool; ``` This is called before `Layer::on_event`, and if `event_enabled` returns `false`, `on_event` is not called (nor is `Subscriber::event`). This allows filter `Layer`s to filter out an `Event` based on its fields. Closes #2007
## Motivation Allow filter layers to filter on the contents of events (see #2007). ## Solution This branch adds a new `Subscriber::event_enabled` method, taking an `Event` and returning `bool`. This is called before the `Subscriber::event` method, and if it returns `false`, `Subscriber::event` is not called. For simple subscriber (e.g. not using `Layer`s), the `event_enabled` method is not particulary necessary, as the subscriber can just skip the `event` call. However, this branch also adds a new `Layer::event_enabled` method, with the signature: ```rust fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool; ``` This is called before `Layer::on_event`, and if `event_enabled` returns `false`, `on_event` is not called (nor is `Subscriber::event`). This allows filter `Layer`s to filter out an `Event` based on its fields. Closes #2007
## Motivation Allow filter layers to filter on the contents of events (see #2007). ## Solution This branch adds a new `Subscriber::event_enabled` method, taking an `Event` and returning `bool`. This is called before the `Subscriber::event` method, and if it returns `false`, `Subscriber::event` is not called. For simple subscriber (e.g. not using `Layer`s), the `event_enabled` method is not particulary necessary, as the subscriber can just skip the `event` call. However, this branch also adds a new `Layer::event_enabled` method, with the signature: ```rust fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool; ``` This is called before `Layer::on_event`, and if `event_enabled` returns `false`, `on_event` is not called (nor is `Subscriber::event`). This allows filter `Layer`s to filter out an `Event` based on its fields. Closes #2007
## Motivation Allow filter layers to filter on the contents of events (see #2007). ## Solution This branch adds a new `Subscriber::event_enabled` method, taking an `Event` and returning `bool`. This is called before the `Subscriber::event` method, and if it returns `false`, `Subscriber::event` is not called. For simple subscriber (e.g. not using `Layer`s), the `event_enabled` method is not particulary necessary, as the subscriber can just skip the `event` call. However, this branch also adds a new `Layer::event_enabled` method, with the signature: ```rust fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool; ``` This is called before `Layer::on_event`, and if `event_enabled` returns `false`, `on_event` is not called (nor is `Subscriber::event`). This allows filter `Layer`s to filter out an `Event` based on its fields. Closes #2007
# 0.1.28 (June 23, 2022) This release of `tracing-core` adds new `Value` implementations, including one for `String`, to allow recording `&String` as a value without having to call `as_str()` or similar, and for 128-bit integers (`i128` and `u128`). In addition, it adds new methods and trait implementations for `Subscriber`s. ### Added - `Value` implementation for `String` ([#2164]) - `Value` implementation for `u128` and `i28` ([#2166]) - `downcast_ref` and `is` methods for `dyn Subscriber + Sync`, `dyn Subscriber + Send`, and `dyn Subscriber + Send + Sync` ([#2160]) - `Subscriber::event_enabled` method to enable filtering based on `Event` field values ([#2008]) - `Subscriber` implementation for `Box<S: Subscriber + ?Sized>` and `Arc<S: Subscriber + ?Sized>` ([#2161]) Thanks to @jswrenn and @CAD97 for contributing to this release! [#2164]: #2164 [#2166]: #2166 [#2160]: #2160 [#2008]: #2008 [#2161]: #2161
# 0.1.28 (June 23, 2022) This release of `tracing-core` adds new `Value` implementations, including one for `String`, to allow recording `&String` as a value without having to call `as_str()` or similar, and for 128-bit integers (`i128` and `u128`). In addition, it adds new methods and trait implementations for `Subscriber`s. ### Added - `Value` implementation for `String` ([#2164]) - `Value` implementation for `u128` and `i28` ([#2166]) - `downcast_ref` and `is` methods for `dyn Subscriber + Sync`, `dyn Subscriber + Send`, and `dyn Subscriber + Send + Sync` ([#2160]) - `Subscriber::event_enabled` method to enable filtering based on `Event` field values ([#2008]) - `Subscriber` implementation for `Box<S: Subscriber + ?Sized>` and `Arc<S: Subscriber + ?Sized>` ([#2161]) Thanks to @jswrenn and @CAD97 for contributing to this release! [#2164]: #2164 [#2166]: #2166 [#2160]: #2160 [#2008]: #2008 [#2161]: #2161
# 0.3.12 (Jun 29, 2022) This release of `tracing-subscriber` adds a new `Layer::event_enabled` method, which allows `Layer`s to filter events *after* their field values are recorded; a `Filter` implementation for `reload::Layer`, to make using `reload` with per-layer filtering more ergonomic, and additional inherent method downcasting APIs for the `Layered` type. In addition, it includes dependency updates, and minor fixes for documentation and feature flagging. ### Added - **layer**: `Layer::event_enabled` method, which can be implemented to filter events based on their field values (#2008) - **reload**: `Filter` implementation for `reload::Layer` (#2159) - **layer**: `Layered::downcast_ref` and `Layered::is` inherent methods (#2160) ### Changed - **parking_lot**: Updated dependency on `parking_lot` to 0.13.0 (#2143) - Replaced `lazy_static` dependency with `once_cell` (#2147) ### Fixed - Don't enable `tracing-core` features by default (#2107) - Several documentation link and typo fixes (#2064, #2068, #2077, #2161, #1088) Thanks to @ben0x539, @jamesmunns, @georgemp, @james7132, @jswrenn, @CAD97, and @guswynn for contributing to this release!
# 0.3.12 (Jun 29, 2022) This release of `tracing-subscriber` adds a new `Layer::event_enabled` method, which allows `Layer`s to filter events *after* their field values are recorded; a `Filter` implementation for `reload::Layer`, to make using `reload` with per-layer filtering more ergonomic, and additional inherent method downcasting APIs for the `Layered` type. In addition, it includes dependency updates, and minor fixes for documentation and feature flagging. ### Added - **layer**: `Layer::event_enabled` method, which can be implemented to filter events based on their field values (#2008) - **reload**: `Filter` implementation for `reload::Layer` (#2159) - **layer**: `Layered::downcast_ref` and `Layered::is` inherent methods (#2160) ### Changed - **parking_lot**: Updated dependency on `parking_lot` to 0.13.0 (#2143) - Replaced `lazy_static` dependency with `once_cell` (#2147) ### Fixed - Don't enable `tracing-core` features by default (#2107) - Several documentation link and typo fixes (#2064, #2068, #2077, #2161, #1088) Thanks to @ben0x539, @jamesmunns, @georgemp, @james7132, @jswrenn, @CAD97, and @guswynn for contributing to this release!
PR #2008 added a new method to the `tracing_core::Subscriber` trait, and modified `tracing-subscriber` to and implement that method. However, that PR did *not* increase the minimum `tracing-core` dependency for the `tracing-subscriber` crate. This means that if a dependent of `tracing-subscriber` updates *only* `tracing-subscriber` dependency version (e.g. by running `cargo update -p tracing-subscriber`), it will not also update its `tracing-core` version to one that contains the new method, and `tracing-subscriber` will fail to compile. This is a common occurence with projects using Dependabot, for example. This commit updates `tracing-subscriber`'s minimum `tracing-core` dep to 0.1.28. Once this merges, I'll release 0.3.13 of `tracing-subscriber` and yank 0.3.12.
## Motivation PR #2008 added a new method to the `tracing_core::Subscriber` trait, and modified `tracing-subscriber` to and implement that method. However, that PR did *not* increase the minimum `tracing-core` dependency for the `tracing-subscriber` crate. This means that if a dependent of `tracing-subscriber` updates *only* `tracing-subscriber` dependency version (e.g. by running `cargo update -p tracing-subscriber`), it will not also update its `tracing-core` version to one that contains the new method, and `tracing-subscriber` will fail to compile. This is a common occurrence with projects using Dependabot, for example. ## Solution This commit updates `tracing-subscriber`'s minimum `tracing-core` dep to 0.1.28. Once this merges, I'll release 0.3.13 of `tracing-subscriber` and yank 0.3.12.
…io-rs#2008) ## Motivation Allow filter layers to filter on the contents of events (see tokio-rs#2007). ## Solution This branch adds a new `Subscriber::event_enabled` method, taking an `Event` and returning `bool`. This is called before the `Subscriber::event` method, and if it returns `false`, `Subscriber::event` is not called. For simple subscriber (e.g. not using `Layer`s), the `event_enabled` method is not particulary necessary, as the subscriber can just skip the `event` call. However, this branch also adds a new `Layer::event_enabled` method, with the signature: ```rust fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool; ``` This is called before `Layer::on_event`, and if `event_enabled` returns `false`, `on_event` is not called (nor is `Subscriber::event`). This allows filter `Layer`s to filter out an `Event` based on its fields. Closes tokio-rs#2007
# 0.1.28 (June 23, 2022) This release of `tracing-core` adds new `Value` implementations, including one for `String`, to allow recording `&String` as a value without having to call `as_str()` or similar, and for 128-bit integers (`i128` and `u128`). In addition, it adds new methods and trait implementations for `Subscriber`s. ### Added - `Value` implementation for `String` ([tokio-rs#2164]) - `Value` implementation for `u128` and `i28` ([tokio-rs#2166]) - `downcast_ref` and `is` methods for `dyn Subscriber + Sync`, `dyn Subscriber + Send`, and `dyn Subscriber + Send + Sync` ([tokio-rs#2160]) - `Subscriber::event_enabled` method to enable filtering based on `Event` field values ([tokio-rs#2008]) - `Subscriber` implementation for `Box<S: Subscriber + ?Sized>` and `Arc<S: Subscriber + ?Sized>` ([tokio-rs#2161]) Thanks to @jswrenn and @CAD97 for contributing to this release! [tokio-rs#2164]: tokio-rs#2164 [tokio-rs#2166]: tokio-rs#2166 [tokio-rs#2160]: tokio-rs#2160 [tokio-rs#2008]: tokio-rs#2008 [tokio-rs#2161]: tokio-rs#2161
# 0.3.12 (Jun 29, 2022) This release of `tracing-subscriber` adds a new `Layer::event_enabled` method, which allows `Layer`s to filter events *after* their field values are recorded; a `Filter` implementation for `reload::Layer`, to make using `reload` with per-layer filtering more ergonomic, and additional inherent method downcasting APIs for the `Layered` type. In addition, it includes dependency updates, and minor fixes for documentation and feature flagging. ### Added - **layer**: `Layer::event_enabled` method, which can be implemented to filter events based on their field values (tokio-rs#2008) - **reload**: `Filter` implementation for `reload::Layer` (tokio-rs#2159) - **layer**: `Layered::downcast_ref` and `Layered::is` inherent methods (tokio-rs#2160) ### Changed - **parking_lot**: Updated dependency on `parking_lot` to 0.13.0 (tokio-rs#2143) - Replaced `lazy_static` dependency with `once_cell` (tokio-rs#2147) ### Fixed - Don't enable `tracing-core` features by default (tokio-rs#2107) - Several documentation link and typo fixes (tokio-rs#2064, tokio-rs#2068, tokio-rs#2077, tokio-rs#2161, tokio-rs#1088) Thanks to @ben0x539, @jamesmunns, @georgemp, @james7132, @jswrenn, @CAD97, and @guswynn for contributing to this release!
Motivation
Allow filter layers to filter on the contents of events (closes #2007).
Solution
Add
Subscribe::event_enabled(&self, event: &Event<'_>, ctx: Context<'_, C>) -> bool;. This is called beforeSubscribe::on_event, and ifevent_enabledreturnsfalse,on_eventis not called (nor isCollect::event).Previously, this PR did
Subscribe::on_eventreturnsControlFlow, and theLayeredsubscriber only continues to callon_eventonControlFlow::Continue.This PR exists mainly as a place for discussion of this potential solution. Looking at this diff, and given that most subscriber layers will want to continue and not break the layering, it might make sense to make this a new method which delegates to on_event by default. Since Layered is the primary way of layering two subscribers together, perhaps the footgun of calling
on_eventrather than "filter_on_event" would not be a big deal in practice?