Überwachung von Rust-Anwendungen: Metriken und Alarme von A bis Z

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

Überwachung von Rust-Anwendungen: Metriken und Alarme von A bis Z

\n\n

Wenn Ihre Rust-Anwendung in die Produktion geht, ist der Code nicht mehr nur Code. Er wird zu einem Dienst, von dem Benutzer und Unternehmen abhängen. Ohne Überwachung fliegen Sie blind: Ausfälle werden durch Beschwerden entdeckt, und die Leistung wird „nach Augenmaß“ bewertet. In diesem Artikel werden wir uns ansehen, wie Sie ein vollständiges Überwachungssystem für Rust aufbauen – von der Erfassung grundlegender Metriken bis zur Konfiguration von Alarmen in Prometheus und der Visualisierung in Grafana.

\n\n

1. Warum Überwachung für Rust-Projekte wichtig ist

\n

Rust ist bekannt für seine Leistung und Speichersicherheit, aber das macht es nicht überflüssig, die Anwendung im Auge zu behalten. Typische Probleme in der Produktion:

\n
    \n
  • Speicherlecks (z. B. durch Arc oder zyklische Referenzen).
  • \n
  • Blockierungen in async-Code (Deadlocks oder Starvation in tokio).
  • \n
  • Unerwartete Paniken (selbst mit catch_unwind).
  • \n
  • Leistungsverschlechterung durch suboptimale Algorithmen.
  • \n
\n

Überwachung liefert Antworten auf die Fragen: „Was passiert gerade?“, „Warum ist das passiert?“ und „Wie kann man es verhindern?“.

\n\n

2. Metrikerfassung: Die Bibliothek metrics und Export nach Prometheus

\n

Der Standard-Stack für Rust ist die Crate metrics (oder prometheus). Wir verwenden metrics, da es den Export abstrahiert und das Backend leicht gewechselt werden kann.

\n\n

2.1. Installation und grundlegende Konfiguration

\n

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

\n
[dependencies]\nmetrics = "0.21"\nmetrics-exporter-prometheus = "0.12"\ntokio = { version = "1", features = ["full"] }
\n\n

Wir erstellen einen einfachen HTTP-Server für den Endpunkt /metrics:

\n
use metrics_exporter_prometheus::PrometheusBuilder;\nuse std::net::SocketAddr;\nuse tokio::net::TcpListener;\n\n#[tokio::main]\nasync fn main() {\n    // Initialisieren des Prometheus-Exporters\n    let (recorder, exporter) = PrometheusBuilder::new()\n        .build()\n        .expect("Konnte den Prometheus-Exporter nicht erstellen");\n\n    metrics::set_boxed_recorder(Box::new(recorder))\n        .expect("Konnte den globalen Recorder nicht setzen");\n\n    // Starten des Metrik-Servers\n    let addr: SocketAddr = "0.0.0.0:9090".parse().unwrap();\n    let listener = TcpListener::bind(addr).await.unwrap();\n    println!("Metriken verfügbar unter http://{}", addr);\n\n    loop {\n        let (mut stream, _) = listener.accept().await.unwrap();\n        let body = exporter.encode().unwrap();\n        let response = format!(\n            "HTTP/1.1 200 OK\\r\\nContent-Type: text/plain\\r\\nContent-Length: {}\\r\\n\\r\\n{}",\n            body.len(),\n            body\n        );\n        tokio::io::AsyncWriteExt::write_all(&mut stream, response.as_bytes())\n            .await\n            .unwrap();\n    }\n}
\n\n

2.2. Registrierung benutzerdefinierter Metriken

\n

Fügen wir einen Anfragezähler und ein Histogramm der Antwortzeit hinzu:

\n
use metrics::{counter, histogram, increment_counter};\nuse std::time::Instant;\n\nasync fn handle_request() {\n    let start = Instant::now();\n\n    // Ihre Geschäftslogik\n    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;\n\n    // Metriken aufzeichnen\n    increment_counter!("http_requests_total", "method" => "GET");\n    histogram!("http_request_duration_seconds", start.elapsed().as_secs_f64(), "method" => "GET");\n}
\n

Jetzt sehen Sie unter /metrics:

\n
# HELP http_requests_total Total HTTP requests\n# TYPE http_requests_total counter\nhttp_requests_total{method="GET"} 1\n# HELP http_request_duration_seconds HTTP request duration\n# TYPE http_request_duration_seconds histogram\nhttp_request_duration_seconds_bucket{method="GET",le="0.005"} 0\nhttp_request_duration_seconds_bucket{method="GET",le="0.01"} 0\nhttp_request_duration_seconds_bucket{method="GET",le="0.025"} 0\n                

Blogs

Buchempfehlungen