pub trait FilterExt<S>: Filter<S> {
// Provided methods
fn and<B>(self, other: B) -> And<Self, B, S> ⓘ
where Self: Sized,
B: Filter<S> { ... }
fn or<B>(self, other: B) -> Or<Self, B, S> ⓘ
where Self: Sized,
B: Filter<S> { ... }
fn not(self) -> Not<Self, S> ⓘ
where Self: Sized { ... }
fn boxed(self) -> Box<dyn Filter<S> + Send + Sync + 'static>
where Self: Sized + Send + Sync + 'static { ... }
}
Available on crate features registry
and std
only.
Extension trait adding combinators for combining Filter
.
Combines this Filter
with another Filter
s so that spans and events are enabled if and only if both filters return true
.
Enabling spans or events if they have both a particular target and are above a certain level:
use tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::*,
};
let target_filter = filter_fn(|meta| {
meta.target().starts_with("interesting_target")
});
let level_filter = LevelFilter::INFO;
let filter = target_filter.and(level_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
tracing::info!("an event with an uninteresting target");
tracing::info!(target: "interesting_target", "a very interesting event");
tracing::debug!(target: "interesting_target", "interesting debug event...");
Source
Combines two Filter
s so that spans and events are enabled if either filter returns true
.
Enabling spans and events at the INFO
level and above, and all spans and events with a particular target:
use tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::*,
};
let target_filter = filter_fn(|meta| {
meta.target().starts_with("interesting_target")
});
let level_filter = LevelFilter::INFO;
let filter = level_filter.or(target_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
tracing::debug!("an uninteresting event");
tracing::info!("an uninteresting INFO event");
tracing::info!(target: "interesting_target", "a very interesting event");
tracing::debug!(target: "interesting_target", "interesting debug event...");
Enabling a higher level for a particular target by using or
in conjunction with the and
combinator:
use tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::*,
};
let my_crate = filter_fn(|meta| {
meta.target().starts_with("my_crate")
});
let filter = my_crate
.and(LevelFilter::INFO)
.or(LevelFilter::WARN);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
Source
Inverts self
, returning a filter that enables spans and events only if self
would not enable them.
This inverts the values returned by the enabled
and callsite_enabled
methods on the wrapped filter; it does not invert event_enabled
, as filters which do not implement filtering on event field values will return the default true
even for events that their enabled
method disables.
Consider a normal filter defined as:
ⓘmatch callsite_enabled() {
ALWAYS => on_span(),
SOMETIMES => if enabled() { on_span() },
NEVER => (),
}
match callsite_enabled() {
ALWAYS => on_event(),
SOMETIMES => if enabled() && event_enabled() { on_event() },
NEVER => (),
}
and an inverted filter defined as:
ⓘmatch callsite_enabled() {
ALWAYS => (),
SOMETIMES => if !enabled() { on_span() },
NEVER => on_span(),
}
match callsite_enabled() {
ALWAYS => (),
SOMETIMES => if !enabled() { on_event() },
NEVER => on_event(),
}
A proper inversion would do !(enabled() && event_enabled())
(or !enabled() || !event_enabled()
), but because of the implicit &&
relation between enabled
and event_enabled
, it is difficult to short circuit and not call the wrapped event_enabled
.
A combinator which remembers the result of enabled
in order to call event_enabled
only when enabled() == true
is possible, but requires additional thread-local mutable state to support a very niche use case.
Boxes self
, erasing its concrete type.
This is equivalent to calling Box::new
, but in method form, so that it can be used when chaining combinator methods.
When different combinations of filters are used conditionally, they may have different types. For example, the following code won’t compile, since the if
and else
clause produce filters of different types:
use tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::*,
};
let enable_bar_target: bool = let filter = if enable_bar_target {
filter_fn(|meta| meta.target().starts_with("foo"))
.or(filter_fn(|meta| meta.target().starts_with("bar")))
.and(LevelFilter::INFO)
} else {
filter_fn(|meta| meta.target().starts_with("foo"))
.and(LevelFilter::INFO)
};
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
By using boxed
, the types of the two different branches can be erased, so the assignment to the filter
variable is valid (as both branches have the type Box<dyn Filter<S> + Send + Sync + 'static>
). The following code does compile:
use tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::*,
};
let enable_bar_target: bool = let filter = if enable_bar_target {
filter_fn(|meta| meta.target().starts_with("foo"))
.or(filter_fn(|meta| meta.target().starts_with("bar")))
.and(LevelFilter::INFO)
.boxed()
} else {
filter_fn(|meta| meta.target().starts_with("foo"))
.and(LevelFilter::INFO)
.boxed()
};
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4