use std::env;
use std::sync::Once;
static INIT: Once = Once::new();
#[inline]
pub fn is_debug_enabled() -> bool {
env::var("PRAX_DEBUG")
.map(|v| matches!(v.to_lowercase().as_str(), "true" | "1" | "yes"))
.unwrap_or(false)
}
pub fn get_log_level() -> &'static str {
if let Ok(level) = env::var("PRAX_LOG_LEVEL") {
match level.to_lowercase().as_str() {
"trace" => "trace",
"debug" => "debug",
"info" => "info",
"warn" => "warn",
"error" => "error",
_ => {
if is_debug_enabled() {
"debug"
} else {
"warn"
}
}
}
} else if is_debug_enabled() {
"debug"
} else {
"warn"
}
}
pub fn get_log_format() -> &'static str {
env::var("PRAX_LOG_FORMAT")
.map(|f| match f.to_lowercase().as_str() {
"pretty" => "pretty",
"compact" => "compact",
_ => "json",
})
.unwrap_or("json")
}
pub fn init() {
INIT.call_once(|| {
if !is_debug_enabled() && env::var("PRAX_LOG_LEVEL").is_err() {
return;
}
#[cfg(feature = "tracing-subscriber")]
{
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
let level = get_log_level();
let filter = EnvFilter::try_new(format!(
"prax={},prax_query={},prax_schema={}",
level, level, level
))
.unwrap_or_else(|_| EnvFilter::new("warn"));
match get_log_format() {
"json" => {
tracing_subscriber::registry()
.with(filter)
.with(fmt::layer().json())
.init();
}
"compact" => {
tracing_subscriber::registry()
.with(filter)
.with(fmt::layer().compact())
.init();
}
_ => {
tracing_subscriber::registry()
.with(filter)
.with(fmt::layer().pretty())
.init();
}
}
tracing::info!(
level = level,
format = get_log_format(),
"Prax logging initialized"
);
}
#[cfg(not(feature = "tracing-subscriber"))]
{
}
});
}
pub fn init_with_level(level: &str) {
unsafe {
env::set_var("PRAX_LOG_LEVEL", level);
}
init();
}
pub fn init_debug() {
unsafe {
env::set_var("PRAX_DEBUG", "true");
}
init();
}
#[macro_export]
macro_rules! prax_debug {
($($arg:tt)*) => {
if $crate::logging::is_debug_enabled() {
tracing::debug!($($arg)*);
}
};
}
#[macro_export]
macro_rules! prax_trace {
($($arg:tt)*) => {
if $crate::logging::is_debug_enabled() {
tracing::trace!($($arg)*);
}
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_debug_disabled_by_default() {
unsafe {
env::remove_var("PRAX_DEBUG");
}
assert!(!is_debug_enabled());
}
#[test]
fn test_log_level_default() {
unsafe {
env::remove_var("PRAX_DEBUG");
env::remove_var("PRAX_LOG_LEVEL");
}
assert_eq!(get_log_level(), "warn");
}
}