log_analyzer/stores/
processing_store.rs

1use crate::models::{
2    filter::{Filter, FilterAction},
3    format::Format,
4    log_line::LogLine,
5};
6use parking_lot::RwLock;
7
8use rustc_hash::FxHashMap as HashMap;
9
10/// Store holding all the processing information. Format and filter definitions
11pub trait ProcessingStore {
12    /// Add a new format to the store
13    /// * `id`: alias
14    /// * `format`: regex formatting
15    fn add_format(&self, id: String, format: String);
16    /// Get the format data for the requested format alias
17    fn get_format(&self, id: &str) -> Option<String>;
18    /// Get a list of formats
19    fn get_formats(&self) -> Vec<Format>;
20    /// Add a new filter to the store
21    /// * `id`: alias
22    /// * `filter`: log line regex definitions
23    fn add_filter(&self, id: String, filter: LogLine, action: FilterAction, enabled: bool);
24    /// Get a list of filters together with their enabled state
25    fn get_filters(&self) -> Vec<(bool, Filter)>;
26    /// Switch the enabled state for the given filter
27    fn toggle_filter(&self, id: &str);
28}
29pub struct InMemmoryProcessingStore {
30    /// Map of <alias, Regex string>
31    formats: RwLock<HashMap<String, String>>,
32    /// Map of <alias, Filter details>
33    filters: RwLock<HashMap<String, (FilterAction, LogLine, bool)>>,
34}
35
36impl InMemmoryProcessingStore {
37    pub fn new() -> Self {
38        Self {
39            formats: RwLock::new(HashMap::default()),
40            filters: RwLock::new(HashMap::default()),
41        }
42    }
43}
44
45impl Default for InMemmoryProcessingStore {
46    fn default() -> Self {
47        Self::new()
48    }
49}
50
51impl ProcessingStore for InMemmoryProcessingStore {
52    fn add_format(&self, id: String, format: String) {
53        let mut w = self.formats.write();
54        w.insert(id, format);
55    }
56
57    fn get_format(&self, id: &str) -> Option<String> {
58        let r = self.formats.read();
59        r.get(id).cloned()
60    }
61
62    fn get_formats(&self) -> Vec<Format> {
63        let formats_lock = self.formats.read();
64        formats_lock
65            .iter()
66            .map(|(alias, regex)| Format {
67                alias: alias.clone(),
68                regex: regex.clone(),
69            })
70            .collect()
71    }
72
73    fn add_filter(&self, id: String, filter: LogLine, action: FilterAction, enabled: bool) {
74        let mut w = self.filters.write();
75        w.insert(id, (action, filter, enabled));
76    }
77
78    fn get_filters(&self) -> Vec<(bool, Filter)> {
79        let r = self.filters.read();
80
81        let filters = r
82            .iter()
83            .map(|(id, (action, filter, enabled))| {
84                (
85                    *enabled,
86                    Filter {
87                        alias: id.clone(),
88                        action: *action,
89                        filter: filter.clone(),
90                    },
91                )
92            })
93            .collect();
94
95        filters
96    }
97
98    fn toggle_filter(&self, id: &str) {
99        let mut w = self.filters.write();
100        if let Some((_, _, enabled)) = w.get_mut(id) {
101            *enabled = !*enabled
102        }
103    }
104}