Logging für Rust: Die besten Lösungen
Logging ist eine kritische Komponente jeder ernsthaften Anwendung in Rust. Es hilft, die Codeausführung zu verfolgen, Fehler zu identifizieren, die Leistung zu überwachen und das Systemverhalten in der Produktion zu analysieren. In diesem Artikel betrachten wir die wichtigsten Bibliotheken für Logging im Rust-Ökosystem, ihre Besonderheiten, Vorteile und Anwendungsbeispiele.
Warum ist Logging in Rust wichtig?
Rust, als systemnahe Sprache, stellt hohe Anforderungen an Zuverlässigkeit und Vorhersagbarkeit. Logging ermöglicht:
- Die Verfolgung des Ausführungsflusses in Multithread-Anwendungen.
- Die Erfassung unerwarteter Zustände und Panics.
- Die Durchführung von Sicherheitsaudits.
- Die Sammlung von Metriken zur Leistungsoptimierung.
Wichtige Bibliotheken für Logging
1. log — Fassade für Logging
log ist die Standard-Fassade (abstrakte Schicht) für Logging in Rust. Sie definiert die Makros info!, warn!, error!, debug!, trace! und das Trait Log. Allein gibt sie keine Logs aus – dafür wird ein Backend benötigt (z. B. env_logger oder slog).
// Cargo.toml[dependencies]log = "0.4"
// main.rsuse log::{info, warn, error};
fn main() { // Initialisierung des Backends ist erforderlich env_logger::init(); info!("Anwendung gestartet"); warn!("Niedriger Speicherstand: {}%", 15); error!("Kritischer Fehler: {}", "Verbindungsabbruch");}2. env_logger — Einfaches und schnelles Backend
env_logger ist das beliebteste Backend für log. Es wird über die Umgebungsvariable RUST_LOG konfiguriert. Unterstützt Filterung nach Modulen und Ebenen.
// Installation// cargo add env_logger
// Konfigurationsbeispieluse log::LevelFilter;
fn main() { env_logger::Builder::from_env( env_logger::Env::default().default_filter_or("info") ).init();
log::info!("Start mit Level INFO"); log::debug!("Diese Nachricht wird nicht ausgegeben");}
// Start mit Variable:// RUST_LOG=debug cargo run3. slog — Strukturiertes Logging
slog ist eine leistungsstarke Bibliothek für strukturiertes Logging. Sie unterstützt Schlüssel-Wert-Paare, Logger-Ketten, asynchrones Schreiben und benutzerdefinierte Treiber. Ideal für komplexe Systeme, bei denen der Kontext wichtig ist.
// Cargo.toml[dependencies]slog = "2.7"slog-term = "2.9"slog-json = "2.6"
// main.rsuse slog::{o, Drain, Logger, info};
fn main() { let decorator = slog_term::TermDecorator::new().build(); let drain = slog_term::FullFormat::new(decorator).build().fuse(); let drain = slog_async::Async::new(drain).build().fuse();
let logger = Logger::root(drain, o!("version" => "1.0"));
info!(logger, "Server gestartet"; "port" => 8080, "env" => "production");}4. tracing — Instrumentierung und Tracing
tracing ist eine moderne Bibliothek vom Tokio-Team, die für strukturiertes Logging und Tracing entwickelt wurde. Sie ermöglicht die Erstellung von Spans – Zeitintervalle mit Kontext –, die für asynchrone und Multithread-Anwendungen unverzichtbar sind.
// Cargo.toml[dependencies]tracing = "0.1"tracing-subscriber = "0.3"
// main.rsuse tracing::{info, span, Level};use tracing_subscriber::fmt;
fn main() { // Initialisierung des Subscribers fmt::init();
let span = span!(Level::INFO, "main", "app" = "my_service"); let _guard = span.enter();
info!("Verarbeitung der Anfrage"); // Logs innerhalb des Spans enthalten automatisch den Kontext}Vergleich der Bibliotheken
- log + env_logger: Einfachheit, Minimalismus, geeignet für kleine Projekte
Auch in der Bibliothek
Internationalisierung (i18n) in C# (.NET): Vollständige Anleitung
Arbeiten mit Bildern in Swift: Resize, Crop (iOS/macOS)
GraphQL-Bibliotheken für Kotlin: Vollständiger Überblick für Backend-Entwickler