use std::fmt::Debug;
pub mod handler;
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
pub enum LogLevel {
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
}
pub struct Logger {
name: String,
level: LogLevel,
handlers: Vec<Box<dyn handler::Handler>>,
}
impl Logger {
pub fn new(level: LogLevel, name: &str) -> Self {
Self {
name: name.to_string(),
level,
handlers: Vec::new(),
}
}
pub fn global() -> &'static mut Self {
unsafe {
if LOGGER.is_none() {
LOGGER = Some(Logger {
level: LogLevel::TRACE,
name: "lambda-rs".to_string(),
handlers: vec![Box::new(handler::ConsoleHandler::new("lambda-rs"))],
});
}
};
return unsafe { &mut LOGGER }
.as_mut()
.expect("Logger not initialized");
}
pub fn add_handler(&mut self, handler: Box<dyn handler::Handler>) {
self.handlers.push(handler);
}
fn compare_levels(&self, level: LogLevel) -> bool {
level as u8 >= self.level as u8
}
pub fn trace(&mut self, message: String) {
if !self.compare_levels(LogLevel::TRACE) {
return;
}
for handler in self.handlers.iter_mut() {
handler.trace(message.clone());
}
}
pub fn debug(&mut self, message: String) {
if !self.compare_levels(LogLevel::DEBUG) {
return;
}
for handler in self.handlers.iter_mut() {
handler.debug(message.clone());
}
}
pub fn info(&mut self, message: String) {
if !self.compare_levels(LogLevel::INFO) {
return;
}
for handler in self.handlers.iter_mut() {
handler.info(message.clone());
}
}
pub fn warn(&mut self, message: String) {
if !self.compare_levels(LogLevel::WARN) {
return;
}
for handler in self.handlers.iter_mut() {
handler.warn(message.clone());
}
}
pub fn error(&mut self, message: String) {
if !self.compare_levels(LogLevel::ERROR) {
return;
}
for handler in self.handlers.iter_mut() {
handler.error(message.clone());
}
}
pub fn fatal(&mut self, message: String) {
if !self.compare_levels(LogLevel::FATAL) {
return;
}
for handler in self.handlers.iter_mut() {
handler.fatal(message.clone());
}
std::process::exit(1);
}
}
pub(crate) static mut LOGGER: Option<Logger> = None;
#[macro_export]
macro_rules! trace {
($($arg:tt)*) => {
logging::Logger::global().trace(format!("{}", format_args!($($arg)*)));
};
}
#[macro_export]
macro_rules! debug {
($($arg:tt)*) => {
logging::Logger::global().debug(format!("{}", format_args!($($arg)*)));
};
}
#[macro_export]
macro_rules! info {
($($arg:tt)*) => {
logging::Logger::global().info(format!("{}", format_args!($($arg)*)));
};
}
#[macro_export]
macro_rules! warn {
($($arg:tt)*) => {
logging::Logger::global().warn(format!("{}", format_args!($($arg)*)));
};
}
#[macro_export]
macro_rules! error {
($($arg:tt)*) => {
logging::Logger::global().error(format!("{}", format_args!($($arg)*)));
};
}
#[macro_export]
macro_rules! fatal {
($($arg:tt)*) => {
logging::Logger::global().fatal(format!("{}", format_args!($($arg)*)));
};
}