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