| 
1 | 1 | //! A module to initialize and customize the logger object used in (most) stdout.  | 
2 | 2 | 
  | 
3 |  | -// non-std crates  | 
4 |  | -use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};  | 
 | 3 | +use std::env;  | 
5 | 4 | 
 
  | 
 | 5 | +use anyhow::{Error, Result};  | 
 | 6 | +use colored::{control::set_override, Colorize};  | 
 | 7 | +use log::{Level, LevelFilter, Metadata, Record};  | 
 | 8 | + | 
 | 9 | +#[derive(Default)]  | 
6 | 10 | struct SimpleLogger;  | 
7 | 11 | 
 
  | 
 | 12 | +impl SimpleLogger {  | 
 | 13 | +    fn level_color(level: &Level) -> String {  | 
 | 14 | +        let name = format!("{:>5}", level.as_str().to_uppercase());  | 
 | 15 | +        match level {  | 
 | 16 | +            Level::Error => name.red().bold().to_string(),  | 
 | 17 | +            Level::Warn => name.yellow().bold().to_string(),  | 
 | 18 | +            Level::Info => name.green().bold().to_string(),  | 
 | 19 | +            Level::Debug => name.blue().bold().to_string(),  | 
 | 20 | +            Level::Trace => name.magenta().bold().to_string(),  | 
 | 21 | +        }  | 
 | 22 | +    }  | 
 | 23 | +}  | 
 | 24 | + | 
8 | 25 | impl log::Log for SimpleLogger {  | 
9 | 26 |     fn enabled(&self, metadata: &Metadata) -> bool {  | 
10 |  | -        metadata.level() <= Level::Debug  | 
 | 27 | +        metadata.level() <= log::max_level()  | 
11 | 28 |     }  | 
12 | 29 | 
 
  | 
13 | 30 |     fn log(&self, record: &Record) {  | 
14 |  | -        if self.enabled(record.metadata()) {  | 
15 |  | -            println!("{}: {}", record.level(), record.args());  | 
 | 31 | +        if record.target() == "CI_LOG_GROUPING" {  | 
 | 32 | +            // this log is meant to manipulate a CI workflow's log grouping  | 
 | 33 | +            println!("{}", record.args());  | 
 | 34 | +        } else if self.enabled(record.metadata()) {  | 
 | 35 | +            println!(  | 
 | 36 | +                "[{}]: {}",  | 
 | 37 | +                Self::level_color(&record.level()),  | 
 | 38 | +                record.args()  | 
 | 39 | +            );  | 
16 | 40 |         }  | 
17 | 41 |     }  | 
18 | 42 | 
 
  | 
19 | 43 |     fn flush(&self) {}  | 
20 | 44 | }  | 
21 | 45 | 
 
  | 
22 |  | -/// A private constant to manage the application's logger object.  | 
23 |  | -static LOGGER: SimpleLogger = SimpleLogger;  | 
24 |  | - | 
25 | 46 | /// A function to initialize the private `LOGGER`.  | 
26 | 47 | ///  | 
27 | 48 | /// The logging level defaults to [`LevelFilter::Info`].  | 
28 | 49 | /// Returns a [`SetLoggerError`] if the `LOGGER` is already initialized.  | 
29 |  | -pub fn init() -> Result<(), SetLoggerError> {  | 
30 |  | -    log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info))  | 
31 |  | -}  | 
32 |  | - | 
33 |  | -/// This prints a line to indicate the beginning of a related group of log statements.  | 
34 |  | -///  | 
35 |  | -/// This function may or may not get moved to [crate::rest_api::RestApiClient] trait  | 
36 |  | -/// if/when platforms other than GitHub are supported.  | 
37 |  | -pub fn start_log_group(name: String) {  | 
38 |  | -    println!("::group::{}", name);  | 
39 |  | -}  | 
40 |  | - | 
41 |  | -/// This prints a line to indicate the ending of a related group of log statements.  | 
42 |  | -///  | 
43 |  | -/// This function may or may not get moved to [crate::rest_api::RestApiClient] trait  | 
44 |  | -/// if/when platforms other than GitHub are supported.  | 
45 |  | -pub fn end_log_group() {  | 
46 |  | -    println!("::endgroup::");  | 
 | 50 | +pub fn init() -> Result<()> {  | 
 | 51 | +    let logger: SimpleLogger = SimpleLogger;  | 
 | 52 | +    if matches!(  | 
 | 53 | +        env::var("CPP_LINTER_COLOR").as_deref(),  | 
 | 54 | +        Ok("on" | "1" | "true")  | 
 | 55 | +    ) {  | 
 | 56 | +        set_override(true);  | 
 | 57 | +    }  | 
 | 58 | +    log::set_boxed_logger(Box::new(logger))  | 
 | 59 | +        .map(|()| log::set_max_level(LevelFilter::Info))  | 
 | 60 | +        .map_err(Error::from)  | 
47 | 61 | }  | 
48 | 62 | 
 
  | 
49 | 63 | #[cfg(test)]  | 
50 |  | -mod tests {  | 
51 |  | -    use super::{end_log_group, start_log_group};  | 
 | 64 | +mod test {  | 
 | 65 | +    use std::env;  | 
 | 66 | + | 
 | 67 | +    use super::{init, SimpleLogger};  | 
52 | 68 | 
 
  | 
53 | 69 |     #[test]  | 
54 |  | -    fn issue_log_grouping_stdout() {  | 
55 |  | -        start_log_group(String::from("a dumb test"));  | 
56 |  | -        end_log_group();  | 
 | 70 | +    fn trace_log() {  | 
 | 71 | +        env::set_var("CPP_LINTER_COLOR", "true");  | 
 | 72 | +        init().unwrap_or(());  | 
 | 73 | +        assert!(SimpleLogger::level_color(&log::Level::Trace).contains("TRACE"));  | 
 | 74 | +        log::set_max_level(log::LevelFilter::Trace);  | 
 | 75 | +        log::trace!("A dummy log statement for code coverage");  | 
57 | 76 |     }  | 
58 | 77 | }  | 
0 commit comments