Métriques Prometheus en Rust : surveiller les performances et la fiabilité
Dans le développement moderne d'applications backend en Rust, le monitoring est devenu un élément essentiel de l'infrastructure de production. Prometheus est la norme de facto pour la collecte et le stockage de métriques, et son intégration avec Rust permet de suivre les performances, la charge CPU, le nombre de requêtes, les erreurs et bien plus encore. Dans cet article, nous allons explorer deux bibliothèques principales : prometheus (le client officiel) et metrics + metrics-exporter-prometheus (une approche plus abstraite).
Pourquoi utiliser des métriques en Rust ?
Les métriques permettent de :
- Surveiller l'état de votre service en temps réel
- Identifier les goulots d'étranglement (latence, erreurs)
- Créer des tableaux de bord dans Grafana
- Configurer des alertes (par exemple, en cas de baisse du QPS ou d'augmentation des erreurs)
Installation et configuration de la bibliothèque prometheus
Ajoutez ceci à votre Cargo.toml :
[dependencies]
prometheus = { version = "0.13", features = ["process"] }
actix-web = "4" # pour l'exemple avec le serveur web
tokio = { version = "1", features = ["full"] }
La bibliothèque prometheus propose trois types de métriques principaux : Counter, Gauge, Histogram.
Exemple : création et enregistrement de métriques
use prometheus::{Counter, Gauge, Histogram, HistogramOpts, Opts, Registry};
fn main() {
// Création du registre de métriques
let registry = Registry::new();
// Counter — compteur de requêtes
let request_counter = Counter::with_opts(
Opts::new("http_requests_total", "Total HTTP requests")
.const_label("service", "my_app")
).unwrap();
registry.register(Box::new(request_counter.clone())).unwrap();
// Gauge — nombre actuel de connexions actives
let active_connections = Gauge::with_opts(
Opts::new("active_connections", "Number of active connections")
).unwrap();
registry.register(Box::new(active_connections.clone())).unwrap();
// Histogram — distribution du temps de réponse
let request_duration = Histogram::with_opts(
HistogramOpts::new("http_request_duration_seconds", "Request duration in seconds")
.buckets(vec![0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0])
).unwrap();
registry.register(Box::new(request_duration.clone())).unwrap();
// Simulation d'utilisation
request_counter.inc();
active_connections.set(42.0);
request_duration.observe(0.123);
}
Export des métriques via HTTP (actix-web)
Pour que Prometheus puisse collecter les métriques, il faut les exposer au format /metrics :
use actix_web::{web, App, HttpServer, HttpResponse, Responder};
use prometheus::{Encoder, TextEncoder, Registry};
use std::sync::Arc;
async fn metrics_handler(registry: web::Data<Arc<Registry>>) -> impl Responder {
let encoder = TextEncoder::new();
let mut buffer = Vec::new();
encoder.encode(®istry.gather(), &mut buffer).unwrap();
HttpResponse::Ok()
.content_type("text/plain; charset=utf-8")
.body(buffer)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let registry = Arc::new(Registry::new());
// ... enregistrez les métriques comme ci-dessus ...
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(registry.clone()))
.route("/metrics", web::get().to(metrics_handler))
})
.bind("127.0.0.1:9090")?
.run()
.await
}
La bibliothèque metrics — une approche haut niveau
Une alternative est la crate metrics avec l'exportateur metrics-exporter-prometheus. Elle fournit des macros pour créer rapidement des métriques :
[dependencies]
metrics = "0.21"
metrics-exporter-prometheus = "0.12"
use metrics::{counter, gauge, histogram};
use metrics_exporter