Skip to main content

fuelcheck_cli/
logger.rs

1use chrono::Utc;
2use clap::ValueEnum;
3use serde_json::json;
4use std::sync::OnceLock;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
7pub enum LogLevel {
8    Trace,
9    Verbose,
10    Debug,
11    Info,
12    Warning,
13    Error,
14    Critical,
15}
16
17impl LogLevel {
18    fn priority(self) -> u8 {
19        match self {
20            LogLevel::Trace => 0,
21            LogLevel::Verbose => 1,
22            LogLevel::Debug => 2,
23            LogLevel::Info => 3,
24            LogLevel::Warning => 4,
25            LogLevel::Error => 5,
26            LogLevel::Critical => 6,
27        }
28    }
29
30    fn as_str(self) -> &'static str {
31        match self {
32            LogLevel::Trace => "trace",
33            LogLevel::Verbose => "verbose",
34            LogLevel::Debug => "debug",
35            LogLevel::Info => "info",
36            LogLevel::Warning => "warning",
37            LogLevel::Error => "error",
38            LogLevel::Critical => "critical",
39        }
40    }
41}
42
43#[derive(Debug, Clone)]
44pub struct LoggerConfig {
45    pub level: LogLevel,
46    pub json_output: bool,
47    pub json_only: bool,
48}
49
50static LOGGER: OnceLock<LoggerConfig> = OnceLock::new();
51
52pub fn init(config: LoggerConfig) {
53    let _ = LOGGER.set(config);
54}
55
56pub fn log(
57    level: LogLevel,
58    event: &str,
59    message: impl AsRef<str>,
60    context: Option<serde_json::Value>,
61) {
62    let Some(config) = LOGGER.get() else {
63        return;
64    };
65    if level.priority() < config.level.priority() {
66        return;
67    }
68    if config.json_output {
69        let payload = json!({
70            "ts": Utc::now().to_rfc3339(),
71            "level": level.as_str(),
72            "event": event,
73            "message": message.as_ref(),
74            "context": context,
75        });
76        if let Ok(line) = serde_json::to_string(&payload) {
77            eprintln!("{}", line);
78        }
79        return;
80    }
81
82    if config.json_only {
83        return;
84    }
85
86    eprintln!("[{}] {}: {}", level.as_str(), event, message.as_ref());
87}