Skip to content
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

WIP: dynamic filters override static ones #2095

Draft
wants to merge 4 commits into
base: v0.1.x
Choose a base branch
from

Conversation

tfreiberg-fastly
Copy link
Contributor

Motivation

See #1388.
Similar to how more specific static filters can disable things that more general filters would enable (e.g. foo=info,foo::bar=warn), it would be nice if dynamic filters could do something similar (although "more specific" is way harder to define here, but let's maybe try)

Solution

  1. Always evaluate dynamic filters (not just when their max level is high enough to enable the metadata)
  2. If none of the dynamic filters in scope (-> with matching span/fields, right?) enable the metadata, that means it was disabled

@tfreiberg-fastly tfreiberg-fastly requested review from hawkw and a team as code owners April 26, 2022 14:02
@tfreiberg-fastly tfreiberg-fastly marked this pull request as draft April 26, 2022 14:03
@tfreiberg-fastly
Copy link
Contributor Author

The tests currently fail, and all those printlns in there are because the changed EnvFilter::enabled method is not actually called, and I have no idea why.

@hawkw
Copy link
Member

hawkw commented Apr 26, 2022

The tests currently fail, and all those printlns in there are because the changed EnvFilter::enabled method is not actually called, and I have no idea why.

The reason EnvFilter::enabled would not be called is if register_callsite returns Interest::always or Interest::never for a span or event, indicating that enabled does not need to be called every time that span/event occurs. Currently, we always return a cacheable interest for all event callsites:

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
if self.has_dynamics && metadata.is_span() {
// If this metadata describes a span, first, check if there is a
// dynamic filter that should be constructed for it. If so, it
// should always be enabled, since it influences filtering.
if let Some(matcher) = self.dynamics.matcher(metadata) {
let mut by_cs = try_lock!(self.by_cs.write(), else return self.base_interest());
by_cs.insert(metadata.callsite(), matcher);
return Interest::always();
}
}
// Otherwise, check if any of our static filters enable this metadata.
if self.statics.enabled(metadata) {
Interest::always()
} else {
self.base_interest()
}

You would need to change this behavior so that if an EnvFilter has dynamic filters, it will always return Interest::sometimes for any event whose level is below the highest level that any static or dynamic filter would ever enable --- since there's no way to determine statically if a given event might ever occur within a particular span. This, unfortunately, increases the overhead of using dynamic filters, but if we ensure that we still return cacheable interests when only static filters are in use, the performance impact would only occur with dynamic filters.

@tfreiberg-fastly
Copy link
Contributor Author

ah! that makes a lot of sense, thanks for the help :)
yeah I'm not sure if this feature is a good idea, I'd leave that up to you. I wanted to explore it though :)

@tfreiberg-fastly
Copy link
Contributor Author

Cool, it actually seems to work now (at least the tests do)

I tried using directives_for(metadata) here, but that doesn't seem to be possible:
cares_for compares the span name (my_span in the test) with the name of the event metadata (event tracing-subscriber/tests/env_filter/per_layer.rs:327 in the test), so it looks like we can't filter the dynamic directives at all here :/

I think it's still debatable whether this feature should exist and whether this is a good implementation.
This currently gives dynamic filters higher priority over static filters, which is not obviously wrong to me, but I definitely haven't thought through all the implications.
Also this should probably be documented somewhere.

@hawkw
Copy link
Member

hawkw commented Apr 27, 2022

I tried using directives_for(metadata) here, but that doesn't seem to be possible:
cares_for compares the span name (my_span in the test) with the name of the event metadata (event tracing-subscriber/tests/env_filter/per_layer.rs:327 in the test), so it looks like we can't filter the dynamic directives at all here :/

I don't think we want to do that, a dynamic directive will effect any event within a span that matches the directive, so we can't filter the directives in that check. Instead, we just want to check if any dynamic directive would enable the event's level. So, what you've written is correct.

@tfreiberg-fastly
Copy link
Contributor Author

yep, I think I kinda noticed that while I was trying to understand why it doesn't work 😅

Comment on lines +631 to +634
} else if self
.dynamics
.directives()
.any(|directive| directive.level < *metadata.level())
Copy link
Member

Choose a reason for hiding this comment

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

we can simplify this check; self.dynamics has a max_level field, so we can just check if the metadata's level is <= self.dynamics.max_level

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i don't think that does the same thing though?
we need to find at least one filter that would disable the metadata,
the max level being greater means that at least one filter can enable it, right?

Copy link

@SomeoneToIgnore SomeoneToIgnore Jan 11, 2023

Choose a reason for hiding this comment

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

While the proposed simplifications is more appealing to me, I obeserve that both versions work for filters like

info,[{timeline=a6cfe8a1ca34765fd9a432d6193856b2}]=debug,[{timeline=a4273b74e519eb7f2d93b2c6245cd8ec}]=error

in my usecase.

Copy link

@SomeoneToIgnore SomeoneToIgnore left a comment

Choose a reason for hiding this comment

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

Hey @hawkw , @tfreiberg-fastly thank you for working on this feature, this is exactly what I've stumbled onto and would wish to have in the tracing-subscriber 0.3 version, if possible.

Can I help you somehow with the PR to make it happen?

Comment on lines +631 to +634
} else if self
.dynamics
.directives()
.any(|directive| directive.level < *metadata.level())
Copy link

@SomeoneToIgnore SomeoneToIgnore Jan 11, 2023

Choose a reason for hiding this comment

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

While the proposed simplifications is more appealing to me, I obeserve that both versions work for filters like

info,[{timeline=a6cfe8a1ca34765fd9a432d6193856b2}]=debug,[{timeline=a4273b74e519eb7f2d93b2c6245cd8ec}]=error

in my usecase.

SomeoneToIgnore added a commit to neondatabase/tracing that referenced this pull request Jan 13, 2023
Issue tokio-rs#1388

Allow dynamic filters to override statis cones, thus
enabling the possibility to have env filters like
warn,pageserver=info,[{tenant=98d670ab7bee6f0051494306a1ab888f}]=error,[{tenant=19cbf2bf51f42a5a5a90aa8954fb3e42}]=debug
SomeoneToIgnore added a commit to neondatabase/tracing that referenced this pull request Jan 13, 2023
Based on tokio-rs#2095
Issue tokio-rs#1388

Allow dynamic filters to override statis cones, thus
enabling the possibility to have env filters like
warn,pageserver=info,[{tenant=98d670ab7bee6f0051494306a1ab888f}]=error,[{tenant=19cbf2bf51f42a5a5a90aa8954fb3e42}]=debug
@slinkydeveloper
Copy link

Hi all,
same here I would find this PR extremely helpful. Is there something I can do to help complete it?

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.

4 participants