use std::sync::atomic::{AtomicU8, Ordering};
use crate::event::{LogLevel, RosaceTrace};
static MAX_LEVEL: AtomicU8 = AtomicU8::new(u8::MAX);
const DEFAULT_MAX_LEVEL: u8 = LogLevel::Info as u8;
pub fn set_max_level(level: LogLevel) {
MAX_LEVEL.store(level as u8, Ordering::Relaxed);
}
#[inline]
pub fn max_level() -> u8 {
let v = MAX_LEVEL.load(Ordering::Relaxed);
if v == u8::MAX {
DEFAULT_MAX_LEVEL
} else {
v
}
}
#[inline]
pub fn enabled(level: LogLevel) -> bool {
(level as u8) <= max_level()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn init_from_env() {
if let Ok(v) = std::env::var("ROSACE_LOG") {
let level = match v.trim().to_ascii_lowercase().as_str() {
"error" => Some(LogLevel::Error),
"warn" => Some(LogLevel::Warn),
"info" => Some(LogLevel::Info),
"debug" => Some(LogLevel::Debug),
"trace" => Some(LogLevel::Trace),
_ => None,
};
if let Some(l) = level {
set_max_level(l);
}
}
}
#[doc(hidden)]
pub fn __emit(level: LogLevel, target: &'static str, args: std::fmt::Arguments) {
crate::TRACING_BUS.emit(RosaceTrace::Log {
level,
target,
message: std::fmt::format(args),
timestamp: web_time::Instant::now(),
});
}
#[macro_export]
macro_rules! log {
($level:expr, $($arg:tt)+) => {{
let __lvl = $level;
if $crate::log::enabled(__lvl) {
$crate::log::__emit(__lvl, ::core::module_path!(), ::core::format_args!($($arg)+));
}
}};
}
#[macro_export]
macro_rules! error {
($($arg:tt)+) => { $crate::log!($crate::event::LogLevel::Error, $($arg)+) };
}
#[macro_export]
macro_rules! warn {
($($arg:tt)+) => { $crate::log!($crate::event::LogLevel::Warn, $($arg)+) };
}
#[macro_export]
macro_rules! info {
($($arg:tt)+) => { $crate::log!($crate::event::LogLevel::Info, $($arg)+) };
}
#[macro_export]
macro_rules! debug {
($($arg:tt)+) => { $crate::log!($crate::event::LogLevel::Debug, $($arg)+) };
}
#[macro_export]
macro_rules! log_trace {
($($arg:tt)+) => { $crate::log!($crate::event::LogLevel::Trace, $($arg)+) };
}