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