Files
ENI-projet-piscine/monitoring/prometheus/tests/enervision.test.yml
T
Johan LEROY dc952d13aa feat(monitoring): supervise l'API, la base et l'hôte avec Prometheus et Grafana
L'API exposait /metrics, mais aucun collecteur ne le lisait : monitoring/ ne contenait que des
.gitkeep.

Sous le profil Compose `monitoring` : prometheus, alertmanager, grafana, postgres-exporter,
node-exporter et cadvisor. Tous ont un mem_limit, pour environ 700 Mo au total sur la VM de 8 Go,
et leurs interfaces n'écoutent que sur 127.0.0.1. Le profil est actif en prod via
COMPOSE_PROFILES, donc à chaque déploiement, et se lance à la demande ailleurs
(make monitoring-up).

- Neuf règles d'alerte (API, base, hôte, cibles). Chacune a un cas dans les tests joués par
  `promtool test rules`, en CI comme par make monitoring-check.
- Alertmanager route les alertes par courriel vers Mailpit ; un critical masque le warning de la
  même cible.
- Grafana est provisionné : sources Prometheus et TimescaleDB, et trois tableaux de bord (API,
  données et dérive du modèle, infrastructure).
- Le rôle PostgreSQL `supervision` est en lecture seule sur les seules tables métier
  (db/roles/supervision.sql), posé par make db-ensure-supervision et par stack-up quand le
  profil est actif.
- Le jeton de /metrics passe à Prometheus en secret Compose (APP_METRICS_TOKEN) ;
  provision-host.sh génère ce secret et les deux autres.

Backend :
- un APP_METRICS_TOKEN vide vaut absent ;
- les sondes de santé ne comptent plus dans les métriques ;
- seaux de latence fins autour de 500 ms ;
- un registre Prometheus par application, sans quoi toute application créée après la première
  (dans les tests) ne mesurait rien.

Réf : #26
2026-09-23 09:41:12 +02:00

113 lines
4.0 KiB
YAML

rule_files:
- ../rules/enervision.yml
evaluation_interval: 1m
tests:
- name: l'API injoignable déclenche une alerte critique au bout de 2 minutes
interval: 1m
input_series:
- series: 'up{job="backend", instance="backend:8000"}'
values: "1 0 0 0 0"
alert_rule_test:
- eval_time: 2m
alertname: ApiIndisponible
exp_alerts: []
- eval_time: 3m
alertname: ApiIndisponible
exp_alerts:
- exp_labels:
severity: critical
job: backend
instance: backend:8000
exp_annotations:
summary: "L'API ne répond plus"
description: "Prometheus ne joint plus backend:8000 depuis 2 minutes."
- name: une API qui répond ne déclenche rien
interval: 1m
input_series:
- series: 'up{job="backend", instance="backend:8000"}'
values: "1x10"
alert_rule_test:
- eval_time: 10m
alertname: ApiIndisponible
exp_alerts: []
- name: dix pour cent de 5xx déclenchent l'alerte d'erreurs serveur
interval: 1m
input_series:
- series: 'http_requests_total{job="backend", handler="/api/v1/sites", method="GET", status="5xx"}'
values: "0+10x20"
- series: 'http_requests_total{job="backend", handler="/api/v1/sites", method="GET", status="2xx"}'
values: "0+90x20"
alert_rule_test:
- eval_time: 12m
alertname: ApiErreursServeur
exp_alerts:
- exp_labels:
severity: critical
exp_annotations:
summary: "Plus de 5 % de réponses 5xx"
description: "10% des réponses de l'API sont des erreurs serveur."
- name: un p95 au-delà d'une seconde déclenche l'alerte de latence
interval: 1m
input_series:
- series: 'http_request_duration_highr_seconds_bucket{job="backend", le="0.5"}'
values: "0x30"
- series: 'http_request_duration_highr_seconds_bucket{job="backend", le="1"}'
values: "0x30"
- series: 'http_request_duration_highr_seconds_bucket{job="backend", le="2"}'
values: "0+10x30"
- series: 'http_request_duration_highr_seconds_bucket{job="backend", le="+Inf"}'
values: "0+10x30"
alert_rule_test:
- eval_time: 20m
alertname: ApiLatenceElevee
exp_alerts:
- exp_labels:
severity: warning
exp_annotations:
summary: "p95 de l'API au-dessus d'une seconde"
description: "Le p95 des réponses vaut 1.95s depuis 10 minutes."
- name: la mémoire de l'hôte au-delà de 90 % déclenche un avertissement
interval: 1m
input_series:
- series: 'node_memory_MemAvailable_bytes{job="node", instance="node-exporter:9100"}'
values: "500000000x15"
- series: 'node_memory_MemTotal_bytes{job="node", instance="node-exporter:9100"}'
values: "10000000000x15"
alert_rule_test:
- eval_time: 12m
alertname: HoteMemoireSaturee
exp_alerts:
- exp_labels:
severity: warning
job: node
instance: node-exporter:9100
exp_annotations:
summary: "Mémoire de l'hôte au-delà de 90 %"
description: "95% de la mémoire est utilisée, recette et prod comprises."
- name: un exportateur muet déclenche l'alerte de cible, pas celle de l'API
interval: 1m
input_series:
- series: 'up{job="postgres", instance="postgres-exporter:9187"}'
values: "0x10"
alert_rule_test:
- eval_time: 6m
alertname: CibleInjoignable
exp_alerts:
- exp_labels:
severity: warning
job: postgres
instance: postgres-exporter:9187
exp_annotations:
summary: "Cible de supervision injoignable"
description: "Prometheus ne joint plus postgres (postgres-exporter:9187) depuis 5 minutes."
- eval_time: 6m
alertname: ApiIndisponible
exp_alerts: []