Surveillance des applications Rust : métriques et alertes de A à Z

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

Surveillance des applications Rust : métriques et alertes de A à Z

\n\n

Lorsque votre application Rust passe en production, le code cesse d'être simplement du code. Il devient un service dont dépendent les utilisateurs et l'entreprise. Sans surveillance, vous volez à l'aveugle : les pannes sont détectées par les plaintes, et les performances sont évaluées « à l'œil ». Dans cet article, nous allons voir comment construire un système de surveillance complet pour Rust — de la collecte des métriques de base à la configuration des alertes dans Prometheus et la visualisation dans Grafana.

\n\n

1. Pourquoi la surveillance est importante pour les projets Rust

\n

Rust est réputé pour ses performances et sa sécurité mémoire, mais cela ne dispense pas de surveiller l'application. Problèmes typiques en production :

\n
    \n
  • Fuites mémoire (par exemple via Arc ou les références cycliques).
  • \n
  • Blocages dans le code async (deadlocks ou starvation dans tokio).
  • \n
  • Pannes inattendues (même avec catch_unwind).
  • \n
  • Dégradation des performances due à des algorithmes non optimaux.
  • \n
\n

La surveillance répond aux questions : « Que se passe-t-il actuellement ? », « Pourquoi cela s'est-il produit ? » et « Comment l'éviter ? ».

\n\n

2. Collecte des métriques : bibliothèque metrics et export vers Prometheus

\n

La pile standard pour Rust est la crate metrics (ou prometheus). Nous utilisons metrics car il abstrait l'export et change facilement de backend.

\n\n

2.1. Installation et configuration de base

\n

Ajoutez les dépendances dans Cargo.toml :

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

Créons un serveur HTTP simple pour le point d'accès /metrics :

\n
use metrics_exporter_prometheus::PrometheusBuilder;\nuse std::net::SocketAddr;\nuse tokio::net::TcpListener;\n\n#[tokio::main]\nasync fn main() {\n    // Initialisation de l'exportateur Prometheus\n    let (recorder, exporter) = PrometheusBuilder::new()\n        .build()\n        .expect("Impossible de créer l'exportateur Prometheus");\n\n    metrics::set_boxed_recorder(Box::new(recorder))\n        .expect("Impossible de définir l'enregistreur global");\n\n    // Démarrage du serveur de métriques\n    let addr: SocketAddr = "0.0.0.0:9090".parse().unwrap();\n    let listener = TcpListener::bind(addr).await.unwrap();\n    println!("Métriques disponibles sur 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. Enregistrement de métriques personnalisées

\n

Ajoutons un compteur de requêtes et un histogramme du temps de réponse :

\n
use metrics::{counter, histogram, increment_counter};\nuse std::time::Instant;\n\nasync fn handle_request() {\n    let start = Instant::now();\n\n    // Votre logique métier\n    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;\n\n    // Enregistrement des métriques\n    increment_counter!("http_requests_total", "method" => "GET");\n    histogram!("http_request_duration_seconds", start.elapsed().as_secs_f64(), "method" => "GET");\n}
\n

Maintenant, sur /metrics vous verrez :

\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

Book Recommendations