gitwatch_rs/
logger.rs

1use anyhow::Result;
2use fern::{
3    colors::{Color, ColoredLevelConfig},
4    Dispatch,
5};
6use log::Level;
7
8use crate::cli::LogLevel;
9
10pub fn setup_logger(level: LogLevel) -> Result<()> {
11    let filter_level = level.into();
12
13    let colors_line = ColoredLevelConfig::new()
14        .error(Color::Red)
15        .warn(Color::Yellow)
16        // we actually don't need to specify the color for debug and info, they are white by default
17        .info(Color::White)
18        .debug(Color::Cyan)
19        // depending on the terminals color scheme, this is the same as the background color
20        .trace(Color::BrightBlack);
21
22    let base_config = Dispatch::new()
23        .format(move |out, message, record| {
24            let level = &record.level();
25            let color = colors_line.get_color(level).to_fg_str();
26            let color_prefix = format!("\x1B[{color}m");
27            const COLOR_SUFFIX: &str = "\x1B[0m";
28            let level_prefix = if level == &Level::Info {
29                "".to_string()
30            } else {
31                format!("[{level}] ", level = level.to_string().to_lowercase())
32            };
33            out.finish(format_args!(
34                "{color_prefix}{level_prefix}{message}{COLOR_SUFFIX}"
35            ));
36        })
37        .level(filter_level)
38        .level_for("ignore::gitignore", log::LevelFilter::Warn)
39        .level_for("globset", log::LevelFilter::Warn);
40
41    let stdout_config = Dispatch::new()
42        .filter(|metadata| metadata.level() == log::Level::Info)
43        .chain(std::io::stdout());
44
45    let stderr_config = Dispatch::new()
46        .filter(|metadata| metadata.level() != log::Level::Info)
47        .chain(std::io::stderr());
48
49    base_config
50        .chain(stdout_config)
51        .chain(stderr_config)
52        .apply()?;
53
54    Ok(())
55}