diff --git a/src/log.rs b/src/log.rs index c60e43e..e400ec3 100644 --- a/src/log.rs +++ b/src/log.rs @@ -28,6 +28,7 @@ use std::sync::{Mutex, OnceLock}; use time::{macros::format_description, OffsetDateTime}; use crate::program; +use crate::config; /// Schweregrade für Logeinträge in aufsteigender Detailtiefe. /// @@ -61,12 +62,25 @@ impl Display for LogLevel { } } +impl TryFrom for LogLevel { + type Error = LogLevel; + + fn try_from(value: std::string::String) -> Result { + match value.to_lowercase().as_str() { + "error" => Ok(LogLevel::Error), + "warn" => Ok(LogLevel::Warn), + "info" => Ok(LogLevel::Info), + "debug" => Ok(LogLevel::Debug), + _ => Err(LogLevel::Info) + } + } +} + /// Zwischenspeicher für die einmalig ermittelte Terminal-Fähigkeit von `stdout`. static IS_TERMINAL: OnceLock = OnceLock::new(); /// Globaler Schweregradfilter für Ausgabe. -/// TODO: In Zukunft aus Konfiguration laden. -static LOG_LEVEL: LogLevel = LogLevel::Debug; +static LOG_LEVEL: OnceLock = OnceLock::new(); /// Lazy-initialisiertes Handle zur Logdatei; kann `None` sein, falls das Öffnen fehlschlug. static LOG_FILE: OnceLock>> = OnceLock::new(); @@ -92,7 +106,7 @@ static LOG_FILE: OnceLock>> = OnceLock::new(); /// log("http", "Server gestartet auf Port 8080", LogLevel::Info); /// ``` pub fn log(tag: &str, message: &str, log_level: LogLevel) { - if log_level <= LOG_LEVEL { + if log_level <= get_log_level() { let message: String = format_message(tag, message, &log_level); if is_terminal() { @@ -113,6 +127,21 @@ pub fn log(tag: &str, message: &str, log_level: LogLevel) { } } +/// Liefert das einmalig initialisierte Log-Level für die Filterung. +/// +/// Ermittelt das konfigurierte Log-Level aus der Config-Datei. +/// Wenn ungültig oder nicht vorhanden, wird LogLevel::Info als Fallback verwendet. +/// +/// Rückgabe: +/// - `LogLevel`: Das zu verwendende Log-Level als enum-Wert. +fn get_log_level() -> LogLevel { + *LOG_LEVEL.get_or_init(|| { + let log_level = &config::get_config().general.log_level; + LogLevel::try_from(log_level.to_string()).unwrap_or(LogLevel::Info) + } + ) +} + /// Ermittelt einmalig, ob `stdout` ein Terminal ist, und cached das Ergebnis. /// /// Rückgabe: