Prometheus¶
Prometheus est le puits de métriques unique de PerfShop. Il scrape trois cibles toutes les 5 secondes, conserve les séries temporelles pendant 7 jours, et alimente les datasources de Grafana ainsi que le panneau de service-graphs/span-metrics produit par Tempo.
Source de vérité
Cette page est tirée de prometheus/prometheus.yml et des command: du service prometheus dans les fichiers compose.
Configuration globale¶
global:
scrape_interval: 15s # défaut, surchargé par chaque job à 5s
evaluation_interval: 15s # défaut, pour les rules
Le service Prometheus est lancé avec ces options de ligne de commande explicites :
--config.file=/etc/prometheus/prometheus.yml
--storage.tsdb.path=/prometheus
--storage.tsdb.retention.time=7d
--storage.tsdb.retention.size=5GB
--web.console.libraries=/usr/share/prometheus/console_libraries
--web.console.templates=/usr/share/prometheus/consoles
--web.enable-remote-write-receiver
--web.enable-lifecycle
| Option | Effet |
|---|---|
--storage.tsdb.retention.time=7d |
Suppression automatique des séries de plus de 7 jours |
--storage.tsdb.retention.size=5GB |
Cap dur sur la taille du TSDB |
--web.enable-remote-write-receiver |
Active l'endpoint /api/v1/write — utilisé par Tempo (metrics_generator) pour pousser ses métriques de span-metrics et service-graphs |
--web.enable-lifecycle |
Active /-/reload et /-/quit pour rechargement à chaud sans restart |
Le port management interne est 9090, exposé sur le port hôte 9091 par défaut (variable PROMETHEUS_HTTP_PORT).
Cibles scrapées¶
PerfShop déclare trois jobs Prometheus, tous avec un scrape_interval: 5s (plus agressif que le défaut global de 15 s, pour permettre une observation fine en temps réel pendant les démonstrations chaos).
flowchart LR
PROM["prometheus<br/>(9090 interne)"]
subgraph t1["Job perfshop-backend"]
APP["perfshop-app:9090<br/>/actuator/prometheus"]
end
subgraph t2["Job perfshop-docker"]
MON["perfshop-monitoring:3001<br/>/metrics"]
end
subgraph t3["Job jmeter"]
JM["perfshop-jmeter:9270<br/>(actif pendant un tir uniquement)"]
end
PROM -->|scrape 5s| APP
PROM -->|scrape 5s| MON
PROM -->|scrape 5s| JM
Job perfshop-backend¶
- job_name: 'perfshop-backend'
static_configs:
- targets: ['perfshop-app:9090']
metrics_path: '/actuator/prometheus'
scrape_interval: 5s
C'est le job principal. Il scrape l'endpoint Spring Boot Actuator exposé par Micrometer sur le port management 9090 (séparé du port applicatif 8080 — c'est volontaire, pour ne pas mélanger trafic métier et trafic d'observabilité). Toutes les métriques JVM, HTTP, JDBC, Tomcat, et les compteurs custom du chaos sont produits par ce seul endpoint.
Les principales familles de métriques scrapées :
| Famille | Préfixe / nom | Origine |
|---|---|---|
| HTTP serveur | http_server_requests_seconds_* |
Micrometer auto-config Spring Boot Web |
| JVM mémoire | jvm_memory_used_bytes, jvm_memory_max_bytes, jvm_memory_committed_bytes |
Micrometer JVM binder |
| JVM threads | jvm_threads_live_threads, jvm_threads_daemon_threads, jvm_threads_peak_threads, jvm_threads_states_threads |
Micrometer JVM binder |
| JVM GC | jvm_gc_pause_seconds_count, jvm_gc_pause_seconds_sum |
Micrometer JVM binder |
| Tomcat | tomcat_threads_busy_threads, tomcat_threads_current_threads, tomcat_threads_config_max_threads |
Micrometer Tomcat binder (activé via management.metrics.enable.tomcat=true) |
| HikariCP | hikaricp_connections_active, _idle, _max, _pending, _acquire_seconds_* |
Micrometer HikariCP binder, label pool="PerfShopHikariPool" |
| Process | process_cpu_usage, process_uptime_seconds, process_files_open_files |
Micrometer process binder |
| Chaos custom | chaos_intensity{type="cpu|memory|thread_pool|db_pool|slow_query|deadlock|network"}, chaos_functional_level, chaos_functional_f4_corruption |
Compteurs custom déclarés dans les services chaos du backend |
L'activation de l'histogramme HTTP est faite dans application.yml :
Sans cette ligne, les requêtes histogram_quantile() sur http_server_requests_seconds_bucket ne fonctionneraient pas (les buckets ne seraient pas exportés).
Job perfshop-docker¶
- job_name: 'perfshop-docker'
static_configs:
- targets: ['perfshop-monitoring:3001']
metrics_path: '/metrics'
scrape_interval: 5s
Le service perfshop-monitoring (Node + Express) interroge l'API Docker via le socket Unix monté en bind mount, calcule les statistiques CPU/RAM/réseau/I/O des principaux containers, et les expose au format Prometheus sur sa propre route /metrics. Voir dashboard-html.md pour le détail.
Les métriques produites par ce job utilisent toutes le préfixe docker_container_ :
| Métrique | Type | Description |
|---|---|---|
docker_container_cpu_percent{container="..."} |
gauge | Pourcentage CPU calculé (cpuDelta / sysDelta) × numCpus × 100 |
docker_container_mem_usage_bytes{container="..."} |
gauge | Mémoire utilisée (hors cache) |
docker_container_mem_limit_bytes{container="..."} |
gauge | Limite mémoire du container |
docker_container_mem_percent{container="..."} |
gauge | Pourcentage mémoire utilisée |
docker_container_net_rx_bytes{container="..."} |
counter | Octets reçus cumulés |
docker_container_net_tx_bytes{container="..."} |
counter | Octets envoyés cumulés |
docker_container_io_read_bytes{container="..."} |
counter | Octets lus disque cumulés |
docker_container_io_write_bytes{container="..."} |
counter | Octets écrits disque cumulés |
docker_container_pids{container="..."} |
gauge | Nombre de processus dans le container |
Et des métriques navigateur poussées par chaos-agent.js depuis le frontend toutes les 2 secondes (POST /api/chaos/client-metrics), qui sont ré-exposées sur la route /metrics :
| Métrique | Description |
|---|---|
perfshop_client_fps |
FPS mesuré dans le navigateur de l'étudiant |
perfshop_client_heap_used_mb |
Heap JS utilisée (Mo) |
perfshop_client_long_tasks_per_sec |
Long tasks (tâches > 50 ms) par seconde |
perfshop_client_fetch_req_per_sec |
Requêtes fetch lancées par seconde |
perfshop_client_dom_node_count |
Nombre de nœuds DOM |
perfshop_client_cpu_worker_active |
1 si un Web Worker CPU-intensive tourne dans le navigateur |
perfshop_client_last_received_timestamp |
Timestamp Unix (ms) du dernier envoi reçu — utile pour calculer la fraîcheur |
Containers surveillés
Le code Node de perfshop-monitoring ne surveille que quatre containers : perfshop-frontend, perfshop-app, perfshop-db, perfshop-monitoring. C'est volontaire — le dashboard HTML cible la chaîne « front → back → BDD » et le tableau Grafana « Vue Générale Containers » utilise le même job.
Job jmeter¶
- job_name: 'jmeter'
static_configs:
- targets: ['perfshop-jmeter:9270']
scrape_interval: 5s
honor_labels: true
Le container perfshop-jmeter est idle en permanence (tail -f /dev/null). Il n'expose rien sur le port 9270 entre les tirs. Quand un tir est lancé via perfshop-jmeter-ui, le plugin Prometheus listener de JMeter ouvre le port 9270 pendant la durée du tir et expose les métriques jmeter_*. Une fois le tir terminé, le port se ferme et Prometheus loggue des erreurs de scrape — c'est normal et attendu, et c'est documenté en commentaire dans prometheus.yml.
honor_labels: true permet aux labels exportés par JMeter (notamment label="..." qui correspond au nom du sampler) de ne pas être écrasés par les labels du job Prometheus.
Métriques exposées par le plugin JMeter Prometheus listener :
| Métrique | Description |
|---|---|
jmeter_threads{state="active|started|finished"} |
Threads virtuels (vUsers) actifs / démarrés / terminés |
jmeter_transactions_total{label="..."} |
Compteur cumulé de transactions par sampler |
jmeter_response_time{quantile="0.5|0.95|0.99",label="..."} |
Quantiles de latence par sampler |
jmeter_response_time_count{label="..."} |
Compteur d'échantillons par sampler |
jmeter_response_time_sum{label="..."} |
Somme cumulée des latences (pour calcul de moyenne) |
jmeter_success_ratio_success{label="..."} |
Compteur de succès |
jmeter_success_ratio_failure{label="..."} |
Compteur d'échecs |
Exemples de requêtes PromQL¶
Toutes les requêtes ci-dessous sont extraites des dashboards Grafana réellement livrés dans grafana/dashboards/{eleves,formateurs}/*.json. Elles sont donc à la fois pédagogiques et représentatives de l'usage réel.
1. Latence HTTP percentile p95 — toutes routes confondues¶
histogram_quantile(
0.95,
sum(rate(http_server_requests_seconds_bucket{job="perfshop-backend"}[5m])) by (le)
) * 1000
C'est la requête de référence pour observer la latence globale du backend. Le * 1000 convertit les secondes en millisecondes. La fenêtre [5m] est suffisamment large pour absorber les variations courtes, tout en restant réactive.
Variantes : 0.50 pour la médiane, 0.99 pour le p99. Le panel « Temps de réponse HTTP » utilise les trois en parallèle.
2. Taux d'erreur HTTP 5xx (en pourcentage)¶
sum(rate(http_server_requests_seconds_count{job="perfshop-backend",outcome="SERVER_ERROR"}[5m]))
/
sum(rate(http_server_requests_seconds_count{job="perfshop-backend"}[5m]))
* 100
Utilise le label outcome produit par Spring Boot Actuator (SUCCESS, CLIENT_ERROR, SERVER_ERROR, INFORMATIONAL, REDIRECTION, UNKNOWN).
3. Heap JVM utilisé (somme de tous les pools heap)¶
area="heap" filtre les pools mémoire heap (Eden, Survivor, Old Gen). Pour la heap maximale :
4. Pool HikariCP — connexions actives vs max¶
hikaricp_connections_active{job="perfshop-backend"}
hikaricp_connections_idle{job="perfshop-backend"}
hikaricp_connections_max{job="perfshop-backend"}
hikaricp_connections_pending{job="perfshop-backend"}
Les quatre métriques sont superposées dans le panel « Connexions BDD — État du pool HikariCP » du dashboard Backend Élève. Quand pending > 0, c'est qu'on attend une connexion — symptôme typique d'une exhaustion du pool, déclenchée par le chaos backend db_pool.
5. Latence d'acquisition d'une connexion BDD¶
rate(hikaricp_connections_acquire_seconds_sum{pool="PerfShopHikariPool"}[1m])
/
rate(hikaricp_connections_acquire_seconds_count{pool="PerfShopHikariPool"}[1m])
* 1000
Calcule la moyenne en millisecondes du temps passé à attendre une connexion HikariCP. Le label pool="PerfShopHikariPool" vient du nom configuré dans application.yml (spring.datasource.hikari.pool-name).
6. Threads HTTP Tomcat — occupés vs configurés¶
tomcat_threads_busy_threads{job="perfshop-backend"}
tomcat_threads_current_threads{job="perfshop-backend"}
tomcat_threads_config_max_threads{job="perfshop-backend"}
Les trois courbes ensemble : busy ≤ current ≤ config_max. Quand busy colle à config_max, c'est l'exhaustion du pool de threads HTTP — déclenchée par le chaos backend thread_pool.
7. Débit de requêtes 2xx vs 5xx vs 4xx¶
rate(http_server_requests_seconds_count{job="perfshop-backend",status=~"2.."}[1m])
rate(http_server_requests_seconds_count{job="perfshop-backend",status=~"5.."}[1m])
rate(http_server_requests_seconds_count{job="perfshop-backend",status=~"4.."}[1m])
Utilise les regex sur le label status. Les trois séries sont empilées dans le panel « Débit requêtes HTTP » pour visualiser le ratio.
8. Intensité courante des chaos (type par type)¶
chaos_intensity{type="cpu"}
chaos_intensity{type="memory"}
chaos_intensity{type="thread_pool"}
chaos_intensity{type="db_pool"}
chaos_intensity{type="slow_query"}
chaos_intensity{type="deadlock"}
chaos_intensity{type="network"}
C'est une gauge custom déclarée par le service ChaosService du backend. Sa valeur (entre 0 et 100, ou 0 et le niveau max) reflète l'intensité courante de chaque chaos backend. Le panel Formateur « Évolution temporelle des anomalies chaos » superpose les sept séries pour donner une vue globale de ce qui est actif.
Bonus — comptage des opérations instrumentées¶
Retourne le nombre d'URIs distinctes connues par Spring Boot. Utile pour confirmer que de nouveaux endpoints ont bien été instrumentés après une mise à jour du backend.
Erreurs de scrape attendues¶
Le job jmeter clignote en rouge entre les tirs — c'est normal
Tant qu'aucun tir JMeter n'est en cours, le port 9270 n'est ouvert par aucun process — Prometheus loggue donc une erreur de scrape pour cette cible. C'est intentionnel et documenté en commentaire dans prometheus.yml. Si vous voulez masquer ces erreurs en démo, désactivez temporairement le job dans Prometheus, ou ignorez la série dans Grafana.
Endpoints utiles côté Prometheus¶
| Endpoint | Usage |
|---|---|
http://localhost:9091/ |
UI Prometheus |
http://localhost:9091/targets |
État des cibles scrapées |
http://localhost:9091/graph |
Console de requêtage PromQL |
http://localhost:9091/api/v1/write |
Endpoint remote-write (utilisé par Tempo) |
http://localhost:9091/-/reload |
Recharge la configuration sans restart |
http://localhost:9091/-/healthy |
Healthcheck |
Pour aller plus loin¶
- Vue d'ensemble — flux global d'observabilité
- Grafana — datasource Prometheus et exploration
- Dashboards livrés — détail panel par panel des 10 dashboards
- Tempo —
metrics_generatorqui pousse ses span-metrics dans Prometheus via remote-write - Dashboard HTML temps réel — code Node qui produit les métriques
docker_container_*