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

subscriber: filter selection depends on ordering #623

Closed
hawkw opened this issue Mar 5, 2020 · 0 comments · Fixed by #624
Closed

subscriber: filter selection depends on ordering #623

hawkw opened this issue Mar 5, 2020 · 0 comments · Fixed by #624
Assignees
Labels
crate/subscriber Related to the `tracing-subscriber` crate kind/bug Something isn't working

Comments

@hawkw
Copy link
Member

hawkw commented Mar 5, 2020

Bug Report

Version

tracing-subscriber 0.2.2

Crates

tracing-subscriber

Description

from linkerd/linkerd2#4138:

A proxy log level like linkerd=debug,warn does not emit any logs, but warn,linkerd=debug seems to work as intended. This is surprising and, I think, a regression from previous behavior. I would expect it to work as longest-match-wins, ignoring order.

my guess is that either 1e35ce2 or d2489fd broke something. this may also be related to #591

@hawkw hawkw added kind/bug Something isn't working crate/subscriber Related to the `tracing-subscriber` crate labels Mar 5, 2020
@hawkw hawkw self-assigned this Mar 5, 2020
@hawkw hawkw closed this as completed in #624 Mar 5, 2020
hawkw added a commit that referenced this issue Mar 5, 2020
## Motivation

Recent changes to `tracing-subscriber` (#580 and #583) introduced some
regressions in filter directive selection. In particular, directive
selection appears to depend on the _order_ in which directives were
specified in a env filter string, or on the order in which they were
added using `add_directive`, rather than on specificity. 

This regression is due to the change that switched the storage of filter
directives in `DirectiveSet`s from a `BTreeSet` to a `Vec`. Previously,
the `DirectiveSet::add` and `DirectiveSet::extend` methods both relied
on the inherent ordering of `BTreeSet`s. After changing to a `Vec`, the
`DirectiveSet::add` method was changed to use a binary search to find
the correct position for each directive, and use `Vec::insert` to add
the directive at that position. This is correct behavior. However, the
`Extend` (and therefore also `FromIterator`) implementations _did not
use_ `add_directive` --- instead, they simply called `extend` on the
underlying data structure. This was fine previously, when we could rely
on the sorted nature of `BTreeSet`s, but now, it means that when a
directive set is created from an iterator (such as when parsing a string
with multiple filter directives!), the ordering of the directive set is
based on the iterator's ordering, rather than sorted.

We didn't catch this bug because all of our tests happen to put the
least specific directive first. When the change to using a `Vec` broke
all the existing tests, I was able to "fix" them simply by adding a
`.rev()` call to the iterator, based on the incorrect assumption that we
were always using the sorted insertion order, and that the test failures
were simply due to the binary search inserting in the opposite order as
`BTreeSet`. Adding the `.rev()` call caused issue #591, where a
`DirectiveSet` built by calls to `add_directive` (which _does_ obey the
correct sorting) was not selecting the right filters, since we were
reversing the ordering and picking the least specific directive first.

## Solution

I've changed the `DirectiveSet::extend` method to call `self.add` for
each directive in the iterator. Now, they are inserted at the correct
position. I've also removed the call to `.rev()` so that we iterate 
over the correctly sorted `DirectiveSet` in most-specific-first order.

I've added new tests to reproduce both issue #591 and issue #623, and
confirmed that they both fail prior to this change.

Fixes #591
Fixes #623

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crate/subscriber Related to the `tracing-subscriber` crate kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant