Browse Source

Filter multiple fields

drone-volume-cache
Alex Mikhalev 4 years ago
parent
commit
f720607936
  1. 87
      src/trace_listeners.rs

87
src/trace_listeners.rs

@ -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…
Cancel
Save