captains_log/
config.rs

1use crate::{file_impl::LoggerSinkFile, formatter::LogFormat, log_impl::LoggerSink};
2use log::{Level, LevelFilter};
3use std::path::Path;
4
5/// Global config to setup logger
6/// See crate::recipe for usage
7
8#[derive(Default)]
9pub struct Builder {
10    /// When dynamic==true,
11    ///   Can safely re-initialize GlobalLogger even it exists,
12    ///   useful to setup different types of logger in test suits.
13    /// When dynamic==false,
14    ///   Only initialize once, logger sinks setting cannot be change afterwards.
15    ///   More efficient for production environment.
16    pub dynamic: bool,
17
18    /// Listen for signal of log-rotate
19    /// NOTE: Once logger started to listen signal, does not support dynamic reconfigure.
20    pub rotation_signals: Vec<i32>,
21
22    /// Hookup to log error when panic
23    pub panic: bool,
24
25    /// Whether to exit program after panic
26    pub continue_when_panic: bool,
27
28    /// Different types of log sink
29    pub sinks: Vec<Box<dyn SinkConfigTrait>>,
30}
31
32impl Builder {
33    pub fn new() -> Self {
34        Self::default()
35    }
36
37    /// Add log-rotate signal
38    pub fn signal(mut self, signal: i32) -> Self {
39        self.rotation_signals.push(signal);
40        self
41    }
42
43    /// Add file sink
44    pub fn file(mut self, config: LogFile) -> Self {
45        self.sinks.push(Box::new(config));
46        self
47    }
48
49    /// Return the max log level in the log sinks
50    pub fn get_max_level(&self) -> LevelFilter {
51        let mut max_level = Level::Error;
52        for sink in &self.sinks {
53            let level = sink.get_level();
54            if level > max_level {
55                max_level = level;
56            }
57        }
58        return max_level.to_level_filter();
59    }
60}
61
62pub trait SinkConfigTrait {
63    fn get_level(&self) -> Level;
64    fn get_file_path(&self) -> Option<Box<Path>>;
65    fn build(&self) -> LoggerSink;
66}
67
68/// Config for file sink
69pub struct LogFile {
70    /// Directory path
71    pub dir: String,
72
73    /// max log level in this file
74    pub level: Level,
75
76    /// filename
77    pub name: String,
78
79    pub(crate) format: LogFormat,
80
81    /// path: dir/name
82    pub file_path: Box<Path>,
83}
84
85impl LogFile {
86    pub fn new(dir: &str, name: &str, level: Level, format: LogFormat) -> Self {
87        let file_path = Path::new(dir).join(Path::new(name)).into_boxed_path();
88        Self { dir: dir.to_string(), name: name.to_string(), level, format, file_path }
89    }
90}
91
92impl SinkConfigTrait for LogFile {
93    fn get_level(&self) -> Level {
94        self.level
95    }
96
97    fn get_file_path(&self) -> Option<Box<Path>> {
98        Some(self.file_path.clone())
99    }
100
101    fn build(&self) -> LoggerSink {
102        LoggerSink::File(LoggerSinkFile::new(self))
103    }
104}