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

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 : 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                    

Recommendations