Skip to main content

sciforge_hub/tools/
logger.rs

1//! Structured logging with configurable severity levels.
2//!
3//! Messages are written to `stderr` via [`log`]. The global level
4//! is controlled by [`set_level`] / [`current_level`].
5
6use std::sync::atomic::{AtomicU8, Ordering};
7
8static LOG_LEVEL: AtomicU8 = AtomicU8::new(2);
9
10/// Log severity level.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12#[repr(u8)]
13pub enum Level {
14    Trace = 0,
15    Debug = 1,
16    Info = 2,
17    Warn = 3,
18    Error = 4,
19    Off = 5,
20}
21
22impl Level {
23    /// Returns the textual representation of the level.
24    pub fn as_str(self) -> &'static str {
25        match self {
26            Self::Trace => "TRACE",
27            Self::Debug => "DEBUG",
28            Self::Info => "INFO",
29            Self::Warn => "WARN",
30            Self::Error => "ERROR",
31            Self::Off => "OFF",
32        }
33    }
34}
35
36/// Sets the global log level.
37pub fn set_level(level: Level) {
38    LOG_LEVEL.store(level as u8, Ordering::Relaxed);
39}
40
41/// Returns the current log level.
42pub fn current_level() -> Level {
43    match LOG_LEVEL.load(Ordering::Relaxed) {
44        0 => Level::Trace,
45        1 => Level::Debug,
46        2 => Level::Info,
47        3 => Level::Warn,
48        4 => Level::Error,
49        _ => Level::Off,
50    }
51}
52
53/// Writes a message to `stderr` if `level` ≥ current level.
54pub fn log(level: Level, module: &str, message: &str) {
55    if level >= current_level() {
56        eprintln!("[{}] {}: {}", level.as_str(), module, message);
57    }
58}
59
60/// Logs at `Trace` level.
61pub fn trace(module: &str, message: &str) {
62    log(Level::Trace, module, message);
63}
64/// Logs at `Debug` level.
65pub fn debug(module: &str, message: &str) {
66    log(Level::Debug, module, message);
67}
68/// Logs at `Info` level.
69pub fn info(module: &str, message: &str) {
70    log(Level::Info, module, message);
71}
72/// Logs at `Warn` level.
73pub fn warn(module: &str, message: &str) {
74    log(Level::Warn, module, message);
75}
76/// Logs at `Error` level.
77pub fn error(module: &str, message: &str) {
78    log(Level::Error, module, message);
79}