Filter multiple fields
This commit is contained in:
parent
6e49d0f849
commit
f720607936
@ -9,13 +9,18 @@ use tracing_subscriber::{
|
||||
registry::{LookupSpan, SpanRef},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct FieldFilter {
|
||||
name: String,
|
||||
value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Filters {
|
||||
filter_target: Option<String>,
|
||||
filter_name: Option<String>,
|
||||
filter_message: Option<String>,
|
||||
filter_field: Option<String>,
|
||||
filter_field_value: Option<String>,
|
||||
filter_fields: Vec<FieldFilter>,
|
||||
}
|
||||
|
||||
impl Filters {
|
||||
@ -24,8 +29,7 @@ impl Filters {
|
||||
filter_target: None,
|
||||
filter_name: None,
|
||||
filter_message: None,
|
||||
filter_field: None,
|
||||
filter_field_value: None,
|
||||
filter_fields: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,13 +49,18 @@ impl Filters {
|
||||
}
|
||||
|
||||
pub fn field(mut self, field: impl ToString) -> Self {
|
||||
self.filter_field = Some(field.to_string());
|
||||
self.filter_fields.push(FieldFilter {
|
||||
name: field.to_string(),
|
||||
value: None,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn field_value(mut self, field: impl ToString, value: impl ToString) -> Self {
|
||||
self.filter_field = Some(field.to_string());
|
||||
self.filter_field_value = Some(value.to_string());
|
||||
self.filter_fields.push(FieldFilter {
|
||||
name: field.to_string(),
|
||||
value: Some(value.to_string()),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
@ -73,7 +82,7 @@ impl Filters {
|
||||
struct TraceListenerVisitor<'a> {
|
||||
filters: &'a Filters,
|
||||
right_message: bool,
|
||||
right_field: bool,
|
||||
right_fields: Vec<bool>,
|
||||
}
|
||||
|
||||
impl<'a> TraceListenerVisitor<'a> {
|
||||
@ -81,13 +90,13 @@ impl<'a> TraceListenerVisitor<'a> {
|
||||
Self {
|
||||
filters,
|
||||
right_message: false,
|
||||
right_field: false,
|
||||
right_fields: vec![false; filters.filter_fields.len()],
|
||||
}
|
||||
}
|
||||
|
||||
fn did_match(&self) -> bool {
|
||||
(self.filters.filter_message.is_none() || self.right_message)
|
||||
&& (self.filters.filter_field.is_none() || self.right_field)
|
||||
&& self.right_fields.iter().all(|right| *right)
|
||||
}
|
||||
}
|
||||
impl<'a> Visit for TraceListenerVisitor<'a> {
|
||||
@ -100,12 +109,17 @@ impl<'a> Visit for TraceListenerVisitor<'a> {
|
||||
self.right_message = true;
|
||||
}
|
||||
}
|
||||
if let Some(filter_field) = &self.filters.filter_field {
|
||||
if field.name() == filter_field {
|
||||
if let Some(filter_field_value) = &self.filters.filter_field_value {
|
||||
self.right_field = &value_str == filter_field_value;
|
||||
for (filter_field, right) in self
|
||||
.filters
|
||||
.filter_fields
|
||||
.iter()
|
||||
.zip(self.right_fields.iter_mut())
|
||||
{
|
||||
if field.name() == filter_field.name {
|
||||
if let Some(filter_field_value) = &filter_field.value {
|
||||
*right = &value_str == filter_field_value;
|
||||
} else {
|
||||
self.right_field = true;
|
||||
*right = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,8 +268,8 @@ impl<S: Subscriber + for<'lookup> LookupSpan<'lookup>> Layer<S> for SpanListener
|
||||
|
||||
mod test {
|
||||
use super::*;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing::info;
|
||||
use tracing_subscriber::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_event_listener() {
|
||||
@ -263,8 +277,7 @@ mod test {
|
||||
let all_listener = EventListener::new(Filters::new().target(std::module_path!()));
|
||||
let msg_listener = EventListener::new(Filters::new().message("filter message"));
|
||||
let field_listener = EventListener::new(Filters::new().field("field"));
|
||||
let field_value_listener =
|
||||
EventListener::new(Filters::new().field_value("field", 1234));
|
||||
let field_value_listener = EventListener::new(Filters::new().field_value("field", 1234));
|
||||
let msg_field_value_listener = EventListener::new(
|
||||
Filters::new()
|
||||
.message("filter message")
|
||||
@ -326,4 +339,42 @@ mod test {
|
||||
assert_eq!(field_value_listener.get_count(), 2);
|
||||
assert_eq!(msg_field_value_listener.get_count(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_fields() {
|
||||
let no_fields = EventListener::new(Filters::new());
|
||||
let one_field = EventListener::new(Filters::new().field("field_one"));
|
||||
let two_fields = EventListener::new(
|
||||
Filters::new()
|
||||
.field("field_one")
|
||||
.field_value("field_two", "123"),
|
||||
);
|
||||
let subscriber = tracing_subscriber::registry()
|
||||
.with(no_fields.clone())
|
||||
.with(one_field.clone())
|
||||
.with(two_fields.clone());
|
||||
let _sub = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
assert_eq!(no_fields.get_count(), 0);
|
||||
assert_eq!(one_field.get_count(), 0);
|
||||
assert_eq!(two_fields.get_count(), 0);
|
||||
|
||||
info!("no fields message");
|
||||
|
||||
assert_eq!(no_fields.get_count(), 1);
|
||||
assert_eq!(one_field.get_count(), 0);
|
||||
assert_eq!(two_fields.get_count(), 0);
|
||||
|
||||
info!(field_one = 123, "one field message");
|
||||
|
||||
assert_eq!(no_fields.get_count(), 2);
|
||||
assert_eq!(one_field.get_count(), 1);
|
||||
assert_eq!(two_fields.get_count(), 0);
|
||||
|
||||
info!(field_one = 123, field_two = 123, "two field message");
|
||||
|
||||
assert_eq!(no_fields.get_count(), 3);
|
||||
assert_eq!(one_field.get_count(), 2);
|
||||
assert_eq!(two_fields.get_count(), 1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user