Refactor: Entferne Terminal-Überprüfung und vereinfache Ausgabehandling
This commit is contained in:
+11
-29
@@ -1,10 +1,10 @@
|
|||||||
//! Einfaches, threadsicheres Logging-Modul.
|
//! Einfaches, threadsicheres Logging-Modul.
|
||||||
//!
|
//!
|
||||||
//! Merkmale:
|
//! Merkmale:
|
||||||
//! - Ausgabe in Terminal (stdout/stderr) und zusätzlich in eine Logdatei im temporären Verzeichnis.
|
//! - Ausgabe auf Standard-Streams (stdout/stderr) und zusätzlich in eine Logdatei im temporären Verzeichnis.
|
||||||
//! - Nachrichtenvorlage: `[DD.MM.YYYY HH:MM:SS.mmm][LEVEL][TAG]: <Text>` mit Präfix ([!]/[?]/[i]/[d]).
|
//! - Nachrichtenvorlage: `[DD.MM.YYYY HH:MM:SS.mmm][LEVEL][TAG]: <Text>` mit Präfix ([!]/[?]/[i]/[d]).
|
||||||
//! - Der aktuell verwendete Schweregradfilter ist statisch (`LOG_LEVEL`) und wird zur Laufzeit nicht geändert.
|
//! - Der aktuell verwendete Schweregradfilter ist statisch (`LOG_LEVEL`) und wird zur Laufzeit nicht geändert.
|
||||||
//! - Terminal-Erkennung und Dateihandle werden lazily initialisiert und zwischengespeichert (`OnceLock`).
|
//! - Dateihandle wird lazily initialisiert und zwischengespeichert (`OnceLock`).
|
||||||
//!
|
//!
|
||||||
//! Hinweise:
|
//! Hinweise:
|
||||||
//! - Bei einem leeren `tag` wird ein leerer Tag-Abschnitt erzeugt.
|
//! - Bei einem leeren `tag` wird ein leerer Tag-Abschnitt erzeugt.
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fs::{create_dir_all, File, OpenOptions};
|
use std::fs::{File, OpenOptions, create_dir_all};
|
||||||
use std::io::{stdout, IsTerminal, Write};
|
use std::io::Write;
|
||||||
use std::sync::{Mutex, OnceLock};
|
use std::sync::{Mutex, OnceLock};
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use crate::program;
|
use crate::program;
|
||||||
use time::{macros::format_description, OffsetDateTime};
|
use time::{OffsetDateTime, macros::format_description};
|
||||||
|
|
||||||
/// Schweregrade für Logeinträge in aufsteigender Detailtiefe.
|
/// Schweregrade für Logeinträge in aufsteigender Detailtiefe.
|
||||||
///
|
///
|
||||||
@@ -71,14 +71,11 @@ impl TryFrom<String> for LogLevel {
|
|||||||
"warn" => Ok(LogLevel::Warn),
|
"warn" => Ok(LogLevel::Warn),
|
||||||
"info" => Ok(LogLevel::Info),
|
"info" => Ok(LogLevel::Info),
|
||||||
"debug" => Ok(LogLevel::Debug),
|
"debug" => Ok(LogLevel::Debug),
|
||||||
_ => Err(LogLevel::Info)
|
_ => Err(LogLevel::Info),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Zwischenspeicher für die einmalig ermittelte Terminal-Fähigkeit von `stdout`.
|
|
||||||
static IS_TERMINAL: OnceLock<bool> = OnceLock::new();
|
|
||||||
|
|
||||||
/// Globaler Schweregradfilter für Ausgabe.
|
/// Globaler Schweregradfilter für Ausgabe.
|
||||||
static LOG_LEVEL: OnceLock<LogLevel> = OnceLock::new();
|
static LOG_LEVEL: OnceLock<LogLevel> = OnceLock::new();
|
||||||
|
|
||||||
@@ -89,7 +86,7 @@ static LOG_FILE: OnceLock<Mutex<Option<File>>> = OnceLock::new();
|
|||||||
///
|
///
|
||||||
/// Verhalten:
|
/// Verhalten:
|
||||||
/// - Wenn `log_level` größer als der globale Filter ist, wird nichts ausgegeben.
|
/// - Wenn `log_level` größer als der globale Filter ist, wird nichts ausgegeben.
|
||||||
/// - Bei Terminalausgabe gehen `Error`-Meldungen nach `stderr`, alle anderen nach `stdout`.
|
/// - `Error`-Meldungen gehen nach `stderr`, alle anderen nach `stdout`.
|
||||||
/// - Zusätzlich wird in eine tägliche Logdatei im Temp-Verzeichnis geschrieben (wenn erfolgreich geöffnet).
|
/// - Zusätzlich wird in eine tägliche Logdatei im Temp-Verzeichnis geschrieben (wenn erfolgreich geöffnet).
|
||||||
///
|
///
|
||||||
/// Parameter:
|
/// Parameter:
|
||||||
@@ -109,12 +106,10 @@ pub fn log(tag: &str, message: &str, log_level: LogLevel) {
|
|||||||
if log_level <= get_log_level() {
|
if log_level <= get_log_level() {
|
||||||
let message: String = format_message(tag, message, &log_level);
|
let message: String = format_message(tag, message, &log_level);
|
||||||
|
|
||||||
if is_terminal() {
|
|
||||||
if log_level == LogLevel::Error {
|
if log_level == LogLevel::Error {
|
||||||
eprintln!("{}", message)
|
eprintln!("{}", message);
|
||||||
} else {
|
} else {
|
||||||
println!("{}", message)
|
println!("{}", message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_lock = get_or_init_log_file();
|
let file_lock = get_or_init_log_file();
|
||||||
@@ -138,17 +133,7 @@ fn get_log_level() -> LogLevel {
|
|||||||
*LOG_LEVEL.get_or_init(|| {
|
*LOG_LEVEL.get_or_init(|| {
|
||||||
let log_level = &config::get_config().general.log_level;
|
let log_level = &config::get_config().general.log_level;
|
||||||
LogLevel::try_from(log_level.to_string()).unwrap_or(LogLevel::Info)
|
LogLevel::try_from(log_level.to_string()).unwrap_or(LogLevel::Info)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ermittelt einmalig, ob `stdout` ein Terminal ist, und cached das Ergebnis.
|
|
||||||
///
|
|
||||||
/// Rückgabe:
|
|
||||||
/// - `true`, wenn `stdout` ein TTY/Terminal ist.
|
|
||||||
/// - `false` andernfalls.
|
|
||||||
fn is_terminal() -> bool {
|
|
||||||
*IS_TERMINAL.get_or_init(|| stdout().is_terminal())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formatiert eine Lognachricht mit Zeitstempel, Level, Tag und Präfix.
|
/// Formatiert eine Lognachricht mit Zeitstempel, Level, Tag und Präfix.
|
||||||
@@ -234,10 +219,7 @@ fn open_log_file() -> std::io::Result<File> {
|
|||||||
let file_name = format!("log-{}.log", date_str);
|
let file_name = format!("log-{}.log", date_str);
|
||||||
dir.push(file_name);
|
dir.push(file_name);
|
||||||
|
|
||||||
OpenOptions::new()
|
OpenOptions::new().create(true).append(true).open(dir)
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open(dir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user