sp_log2/loggers/
splog.rs

1use super::logging::try_log;
2use crate::{Config, SharedLogger};
3use log::{
4    set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record, SetLoggerError,
5};
6use std::io::{stderr, stdout};
7use std::sync::Mutex;
8
9/// The SimpleLogger struct. Provides a very basic Logger implementation
10pub struct SimpleLogger {
11    level: LevelFilter,
12    config: Config,
13    output_lock: Mutex<()>,
14}
15
16impl SimpleLogger {
17    /// init function. Globally initializes the SimpleLogger as the one and only used log facility.
18    ///
19    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
20    /// Fails if another Logger was already initialized.
21    ///
22    /// # Examples
23    /// ```
24    /// # extern crate sp_log2;
25    /// # use sp_log2::*;
26    /// # fn main() {
27    /// let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
28    /// # }
29    /// ```
30    pub fn init(log_level: LevelFilter, config: Config) -> Result<(), SetLoggerError> {
31        set_max_level(log_level);
32        set_boxed_logger(SimpleLogger::new(log_level, config))
33    }
34
35    /// allows to create a new logger, that can be independently used, no matter what is globally set.
36    ///
37    /// no macros are provided for this case and you probably
38    /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`.
39    ///
40    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
41    ///
42    /// # Examples
43    /// ```
44    /// # extern crate sp_log2;
45    /// # use sp_log2::*;
46    /// # fn main() {
47    /// let simple_logger = SimpleLogger::new(LevelFilter::Info, Config::default());
48    /// # }
49    /// ```
50    #[must_use]
51    pub fn new(log_level: LevelFilter, config: Config) -> Box<SimpleLogger> {
52        Box::new(SimpleLogger {
53            level: log_level,
54            config,
55            output_lock: Mutex::new(()),
56        })
57    }
58}
59
60impl Log for SimpleLogger {
61    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
62        metadata.level() <= self.level
63    }
64
65    fn log(&self, record: &Record<'_>) {
66        if self.enabled(record.metadata()) {
67            let _lock = self.output_lock.lock().unwrap();
68
69            match record.level() {
70                Level::Error => {
71                    let stderr = stderr();
72                    let mut stderr_lock = stderr.lock();
73                    let _ = try_log(&self.config, record, &mut stderr_lock);
74                }
75                _ => {
76                    let stdout = stdout();
77                    let mut stdout_lock = stdout.lock();
78                    let _ = try_log(&self.config, record, &mut stdout_lock);
79                }
80            }
81        }
82    }
83
84    fn flush(&self) {
85        use std::io::Write;
86        let _ = stdout().flush();
87    }
88}
89
90impl SharedLogger for SimpleLogger {
91    fn level(&self) -> LevelFilter {
92        self.level
93    }
94
95    fn config(&self) -> Option<&Config> {
96        Some(&self.config)
97    }
98
99    fn as_log(self: Box<Self>) -> Box<dyn Log> {
100        Box::new(*self)
101    }
102}