- ADR 0014 : un pipeline CI unique, « CI ok » seul check à exiger, déploiement du commit testé. - ADR 0015 : e2e et charge contre la stack Compose déployée, hypothèses et seuils de k6. - ADR 0016 : supervision en profil Compose, active en prod, rôle en lecture seule. - Nouvelle vue 60-observabilite.md ; 00-vue-ensemble, 10-infra, 20-backend et 50-cicd mis à jour (monitoring passé à Fait, nouveau graphe de CI, gates, ports). - README racine et guide de tests du frontend : où sont l'e2e, la charge et la supervision.
5.7 KiB
Observabilité
Ce document décrit ce qu'on voit du système en fonctionnement : métriques, tableaux de bord,
alertes et journaux. Décision dans l'ADR 0016,
mode d'emploi dans monitoring/README.md.
| Brique | Sert à | Statut |
|---|---|---|
| Métriques de l'API | Débit, erreurs et latences par route | Fait |
| Collecte et alertes | Prometheus, neuf règles testées, Alertmanager vers Mailpit | Fait |
| Tableaux de bord | Grafana : API, données et modèle, infrastructure | Fait |
| Métriques d'Airflow | StatsD ou OpenTelemetry des DAGs | Cible |
| Journaux centralisés | Loki ou équivalent | Cible |
Vue d'ensemble
flowchart LR
subgraph projet["Projet Compose de la prod"]
api["backend<br/>/metrics"]
db[("db<br/>TimescaleDB")]
mail["mailpit"]
subgraph sup["Profil monitoring"]
prom["prometheus<br/>15 s, 15 jours"]
am["alertmanager"]
graf["grafana"]
pge["postgres-exporter"]
node["node-exporter"]
cad["cadvisor"]
end
end
hote["Hôte : VM ENI<br/>recette et prod"]
prom -->|"Bearer APP_METRICS_TOKEN"| api
prom --> pge & node & cad
pge -->|"rôle supervision"| db
node -.->|"/proc, /sys"| hote
cad -.->|"cgroups"| hote
prom -->|"règles franchies"| am -->|"SMTP"| mail
graf --> prom
graf -->|"rôle supervision, SQL"| db
Tout vit dans le projet Compose de la prod, sur son réseau. La recette n'a pas de supervision
propre. node-exporter et cAdvisor voient pourtant tout l'hôte : la mémoire de la VM et de chaque
conteneur couvre donc aussi la recette, qu'on distingue au préfixe enervision-rec-.
Ce que mesure chaque source
| Source | Métriques utiles | Où les lire |
|---|---|---|
API (prometheus-fastapi-instrumentator) |
http_requests_total par route et classe de statut, http_request_duration_seconds par route (seaux 50 ms à 2,5 s), http_request_duration_highr_seconds global, mémoire du processus |
Tableau « API » |
| postgres-exporter | pg_up, connexions par état, max_connections, transactions validées, taille des bases |
Tableau « Infrastructure » |
| node-exporter | Processeur, mémoire disponible, espace disque de / |
Tableau « Infrastructure » |
| cAdvisor | Mémoire (working_set) et processeur par conteneur |
Tableau « Infrastructure » |
| TimescaleDB, en SQL | Fraîcheur des relevés par site, relevés ingérés par heure, alertes par sévérité, drift_report |
Tableau « Données et modèle » |
Deux choix de l'instrumentation se lisent dans ces courbes :
- Les sondes
/health/*et/metricsne sont pas comptées. La sonde Docker frappe toutes les 30 s : incluse, elle ferait baisser la latence moyenne et gonfler le débit d'une API au repos. - Les seaux par route encadrent 500 ms, seuil de charge de l'ADR 0015. Grafana lit ainsi le même p95 que k6 pendant un tir.
Alertes
| Groupe | Alertes | Sévérité |
|---|---|---|
| API | Indisponible 2 min, 5xx au-delà de 5 %, p95 au-delà d'une seconde | critical, critical, warning |
| Base | PostgreSQL injoignable 2 min, connexions au-delà de 80 % | critical, warning |
| Hôte | Mémoire au-delà de 90 %, disque sous 10 %, processeur au-delà de 90 % | warning, critical, warning |
| Supervision | Un exporteur muet 5 min | warning |
- Tests des règles. Chaque règle a un cas dans
monitoring/prometheus/tests/, joué parpromtool test rulesdans le job Infra de la CI. Une règle qui ne se déclenche plus, ou se déclenche à tort, casse la CI avant d'atteindre la prod. - Envoi. Alertmanager groupe les alertes par nom et sévérité et les envoie par courriel via
Mailpit, qui les capture sans rien relayer. Un
criticalest rappelé toutes les heures, unwarningtoutes les douze. Uncriticalmasque lewarningde la même cible.
Sécurité
- Aucune interface exposée. Prometheus, Alertmanager et Grafana n'écoutent que sur
127.0.0.1, et rien ne passe par le proxy (ADR 0007). Accès par tunnel SSH. /metricsgardé par jeton. Il n'est pas routé par nginx, et Prometheus y présenteAPP_METRICS_TOKEN, que l'API exige dès qu'il est posé. Le jeton lui parvient en secret Compose, jamais en clair dans sa configuration.- Base en lecture seule. Grafana et postgres-exporter lisent la base par le rôle
supervision, en lecture seule, limité aux tables métier (db/roles/supervision.sql). Ils n'ont niapp_user, ni jetons, ni journal d'audit. - Grafana verrouillé. Il refuse de démarrer sans
GRAFANA_ADMIN_PASSWORD. Inscription, accès anonyme et appels sortants (statistiques d'usage, vérification de mises à jour) y sont désactivés. - cAdvisor en
privileged. Il tourne ainsi pour lire les cgroups, avec des montages en lecture seule et sans port publié.
Journaux
Les journaux restent ceux de Docker : docker compose logs, make stack-logs,
make monitoring-logs. L'API écrit du JSON dès APP_ENV=prod, caviardé des jetons et des mots
de passe (voir 20-backend.md). Aucune agrégation centralisée n'est en place.
Ce qui manque
| Manque | Conséquence assumée |
|---|---|
| Métriques d'Airflow (StatsD, OpenTelemetry) | Un DAG qui échoue ne se voit que dans Airflow ; le tableau « Données » le trahit indirectement par des relevés qui vieillissent |
| Alerte sur la fraîcheur des relevés | Visible dans Grafana, mais aucune règle Prometheus ne la porte : il faudrait une métrique calculée par l'API ou un exportateur SQL |
| Journaux centralisés | Un incident se diagnostique conteneur par conteneur |
| Destinataire réel des alertes | Mailpit capture tout : les alertes se lisent dans son interface, elles ne réveillent personne |