Logging in Rust: Best Practices für Anfänger

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Logging in Rust-Anwendungen: Best Practices für Anfänger

\n

Logging ist einer der wichtigsten Aspekte der Entwicklung jeder Anwendung. Es hilft, Fehler zu verfolgen, die Leistung zu analysieren und das Verhalten des Systems in der Produktion zu verstehen. Im Rust-Ökosystem gibt es mehrere leistungsstarke Bibliotheken für das Logging, die eine flexible Konfiguration der Nachrichtenausgabe ermöglichen. In diesem Artikel werden wir die besten Praktiken für das Logging in Rust für Anfänger durchgehen, beginnend mit grundlegenden Konzepten bis hin zu realen Codebeispielen.

\n\n

Warum ist Logging in Rust wichtig?

\n

Rust ist eine systemnahe Programmiersprache, die häufig für die Erstellung hochbelasteter und kritischer Anwendungen verwendet wird. In solchen Systemen kann jeder Fehler schwerwiegende Folgen haben. Logging ermöglicht:

\n
    \n
  • Fehler erkennen — selbst wenn die Anwendung nicht abstürzt, helfen Logs zu verstehen, was schiefgelaufen ist.
  • \n
  • Leistung überwachen — messen Sie die Ausführungszeit von Funktionen und finden Sie Engpässe.
  • \n
  • Komplexe Szenarien debuggen — in Multithread-Anwendungen sind Logs unverzichtbar, um die Ausführungsreihenfolge zu verstehen.
  • \n
  • Transparenz gewährleisten — in der Produktion können Sie in Echtzeit sehen, was mit der Anwendung passiert.
  • \n
\n

In Rust enthält die Standardbibliothek keinen integrierten Logger, aber die Community hat hervorragende Crates (Bibliotheken) für diese Aufgabe entwickelt. Wir werden uns die beiden beliebtesten ansehen: log + env_logger und tracing.

\n\n

Erste Schritte mit dem log- und env_logger-Crate

\n

Der einfachste Weg, Logging zu einer Rust-Anwendung hinzuzufügen, ist die Kombination der Crates log und env_logger. log bietet abstrakte Makros für das Logging, während env_logger eine konkrete Implementierung bereitstellt, die über Umgebungsvariablen konfiguriert wird.

\n

Fügen Sie die Abhängigkeiten in Cargo.toml hinzu:

\n
[dependencies]\nlog = "0.4"\nenv_logger = "0.10"
\n

Nun ein einfaches Beispiel:

\n
use log::{info, warn, error, debug};\n\nfn main() {\n    env_logger::init();\n\n    info!("Anwendung gestartet");\n    debug!("Debug-Modus aktiv");\n    warn!("Dies ist eine Warnung");\n    error!("Ein Fehler ist aufgetreten: {}", "unbekannter Code");\n}
\n

Standardmäßig gibt env_logger nur Nachrichten der Stufe error und höher aus. Um alle Stufen zu sehen, setzen Sie die Umgebungsvariable RUST_LOG:

\n
RUST_LOG=debug cargo run
\n

Sie sehen Nachrichten aller Stufen: error, warn, info, debug und trace. Sie können auch nach Modulen filtern:

\n
RUST_LOG=my_crate=info cargo run
\n

Dies gibt nur info und höher für das Crate my_crate aus.

\n\n

Fortgeschrittenes Logging mit tracing

\n

Für komplexere Anwendungen (Webserver, asynchrone Systeme) wird die Verwendung des Crates tracing empfohlen. Es unterstützt strukturiertes Logging, Spans und Events, was besonders nützlich ist, um Aufrufketten in asynchronem Code zu verfolgen.

\n

Fügen Sie die Abhängigkeiten hinzu:

\n
[dependencies]\ntracing = "0.1"\ntracing-subscriber = "0.3"
\n

Beispiel mit Verwendung von Spans:

\n
use tracing::{info, error, span, Level};\nuse tracing_subscriber;\n\nfn main() {\n    tracing_subscriber::fmt::init();\n\n    let outer_span = span!(Level::INFO, "outer", work_id = 42);\n    let _enter = outer_span.enter();\n\n    info!("Starte Arbeit");\n    process_data();\n    info!("Arbeit abgeschlossen");\n}\n\nfn process_data() {\n    let inner_span = span!(Level::DEBUG, "process_data", data_id = 100);\n    let _enter = inner_span.enter();\n\n    // Simulation eines Fehlers\n    if true {\n        error!("Datenverarbeitungsfehler: ID {}", 100);\n    }\n}

Blogs

Buchempfehlungen