1#![allow(clippy::uninlined_format_args)]
13
14use std::io::Write;
15
16use log::{Level, Metadata, Record};
17
18use irox_time::datetime::UTCDateTime;
19use irox_time::format::iso8601::BASIC_TIME_OF_DAY;
20use irox_tools::ansi_colors::{
21 FORMAT_COLOR_FG_BLUE, FORMAT_COLOR_FG_CYAN, FORMAT_COLOR_FG_MAGENTA, FORMAT_COLOR_FG_RED,
22 FORMAT_COLOR_FG_YELLOW, FORMAT_RESET,
23};
24
25macro_rules! mk_log {
26 ($name:ident, $level:expr) => {
27 pub static $name: ConsoleLogger = ConsoleLogger { max_level: $level };
28 };
29}
30
31mk_log!(ERROR_LOGGER, Level::Error);
32mk_log!(WARN_LOGGER, Level::Warn);
33mk_log!(INFO_LOGGER, Level::Info);
34mk_log!(DEBUG_LOGGER, Level::Debug);
35mk_log!(TRACE_LOGGER, Level::Trace);
36
37pub struct ConsoleLogger {
40 max_level: Level,
41}
42
43impl log::Log for ConsoleLogger {
44 fn enabled(&self, metadata: &Metadata) -> bool {
45 self.max_level >= metadata.level()
46 }
47
48 fn log(&self, record: &Record) {
49 if !self.enabled(record.metadata()) {
50 return;
51 }
52 let level = match record.level() {
53 Level::Error => format!("{}ERROR{}", FORMAT_COLOR_FG_RED, FORMAT_RESET),
54 Level::Warn => format!("{}WARN{FORMAT_RESET}", FORMAT_COLOR_FG_YELLOW),
55 Level::Info => format!("{}INFO{FORMAT_RESET}", FORMAT_COLOR_FG_BLUE),
56 Level::Debug => format!("{}DEBUG{FORMAT_RESET}", FORMAT_COLOR_FG_MAGENTA),
57 Level::Trace => format!("{}TRACE{FORMAT_RESET}", FORMAT_COLOR_FG_CYAN),
58 };
59 let time = UTCDateTime::now().format(&BASIC_TIME_OF_DAY);
60 let thread = std::thread::current();
61 let thread = thread.name().unwrap_or("").split("::").last().unwrap_or("");
62 let module = record
63 .module_path()
64 .unwrap_or("")
65 .split("::")
66 .last()
67 .unwrap_or("");
68 if let Err(_e) = writeln!(
69 std::io::stderr(),
70 "[{time} {level} {thread} {module}] {}",
71 record.args()
72 ) {
73 }
75 }
76
77 fn flush(&self) {
78 let _ign = std::io::stderr().flush();
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use log::*;
85
86 use crate::init_console_level;
87
88 #[test]
89 pub fn test() {
90 init_console_level(Level::Trace);
91
92 error!("Test Error!");
93 warn!("Test Warn!");
94 info!("Test Info!");
95 debug!("Test Debug!");
96 trace!("Test Trace!");
97 }
98}