use std::sync::{Arc, Mutex, OnceLock};
use crate::config::Config;
use crate::level::LogLevel;
use crate::writer::Writer;
pub struct Logger {
level: Mutex<LogLevel>,
writer: Arc<Writer>,
}
static LOGGER: OnceLock<Arc<Logger>> = OnceLock::new();
impl Logger {
pub fn get_instance() -> Arc<Self> {
LOGGER.get_or_init(|| {
let config = Config::default();
let writer = Arc::new(Writer::new(config.clone()));
Arc::new(Logger {
level: Mutex::new(config.level),
writer,
})
}).clone()
}
pub fn init_with_config(config: Config) {
LOGGER.get_or_init(|| {
let writer = Arc::new(Writer::new(config.clone()));
Arc::new(Logger {
level: Mutex::new(config.level),
writer,
})
});
}
pub fn set_level(&self, level: LogLevel) {
*self.level.lock().unwrap() = level;
}
pub fn get_level(&self) -> LogLevel {
*self.level.lock().unwrap()
}
pub fn set_console_enabled(&self, enabled: bool) {
self.writer.set_console_enabled(enabled);
}
pub fn set_console_colors(&self, enabled: bool) {
self.writer.set_console_colors(enabled);
}
pub fn debug(&self, message: &str) {
self.log(LogLevel::Debug, message);
}
pub fn info(&self, message: &str) {
self.log(LogLevel::Info, message);
}
pub fn warn(&self, message: &str) {
self.log(LogLevel::Warn, message);
}
pub fn error(&self, message: &str) {
self.log(LogLevel::Error, message);
}
pub fn critical(&self, message: &str) {
self.log(LogLevel::Critical, message);
}
fn log(&self, level: LogLevel, message: &str) {
if self.get_level().should_log(level) {
self.writer.write(level, message);
}
}
}