Trait tracing_subscriber::filter::FilterExt
source · [−]pub trait FilterExt<S>: Filter<S> {
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,
{ ... }
}
Expand description
Extension trait adding combinators for combining Filter
.
Provided methods
Combines this Filter
with another Filter
s so that spans and
events are enabled if and only if both filters return true
.
Examples
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::*,
};
// Enables spans and events with targets starting with `interesting_target`:
let target_filter = filter_fn(|meta| {
meta.target().starts_with("interesting_target")
});
// Enables spans and events with levels `INFO` and below:
let level_filter = LevelFilter::INFO;
// Combine the two filters together, returning a filter that only enables
// spans and events that *both* filters will enable:
let filter = target_filter.and(level_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
// This event will *not* be enabled:
tracing::info!("an event with an uninteresting target");
// This event *will* be enabled:
tracing::info!(target: "interesting_target", "a very interesting event");
// This event will *not* be enabled:
tracing::debug!(target: "interesting_target", "interesting debug event...");
Combines two Filter
s so that spans and events are enabled if either filter
returns true
.
Examples
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::*,
};
// Enables spans and events with targets starting with `interesting_target`:
let target_filter = filter_fn(|meta| {
meta.target().starts_with("interesting_target")
});
// Enables spans and events with levels `INFO` and below:
let level_filter = LevelFilter::INFO;
// Combine the two filters together so that a span or event is enabled
// if it is at INFO or lower, or if it has a target starting with
// `interesting_target`.
let filter = level_filter.or(target_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
// This event will *not* be enabled:
tracing::debug!("an uninteresting event");
// This event *will* be enabled:
tracing::info!("an uninteresting INFO event");
// This event *will* be enabled:
tracing::info!(target: "interesting_target", "a very interesting event");
// This event *will* be enabled:
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::*,
};
// This filter will enable spans and events with targets beginning with
// `my_crate`:
let my_crate = filter_fn(|meta| {
meta.target().starts_with("my_crate")
});
let filter = my_crate
// Combine the `my_crate` filter with a `LevelFilter` to produce a
// filter that will enable the `INFO` level and lower for spans and
// events with `my_crate` targets:
.and(LevelFilter::INFO)
// If a span or event *doesn't* have a target beginning with
// `my_crate`, enable it if it has the `WARN` level or lower:
.or(LevelFilter::WARN);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
Inverts self
, returning a filter that enables spans and events only if
self
would not enable them.
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.
Examples
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"))
// If `enable_bar_target` is true, add a `filter_fn` enabling
// spans and events with the target `bar`:
.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)
// Boxing the filter erases its type, so both branches now
// have the same type.
.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();