1 use super::Transform; 2 use crate::{ 3 event::Event, 4 topology::config::{DataType, TransformConfig, TransformContext, TransformDescription}, 5 }; 6 use serde::{Deserialize, Serialize}; 7 use string_cache::DefaultAtom as Atom; 8 9 #[derive(Deserialize, Serialize, Debug)] 10 #[serde(deny_unknown_fields)] 11 pub struct FieldFilterConfig { 12 pub field: String, 13 pub value: String, 14 } 15 16 inventory::submit! { 17 TransformDescription::new_without_default::<FieldFilterConfig>("field_filter") 18 } 19 20 #[typetag::serde(name = "field_filter")] 21 impl TransformConfig for FieldFilterConfig { build(&self, _cx: TransformContext) -> crate::Result<Box<dyn Transform>>22 fn build(&self, _cx: TransformContext) -> crate::Result<Box<dyn Transform>> { 23 warn!( 24 message = 25 r#"The "field_filter" transform is deprecated, use the "filter" transform instead"# 26 ); 27 Ok(Box::new(FieldFilter::new( 28 self.field.clone(), 29 self.value.clone(), 30 ))) 31 } 32 input_type(&self) -> DataType33 fn input_type(&self) -> DataType { 34 DataType::Log 35 } 36 output_type(&self) -> DataType37 fn output_type(&self) -> DataType { 38 DataType::Log 39 } 40 transform_type(&self) -> &'static str41 fn transform_type(&self) -> &'static str { 42 "field_filter" 43 } 44 } 45 46 pub struct FieldFilter { 47 field_name: Atom, 48 value: String, 49 } 50 51 impl FieldFilter { new(field_name: String, value: String) -> Self52 pub fn new(field_name: String, value: String) -> Self { 53 Self { 54 field_name: field_name.into(), 55 value, 56 } 57 } 58 } 59 60 impl Transform for FieldFilter { transform(&mut self, event: Event) -> Option<Event>61 fn transform(&mut self, event: Event) -> Option<Event> { 62 if event 63 .as_log() 64 .get(&self.field_name) 65 .map(|f| f.as_bytes()) 66 .map_or(false, |b| b == self.value.as_bytes()) 67 { 68 Some(event) 69 } else { 70 None 71 } 72 } 73 } 74