Métriques Prometheus en Rust : bibliothèques prometheus et metrics-exporter-prometheus

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Métriques Prometheus en Rust : surveillance des performances



Prometheus est la norme de facto pour la collecte et l'analyse de métriques dans les architectures microservices modernes. Dans l'écosystème Rust, il existe plusieurs bibliothèques matures permettant d'intégrer facilement l'export de métriques au format Prometheus. Dans cet article, nous examinerons deux bibliothèques principales : prometheus (le client officiel) et metrics-exporter-prometheus (partie du framework metrics).



Pourquoi des métriques en Rust ?



La surveillance des applications Rust est essentielle pour :

  • Suivre les performances (latence, débit)
  • Détecter les fuites mémoire et les problèmes de ressources
  • Configurer des alertes basées sur des seuils
  • Analyser les tendances et planifier la capacité


Bibliothèque prometheus (prometheus-rs)



Le client Rust officiel pour Prometheus. Il fournit un ensemble complet d'outils pour créer et exporter des métriques.



Installation

Ajoutez dans Cargo.toml :

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


Exemple de base : serveur HTTP avec métriques

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();

// Création d'un compteur de requêtes let request_counter = IntCounter::new("http_requests_total", "Total HTTP requests") .unwrap(); registry.register(Box::new(request_counter.clone())).unwrap();

// Histogramme pour le temps de réponse 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();

// Traitement de la requête 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

Recommendations