use colored::Colorize;
use log::Level;
use std::{env, str::FromStr, sync::OnceLock};
#[derive(Clone)]
pub struct Logger;
impl log::Log for Logger {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.level() <= Level::Debug
}
fn log(&self, record: &log::Record) {
if !self.enabled(record.metadata()) {
return;
}
let time = chrono::Local::now()
.format("%Y-%m-%d %H:%M:%S")
.to_string()
.magenta();
let level = match record.level() {
Level::Error => "ERROR".red(),
Level::Warn => "WARN".yellow(),
Level::Info => "INFO".green(),
Level::Debug => "DEBUG".green(),
Level::Trace => "TRACE".green(),
};
let log = format!(
"{} {} {} {} {}",
time,
record.module_path().unwrap_or("unknown").cyan(),
record.target().cyan(),
level,
record.args()
);
println!("{}", log);
}
fn flush(&self) {}
}
static LOGGER: OnceLock<()> = OnceLock::new();
pub fn init_logger() {
if LOGGER.get().is_some() {
return;
}
LOGGER.get_or_init(|| {
let level = env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
let level = log::Level::from_str(&level).unwrap_or(log::Level::Info);
log::set_logger(&Logger).unwrap();
log::set_max_level(level.to_level_filter());
});
}
pub fn init_logger_with_level(level: log::Level) {
if LOGGER.get().is_some() {
return;
}
LOGGER.get_or_init(|| {
log::set_logger(&Logger).unwrap();
log::set_max_level(level.to_level_filter());
});
}