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
9pub struct SimpleLogger {
11 level: LevelFilter,
12 config: Config,
13 output_lock: Mutex<()>,
14}
15
16impl SimpleLogger {
17 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 #[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}