use chrono::Local; use std::io::Write; use crate::output::ansi_control::Colorize; /// Simple env logger that prints formatted messages. /// Usage: `env_logger::init_with(EnvLogger { show_time: true, show_level: true });` pub struct EnvLogger { pub show_time: bool, pub show_level: bool, pub level: log::Level, } impl log::Log for EnvLogger { fn enabled(&self, metadata: &log::Metadata) -> bool { metadata.level() <= log::Level::Info } fn log(&self, record: &log::Record) { if !self.enabled(record.metadata()) { return; } let mut buf = Vec::new(); if self.show_time { let now = Local::now().format("%Y-%m-%d %H:%M:%S%.3f"); write!(buf, "[{}] ", now).ok(); } if self.show_level { let level_str = match record.level() { log::Level::Trace => "TRACE".bright_black(), log::Level::Debug => "DEBUG".cyan(), log::Level::Info => "INFO".green(), log::Level::Warn => "WARN".yellow(), log::Level::Error => "ERROR".red(), }; write!(buf, "{}: ", level_str.bold()).ok(); } write!(buf, "{}", record.args()).ok(); eprintln!("{}", String::from_utf8_lossy(&buf)); } fn flush(&self) {} } /// Initialize the env logger with the given configuration. pub fn init_envlogger(config: EnvLogger) { log::set_boxed_logger(Box::new(config)) .map(|()| log::set_max_level(log::LevelFilter::Info)) .ok(); }