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 .info(Color::White)
18 .debug(Color::Cyan)
19 .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}