Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/lambda-rs-logging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ use logging; // renamed in Cargo.toml
use lambda_rs_logging as logging;

fn main() {
// Default global level:
// - Debug builds: DEBUG
// - Release builds: INFO
//
// Override at runtime with LAMBDA_LOG=trace|debug|info|warn|error|fatal
logging::trace!("trace {}", 1);
logging::debug!("debug {}", 2);
logging::info!("info {}", 3);
Expand Down
44 changes: 37 additions & 7 deletions crates/lambda-rs-logging/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#![allow(clippy::needless_return)]
//! A simple logging library for lambda-rs crates.
//!
//! # Default global level
//! - Debug builds (`cfg(debug_assertions)`): `DEBUG`
//! - Release builds (`cfg(not(debug_assertions))`): `INFO`
//!
//! The global level can be overridden at runtime with `LAMBDA_LOG`
//! (`trace|debug|info|warn|error|fatal`). For best results, call
//! `lambda_rs_logging::env::init_global_from_env()` early in startup before
//! any logging macros are used.

use std::{
fmt,
Expand Down Expand Up @@ -61,6 +70,20 @@ pub struct Logger {
handlers: RwLock<Vec<Box<dyn handler::Handler>>>,
}

static GLOBAL_LOGGER: OnceLock<Arc<Logger>> = OnceLock::new();

fn default_global_level() -> LogLevel {
#[cfg(debug_assertions)]
{
return LogLevel::DEBUG;
}

#[cfg(not(debug_assertions))]
{
return LogLevel::INFO;
}
}

impl Logger {
/// Creates a new logger with the given log level and name.
pub fn new(level: LogLevel, name: &str) -> Self {
Expand All @@ -79,9 +102,8 @@ impl Logger {
/// Returns the global logger (thread-safe). Initializes with a default
/// console handler if not explicitly initialized via `init`.
pub fn global() -> &'static Arc<Self> {
static GLOBAL: OnceLock<Arc<Logger>> = OnceLock::new();
GLOBAL.get_or_init(|| {
let logger = Logger::new(LogLevel::TRACE, "lambda-rs");
GLOBAL_LOGGER.get_or_init(|| {
let logger = Logger::new(default_global_level(), "lambda-rs");
// Default console handler
logger.add_handler(Box::new(handler::ConsoleHandler::new("lambda-rs")));
Arc::new(logger)
Expand All @@ -90,8 +112,7 @@ impl Logger {

/// Initialize the global logger (first caller wins).
pub fn init(logger: Logger) -> Result<(), InitError> {
static GLOBAL: OnceLock<Arc<Logger>> = OnceLock::new();
GLOBAL
GLOBAL_LOGGER
.set(Arc::new(logger))
.map_err(|_| InitError::AlreadyInitialized)
}
Expand Down Expand Up @@ -261,11 +282,20 @@ pub mod env {
pub fn init_global_from_env() -> Result<(), super::InitError> {
let logger = Logger::builder()
.name("lambda-rs")
.level(LogLevel::INFO)
.level(super::default_global_level())
.with_handler(Box::new(crate::handler::ConsoleHandler::new("lambda-rs")))
.build();
apply_env_level(&logger, Some("LAMBDA_LOG"));
super::Logger::init(logger)
match super::Logger::init(logger) {
Ok(()) => {
return Ok(());
}
Err(super::InitError::AlreadyInitialized) => {
let global = super::Logger::global().clone();
apply_env_level(global.as_ref(), Some("LAMBDA_LOG"));
return Ok(());
}
}
}
}
/// Returns whether the global logger would log at `level`.
Expand Down
Loading