diff --git a/.gitea/workflows/code-quality.yaml b/.gitea/workflows/code-quality.yaml
index 8c35d11..dc69eb5 100644
--- a/.gitea/workflows/code-quality.yaml
+++ b/.gitea/workflows/code-quality.yaml
@@ -24,16 +24,14 @@ jobs:
components: clippy, rustfmt
cache: false
+ # Ein rohes 'actions/cache' auf target/ liefert zwar einen technischen Cache-Hit (Dateien
+ # werden wiederhergestellt), Cargo kompiliert die Abhängigkeiten aber oft trotzdem neu:
+ # Der tar-basierte Restore-Vorgang setzt bei allen wiederhergestellten Dateien dieselbe
+ # Mtime, wodurch Cargos Fingerprinting nicht mehr zuverlässig erkennen kann, was
+ # älter/neuer als was ist, und sicherheitshalber alles neu baut. Swatinem/rust-cache ist
+ # genau dafür gebaut (u. a. gezielte Mtime-Korrektur nach dem Restore).
- name: Cache Cargo-Abhängigkeiten & Build-Artefakte
- uses: actions/cache@v6
- with:
- path: |
- ~/.cargo/registry
- ~/.cargo/git
- target
- key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
- restore-keys: |
- cargo-${{ runner.os }}-
+ uses: Swatinem/rust-cache@v2
- name: Formatierung automatisch beheben
run: cargo fmt
diff --git a/.gitea/workflows/main.yaml b/.gitea/workflows/main.yaml
index 8157f26..6db7dcb 100644
--- a/.gitea/workflows/main.yaml
+++ b/.gitea/workflows/main.yaml
@@ -54,16 +54,14 @@ jobs:
toolchain: stable
cache: false
+ # Ein rohes 'actions/cache' auf target/ liefert zwar einen technischen Cache-Hit (Dateien
+ # werden wiederhergestellt), Cargo kompiliert die Abhängigkeiten aber oft trotzdem neu:
+ # Der tar-basierte Restore-Vorgang setzt bei allen wiederhergestellten Dateien dieselbe
+ # Mtime, wodurch Cargos Fingerprinting nicht mehr zuverlässig erkennen kann, was
+ # älter/neuer als was ist, und sicherheitshalber alles neu baut. Swatinem/rust-cache ist
+ # genau dafür gebaut (u. a. gezielte Mtime-Korrektur nach dem Restore).
- name: Cache Cargo-Abhängigkeiten & Build-Artefakte
- uses: actions/cache@v6
- with:
- path: |
- ~/.cargo/registry
- ~/.cargo/git
- target
- key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
- restore-keys: |
- cargo-${{ runner.os }}-
+ uses: Swatinem/rust-cache@v2
- name: Run Tests
run: |
diff --git a/.gitea/workflows/renovate.yaml b/.gitea/workflows/renovate.yaml
index ccbdcb2..3e3f23e 100644
--- a/.gitea/workflows/renovate.yaml
+++ b/.gitea/workflows/renovate.yaml
@@ -9,7 +9,7 @@ jobs:
renovate:
name: Dependency-Updates prüfen & Pull Requests erstellen
runs-on: ubuntu-latest
- container: ghcr.io/renovatebot/renovate:44.83.0
+ container: ghcr.io/renovatebot/renovate:44.103.6
steps:
- name: Renovate ausführen
run: renovate
diff --git a/.gitea/workflows/security-scan.yaml b/.gitea/workflows/security-scan.yaml
index 75df4b3..040bef7 100644
--- a/.gitea/workflows/security-scan.yaml
+++ b/.gitea/workflows/security-scan.yaml
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
env:
TRIVY_VERSION: "0.74.0"
- OSV_SCANNER_VERSION: "2.5.1"
+ OSV_SCANNER_VERSION: "2.6.0"
steps:
- name: Checkout Repository
uses: actions/checkout@v7
diff --git a/.gitea/workflows/testing.yaml b/.gitea/workflows/testing.yaml
index 44e60dd..fbefcde 100644
--- a/.gitea/workflows/testing.yaml
+++ b/.gitea/workflows/testing.yaml
@@ -43,16 +43,14 @@ jobs:
toolchain: stable
cache: false
+ # Ein rohes 'actions/cache' auf target/ liefert zwar einen technischen Cache-Hit (Dateien
+ # werden wiederhergestellt), Cargo kompiliert die Abhängigkeiten aber oft trotzdem neu:
+ # Der tar-basierte Restore-Vorgang setzt bei allen wiederhergestellten Dateien dieselbe
+ # Mtime, wodurch Cargos Fingerprinting nicht mehr zuverlässig erkennen kann, was
+ # älter/neuer als was ist, und sicherheitshalber alles neu baut. Swatinem/rust-cache ist
+ # genau dafür gebaut (u. a. gezielte Mtime-Korrektur nach dem Restore).
- name: Cache Cargo-Abhängigkeiten & Build-Artefakte
- uses: actions/cache@v6
- with:
- path: |
- ~/.cargo/registry
- ~/.cargo/git
- target
- key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
- restore-keys: |
- cargo-${{ runner.os }}-
+ uses: Swatinem/rust-cache@v2
- name: Run Tests
run: |
diff --git a/.gitea/workflows/trufflehog-scan.yaml b/.gitea/workflows/trufflehog-scan.yaml
index 5e4fcb6..c6457cd 100644
--- a/.gitea/workflows/trufflehog-scan.yaml
+++ b/.gitea/workflows/trufflehog-scan.yaml
@@ -12,7 +12,7 @@ jobs:
name: TruffleHog
runs-on: ubuntu-latest
env:
- TRUFFLEHOG_VERSION: "3.97.4"
+ TRUFFLEHOG_VERSION: "3.97.5"
steps:
- name: Checkout Repository
uses: actions/checkout@v7
diff --git a/.gitea/workflows/unit-tests.yaml b/.gitea/workflows/unit-tests.yaml
index 7703f7f..69175cb 100644
--- a/.gitea/workflows/unit-tests.yaml
+++ b/.gitea/workflows/unit-tests.yaml
@@ -8,6 +8,7 @@ on:
- reopened
branches:
- testing
+ - dev
jobs:
test:
@@ -23,16 +24,14 @@ jobs:
toolchain: stable
cache: false
+ # Ein rohes 'actions/cache' auf target/ liefert zwar einen technischen Cache-Hit (Dateien
+ # werden wiederhergestellt), Cargo kompiliert die Abhängigkeiten aber oft trotzdem neu:
+ # Der tar-basierte Restore-Vorgang setzt bei allen wiederhergestellten Dateien dieselbe
+ # Mtime, wodurch Cargos Fingerprinting nicht mehr zuverlässig erkennen kann, was
+ # älter/neuer als was ist, und sicherheitshalber alles neu baut. Swatinem/rust-cache ist
+ # genau dafür gebaut (u. a. gezielte Mtime-Korrektur nach dem Restore).
- name: Cache Cargo-Abhängigkeiten & Build-Artefakte
- uses: actions/cache@v6
- with:
- path: |
- ~/.cargo/registry
- ~/.cargo/git
- target
- key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
- restore-keys: |
- cargo-${{ runner.os }}-
+ uses: Swatinem/rust-cache@v2
- name: Run Tests
run: cargo test
diff --git a/.idea/Logger.iml b/.idea/Logger.iml
index bbe0a70..1aed096 100644
--- a/.idea/Logger.iml
+++ b/.idea/Logger.iml
@@ -4,6 +4,7 @@
+
diff --git a/Cargo.lock b/Cargo.lock
index 2892bf2..6b1feb0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,7 +16,7 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "logger-ctdra"
-version = "1.0.5"
+version = "1.1.0"
dependencies = [
"program-ctdra",
"time",
diff --git a/Cargo.toml b/Cargo.toml
index ece5d05..93b814b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "logger-ctdra"
-version = "1.0.5"
+version = "1.1.0"
edition = "2024"
authors = ['DragonSlayer_14']
readme = "README.md"
diff --git a/README.md b/README.md
index 1c270f3..11aa0f2 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@
- `Warn` (2) — Warnungen (Ausgabe auf `stdout` mit `[?]`-Präfix)
- `Info` (3) — Betriebsinformationen (Ausgabe auf `stdout` mit `[i]`-Präfix)
- `Debug` (4) — Diagnoseausgaben (Ausgabe auf `stdout` mit `[d]`-Präfix)
+- **Farbige Terminalausgabe**: Jede Zeile wird je nach Schweregrad eingefärbt (`Error` rot, `Warn` gelb, `Info` grün, `Debug` cyan). Farben werden nur ausgegeben, wenn `stdout`/`stderr` ein echtes Terminal ist (keine Umleitung in Datei/Pipe), `NO_COLOR` nicht gesetzt ist und `TERM` nicht `dumb` ist. Die Logdatei enthält stets reinen Text ohne ANSI-Codes.
- **Threadsicherheit**: Dateischreibzugriffe und Konfiguration sind thread-sicher serialisiert.
- **Einheitliches Format**: `[Präfix][DD.MM.YYYY HH:MM:SS.mmm][LEVEL][Tag]: Nachricht`
- **Flexible Konfiguration**:
diff --git a/renovate.json b/renovate.json
index 717bd4d..0bb42ae 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,29 +1,59 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": ["config:recommended"],
+ "extends": [
+ "config:recommended"
+ ],
"timezone": "Europe/Berlin",
- "schedule": ["before 6am on monday"],
+ "schedule": [
+ "before 6am"
+ ],
"baseBranchPatterns": [
"dev"
],
"packageRules": [
{
- "matchFileNames": [".gitea/workflows/**"],
+ "matchFileNames": [
+ ".gitea/workflows/**"
+ ],
"groupName": "Gitea Actions",
"separateMajorMinor": false,
"separateMinorPatch": false
},
{
- "matchManagers": ["cargo"],
+ "matchManagers": [
+ "cargo"
+ ],
"groupName": "Cargo Dependencies",
"separateMajorMinor": false,
"separateMinorPatch": false
},
{
- "matchManagers": ["dockerfile", "docker-compose"],
+ "matchManagers": [
+ "dockerfile",
+ "docker-compose"
+ ],
"groupName": "Docker-Images",
"separateMajorMinor": false,
"separateMinorPatch": false
+ },
+ {
+ "description": "Patch-/Minor-/Digest-Updates automatisch mergen, sobald alle CI-Checks (inkl. Unit-Tests) erfolgreich sind - Major-Updates sind unten explizit ausgenommen (siehe nächste Regel).",
+ "matchUpdateTypes": [
+ "patch",
+ "minor",
+ "digest",
+ "lockFileMaintenance"
+ ],
+ "automerge": true,
+ "automergeType": "pr",
+ "platformAutomerge": true
+ },
+ {
+ "description": "Major-Updates immer manuell prüfen, da potenziell brechende Änderungen.",
+ "matchUpdateTypes": [
+ "major"
+ ],
+ "automerge": false
}
],
"customManagers": [
diff --git a/src/lib.rs b/src/lib.rs
index bea72bd..407afab 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -24,7 +24,7 @@
use std::env;
use std::fmt::{Display, Formatter};
use std::fs::{File, OpenOptions, create_dir_all};
-use std::io::Write;
+use std::io::{IsTerminal, Write};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::atomic::{AtomicU8, Ordering};
@@ -156,6 +156,33 @@ pub fn set_log_dir(path: impl Into) {
}
}
+/// ANSI-Escape-Sequenz zum Zurücksetzen der Textfarbe.
+const ANSI_RESET: &str = "\x1b[0m";
+
+/// Liefert die ANSI-Farbsequenz für den jeweiligen Schweregrad.
+///
+/// Farben: `Error` -> Rot, `Warn` -> Gelb, `Info` -> Grün, `Debug` -> Cyan.
+fn ansi_color(log_level: &LogLevel) -> &'static str {
+ match log_level {
+ LogLevel::Error => "\x1b[31m",
+ LogLevel::Warn => "\x1b[33m",
+ LogLevel::Info => "\x1b[32m",
+ LogLevel::Debug => "\x1b[36m",
+ }
+}
+
+/// Prüft, ob Farbausgabe für den gegebenen Stream sinnvoll ist.
+///
+/// Voraussetzungen:
+/// - Der Stream muss ein echtes Terminal sein (`is_terminal`), keine Umleitung in eine Datei oder Pipe.
+/// - Die Umgebungsvariable `NO_COLOR` darf nicht gesetzt sein (siehe ).
+/// - `TERM` darf nicht auf `dumb` stehen.
+fn color_supported(stream_is_terminal: bool) -> bool {
+ stream_is_terminal
+ && env::var_os("NO_COLOR").is_none()
+ && env::var("TERM").map(|term| term != "dumb").unwrap_or(true)
+}
+
/// Formatiert eine Lognachricht mit Zeitstempel, Level, Tag und Präfix.
///
/// Format:
@@ -224,7 +251,13 @@ pub fn log(tag: &str, message: &str, log_level: LogLevel) {
let formatted = format_message(tag, message, &log_level);
if log_level == LogLevel::Error {
- eprintln!("{}", formatted);
+ if color_supported(std::io::stderr().is_terminal()) {
+ eprintln!("{}{}{}", ansi_color(&log_level), formatted, ANSI_RESET);
+ } else {
+ eprintln!("{}", formatted);
+ }
+ } else if color_supported(std::io::stdout().is_terminal()) {
+ println!("{}{}{}", ansi_color(&log_level), formatted, ANSI_RESET);
} else {
println!("{}", formatted);
}