Prometheus-Metriken in Rust: Die Bibliotheken prometheus und metrics-exporter-prometheus

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

Prometheus-Metriken in Rust: Leistungsüberwachung



Prometheus ist der De-facto-Standard für die Erfassung und Analyse von Metriken in modernen Microservice-Architekturen. Im Rust-Ökosystem gibt es mehrere ausgereifte Bibliotheken, die eine einfache Integration des Metrik-Exports im Prometheus-Format ermöglichen. In diesem Artikel betrachten wir zwei Hauptbibliotheken: prometheus (offizieller Client) und metrics-exporter-prometheus (Teil des metrics-Frameworks).



Warum sind Metriken in Rust wichtig?



Das Monitoring von Rust-Anwendungen ist kritisch für:

  • Verfolgung der Leistung (Latenz, Durchsatz)
  • Erkennung von Speicherlecks und Ressourcenproblemen
  • Einrichtung von Alarmen basierend auf Schwellenwerten
  • Analyse von Trends und Kapazitätsplanung


Die Bibliothek prometheus (prometheus-rs)



Offizieller Rust-Client für Prometheus. Bietet einen vollständigen Satz von Werkzeugen zum Erstellen und Exportieren von Metriken.



Installation

Fügen Sie in Cargo.toml hinzu:

[dependencies]prometheus = { version = "0.13", features = ["process"] }hyper = { version = "0.14", features = ["http1", "server"] }


Basisbeispiel: HTTP-Server mit Metriken

use prometheus::{Counter, HistogramOpts, HistogramVec, IntCounter, Registry, TextEncoder};use std::net::SocketAddr;use hyper::{Body, Request, Response, Server};use hyper::service::{make_service_fn, service_fn};use std::convert::Infallible;use std::sync::Arc;use tokio::sync::Mutex;

#[tokio::main]async fn main() { let registry = Registry::new();

// Erstellen eines Anfragenzählers let request_counter = IntCounter::new("http_requests_total", "Total HTTP requests") .unwrap(); registry.register(Box::new(request_counter.clone())).unwrap();

// Histogramm für Antwortzeit let request_duration = HistogramVec::new( HistogramOpts::new("http_request_duration_seconds", "HTTP request duration"), &["method", "path"] ).unwrap(); registry.register(Box::new(request_duration.clone())).unwrap();

let data = Arc::new(Mutex::new((request_counter, request_duration)));

let make_svc = make_service_fn(move |_conn| { let data = data.clone(); async move { Ok::<_, Infallible>(service_fn(move |req: Request| { let data = data.clone(); async move { let start = std::time::Instant::now(); let (counter, duration) = &*data.lock().await; counter.inc();

// Anfrage verarbeiten let response = match req.uri().path() { "/metrics" => { let encoder = TextEncoder::new(); let metric_families = registry.gather(); let mut buffer = vec![]; encoder.encode(&metric_families, &mut buffer).unwrap(); Response::new(Body::from(buffer)) } "/" => Response::new(Body::from("Hello, World!")), _ => Response::builder() .status(404) .body(Body::from("Not Found")) .unwrap(), };

let elapsed = start.elapsed().as_secs_f64(); duration .with_label_values(&[req.method().as_str(), req.uri().path()]) .observe(elapsed);

Ok::<_, Infallible>(response) } })) } });

let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); let server = Server::bind(&addr).serve(make_svc); println!("Listening on http://{}", addr); if let Err(e) = server.a

Empfehlungen