xref: /DragonOS/tools/debugging/logmonitor/src/backend/monitor/logset.rs (revision 7b32f5080f42bcbf7d2421013f3ea53c776a063c)
1*7b32f508SLoGin use std::{collections::BTreeMap, fmt::Debug, fs::File, io::Write, path::PathBuf};
2*7b32f508SLoGin 
3*7b32f508SLoGin use log::error;
4*7b32f508SLoGin 
5*7b32f508SLoGin use crate::constant::CMD_ARGS;
6*7b32f508SLoGin 
7*7b32f508SLoGin /// 日志集合
8*7b32f508SLoGin ///
9*7b32f508SLoGin /// 所有的日志都会被存到这个集合中, 以便于进行各种操作
10*7b32f508SLoGin ///
11*7b32f508SLoGin /// 日志集合的后端可以在日志插入前后做一些操作(需要实现[`LogSetBackend`])
12*7b32f508SLoGin #[derive(Debug)]
13*7b32f508SLoGin #[allow(dead_code)]
14*7b32f508SLoGin pub struct LogSet<K, V> {
15*7b32f508SLoGin     inner: BTreeMap<K, V>,
16*7b32f508SLoGin     backend: Box<dyn LogSetBackend<K, V>>,
17*7b32f508SLoGin     name: String,
18*7b32f508SLoGin     file_path: PathBuf,
19*7b32f508SLoGin     log_file: Option<File>,
20*7b32f508SLoGin }
21*7b32f508SLoGin 
22*7b32f508SLoGin #[allow(dead_code)]
23*7b32f508SLoGin impl<K: Ord, V: Clone + PartialEq + Debug> LogSet<K, V> {
new(name: String, backend: Option<Box<dyn LogSetBackend<K, V>>>) -> Self24*7b32f508SLoGin     pub fn new(name: String, backend: Option<Box<dyn LogSetBackend<K, V>>>) -> Self {
25*7b32f508SLoGin         let mut file_path = CMD_ARGS.read().unwrap().as_ref().unwrap().log_dir.clone();
26*7b32f508SLoGin         file_path.push(format!("{}-{}.log", name, std::process::id()));
27*7b32f508SLoGin 
28*7b32f508SLoGin         let log_file = File::create(&file_path).expect("Failed to create log file.");
29*7b32f508SLoGin 
30*7b32f508SLoGin         Self {
31*7b32f508SLoGin             inner: BTreeMap::new(),
32*7b32f508SLoGin             backend: backend.unwrap_or_else(|| Box::new(DefaultBackend::new())),
33*7b32f508SLoGin             name,
34*7b32f508SLoGin             file_path,
35*7b32f508SLoGin             log_file: Some(log_file),
36*7b32f508SLoGin         }
37*7b32f508SLoGin     }
38*7b32f508SLoGin 
insert(&mut self, key: K, value: V)39*7b32f508SLoGin     pub fn insert(&mut self, key: K, value: V) {
40*7b32f508SLoGin         let cloned_value = value.clone();
41*7b32f508SLoGin         self.backend.before_insert(&self.name, &value);
42*7b32f508SLoGin 
43*7b32f508SLoGin         let prev = self.inner.insert(key, value);
44*7b32f508SLoGin         if let Some(prev) = prev {
45*7b32f508SLoGin             if prev.ne(&cloned_value) {
46*7b32f508SLoGin                 error!(
47*7b32f508SLoGin                     "LogSet::insert(): prev != cloned_value: prev: {:?}, cloned_value: {:?}",
48*7b32f508SLoGin                     prev, cloned_value
49*7b32f508SLoGin                 );
50*7b32f508SLoGin             }
51*7b32f508SLoGin         } else {
52*7b32f508SLoGin             self.log_file
53*7b32f508SLoGin                 .as_mut()
54*7b32f508SLoGin                 .map(|f| writeln!(f, "{:?}", cloned_value).ok());
55*7b32f508SLoGin         }
56*7b32f508SLoGin 
57*7b32f508SLoGin         self.backend.after_insert(&self.name, &cloned_value);
58*7b32f508SLoGin     }
59*7b32f508SLoGin 
file_path(&self) -> &PathBuf60*7b32f508SLoGin     pub fn file_path(&self) -> &PathBuf {
61*7b32f508SLoGin         &self.file_path
62*7b32f508SLoGin     }
63*7b32f508SLoGin 
len(&self) -> usize64*7b32f508SLoGin     pub fn len(&self) -> usize {
65*7b32f508SLoGin         self.inner.len()
66*7b32f508SLoGin     }
67*7b32f508SLoGin 
get(&self, key: &K) -> Option<&V>68*7b32f508SLoGin     pub fn get(&self, key: &K) -> Option<&V> {
69*7b32f508SLoGin         self.inner.get(key)
70*7b32f508SLoGin     }
71*7b32f508SLoGin 
get_mut(&mut self, key: &K) -> Option<&mut V>72*7b32f508SLoGin     pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
73*7b32f508SLoGin         self.inner.get_mut(key)
74*7b32f508SLoGin     }
75*7b32f508SLoGin 
remove(&mut self, key: &K) -> Option<V>76*7b32f508SLoGin     pub fn remove(&mut self, key: &K) -> Option<V> {
77*7b32f508SLoGin         self.inner.remove(key)
78*7b32f508SLoGin     }
79*7b32f508SLoGin 
clear(&mut self)80*7b32f508SLoGin     pub fn clear(&mut self) {
81*7b32f508SLoGin         self.inner.clear();
82*7b32f508SLoGin     }
83*7b32f508SLoGin 
iter(&self) -> impl Iterator<Item = (&K, &V)>84*7b32f508SLoGin     pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
85*7b32f508SLoGin         self.inner.iter()
86*7b32f508SLoGin     }
87*7b32f508SLoGin 
contains_key(&self, key: &K) -> bool88*7b32f508SLoGin     pub fn contains_key(&self, key: &K) -> bool {
89*7b32f508SLoGin         self.inner.contains_key(key)
90*7b32f508SLoGin     }
91*7b32f508SLoGin }
92*7b32f508SLoGin 
93*7b32f508SLoGin /// 日志集合的后端, 用于在日志插入前后做一些操作
94*7b32f508SLoGin pub trait LogSetBackend<K, V>: Debug {
before_insert(&mut self, _log_set_name: &str, _log: &V)95*7b32f508SLoGin     fn before_insert(&mut self, _log_set_name: &str, _log: &V) {}
96*7b32f508SLoGin 
after_insert(&mut self, _log_set_name: &str, _log: &V)97*7b32f508SLoGin     fn after_insert(&mut self, _log_set_name: &str, _log: &V) {}
98*7b32f508SLoGin }
99*7b32f508SLoGin 
100*7b32f508SLoGin #[derive(Debug)]
101*7b32f508SLoGin struct DefaultBackend(());
102*7b32f508SLoGin 
103*7b32f508SLoGin impl DefaultBackend {
new() -> Self104*7b32f508SLoGin     pub const fn new() -> Self {
105*7b32f508SLoGin         Self(())
106*7b32f508SLoGin     }
107*7b32f508SLoGin }
108*7b32f508SLoGin 
109*7b32f508SLoGin impl<K, V> LogSetBackend<K, V> for DefaultBackend {
before_insert(&mut self, _log_set_name: &str, _log: &V)110*7b32f508SLoGin     fn before_insert(&mut self, _log_set_name: &str, _log: &V) {}
111*7b32f508SLoGin 
after_insert(&mut self, _log_set_name: &str, _log: &V)112*7b32f508SLoGin     fn after_insert(&mut self, _log_set_name: &str, _log: &V) {}
113*7b32f508SLoGin }
114