Suppression de tous les exemples de code pour garder uniquement les descriptions techniques : ADR-023 (Architecture Modération) : - Diagramme Mermaid → description flux textuelle - Exemples SQL/Redis → description workflow - Interface Go → description abstraction - Dépendances → liste concise ADR-024 (Monitoring et Observabilité) : - Diagramme Mermaid → architecture textuelle - Exemples PromQL → description métriques - Config YAML alertes → liste alertes avec seuils - Commandes bash WAL-E → description backup - Runbooks → étapes sans commandes ADR-025 (Sécurité et Secrets) : - Diagramme Mermaid → flux secrets textuel - Commandes bash Vault → description process - Code Go encryption → architecture encryption - Schéma SQL → contraintes textuelles - Config Nginx → configuration TLS - Code Go rate limiting → paramètres middleware ADR restent 100% techniques et complets sans code concret. Cohérence avec ADR-022 (même approche). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
9.5 KiB
9.5 KiB
ADR-024 : Monitoring, Observabilité et Incident Response
Statut : Accepté Date : 2026-02-01
Contexte
RoadWave nécessite un système de monitoring pour garantir la disponibilité cible 99.9% (SLO) définie dans TECHNICAL.md :
- Métriques : latency p99 < 100ms, throughput API, erreurs
- Alerting : détection pannes, dégradations performance
- Incident response : runbooks, escalation, post-mortems
- Backup/Disaster Recovery : RTO 1h, RPO 15min
Contrainte : self-hosted pour souveraineté données (ADR-015).
Décision
Stack Prometheus + Grafana + Loki self-hosted avec alerting multi-canal.
Stack Technique
| Composant | Technologie | Licence | Justification |
|---|---|---|---|
| Métriques | Prometheus | Apache-2.0 | Standard industrie, PromQL, TSDB performant |
| Visualisation | Grafana | AGPL-3.0 | Dashboards riches, alerting intégré |
| Logs | Grafana Loki | AGPL-3.0 | "Prometheus pour logs", compression efficace |
| Tracing | Tempo (optionnel Phase 2) | AGPL-3.0 | Traces distribuées, compatible OpenTelemetry |
| Alerting | Alertmanager | Apache-2.0 | Grouping, silencing, routing multi-canal |
| Canaux alerts | Email (Brevo) + Webhook (Slack/Discord) | - | Multi-canal, pas de coût SMS |
| Uptime monitoring | Uptime Kuma | MIT | Self-hosted, SSL checks, incidents page |
Architecture
Services surveillés :
- Backend Go API (métriques Fiber)
- PostgreSQL (pg_exporter)
- Redis (redis_exporter)
- Zitadel (endpoint metrics)
Stack Monitoring :
- Prometheus : Collecte métriques (scrape), stockage TSDB 15j rétention
- Grafana : Visualisation dashboards
- Loki : Agrégation logs (chunks compressés, 7j rétention)
- Alertmanager : Routing alertes multi-canal
- Uptime Kuma : Checks HTTP externes, SSL monitoring
Alerting :
- Email (Brevo) : asynchrone, faible intrusivité
- Webhook (Slack/Discord) : temps réel, on-call
Stockage :
- Prometheus TSDB : métriques 15j
- Loki chunks : logs 7j
- Backups PostgreSQL : WAL-E continuous vers S3 OVH
Métriques Clés
API Performance (requêtes PromQL) :
- Latency p99 : histogramme quantile 99e percentile sur durée requêtes HTTP (fenêtre 5 min)
- Error rate : ratio requêtes 5xx / total requêtes (fenêtre 5 min)
- Throughput : taux de requêtes par seconde (fenêtre 5 min)
Infrastructure :
- CPU usage : taux utilisation CPU (mode non-idle, fenêtre 5 min)
- Memory usage : ratio mémoire disponible / totale
- Disk I/O : temps I/O disque (fenêtre 5 min)
Business (compteurs custom) :
- Active users (DAU) :
roadwave_active_users_total - Audio streams actifs :
roadwave_hls_streams_active - Signalements modération :
roadwave_moderation_reports_total
Alternatives considérées
Stack Monitoring
| Option | Coût | Hébergement | Complexité | Verdict |
|---|---|---|---|---|
| Prometheus + Grafana | 0€ | Self-hosted | ⭐⭐ Moyenne | ✅ Choisi |
| Datadog | 15-31$/host/mois | SaaS US | ⭐ Faible | ❌ Coût + souveraineté |
| New Relic | 99-349$/user/mois | SaaS US | ⭐ Faible | ❌ Coût prohibitif |
| Elastic Stack (ELK) | 0€ (open) | Self-hosted | ⭐⭐⭐ Complexe | ❌ Overhead JVM |
| VictoriaMetrics | 0€ | Self-hosted | ⭐⭐ Moyenne | ⚠️ Moins mature |
Alerting Canaux
| Canal | Coût | Disponibilité | Intrusivité | Verdict |
|---|---|---|---|---|
| Email (Brevo) | 0€ (300/j) | Asynchrone | ⭐ Basse | ✅ Standard |
| Webhook Slack/Discord | 0€ | Temps réel | ⭐⭐ Moyenne | ✅ On-call |
| SMS (Twilio) | 0.04€/SMS | Immédiat | ⭐⭐⭐ Haute | ⚠️ Phase 2 (critique) |
| PagerDuty | 21$/user/mois | Immédiat + escalation | ⭐⭐⭐ Haute | ❌ Coût |
| OpsGenie | 29$/user/mois | Immédiat + escalation | ⭐⭐⭐ Haute | ❌ Coût |
Backup Strategy
| Option | RPO | RTO | Coût | Verdict |
|---|---|---|---|---|
| WAL-E continuous archiving | 15 min | 1h | 5-15€/mois (S3) | ✅ Choisi |
| pg_dump quotidien | 24h | 2-4h | 0€ (local) | ❌ RPO trop élevé |
| pgBackRest | 5 min | 30 min | 10-20€/mois | ⚠️ Complexe MVP |
| Managed backup (Scaleway) | 5 min | 15 min | 50€/mois | ❌ Phase 2 |
Justification
Prometheus + Grafana
- Standard industrie : adopté par CNCF, documentation riche
- Performance : TSDB optimisé, compression >10x vs PostgreSQL
- Écosystème : 150+ exporters officiels (PostgreSQL, Redis, Go, Nginx)
- PromQL : langage requête puissant pour alerting complexe
- Coût 0€ : self-hosted, licences permissives
Loki pour Logs
- Compression : 10-50x vs Elasticsearch (stockage chunks)
- Simplicité : pas de schéma, logs = labels + timestamp
- Intégration Grafana : requêtes logs + métriques unifiées
- Performance : grep distribué sur labels indexés
Uptime Kuma
- Self-hosted : alternative à UptimeRobot (SaaS)
- Fonctionnalités : HTTP/HTTPS checks, SSL expiry, status page public
- Alerting : intégration Webhook, Email
- Coût 0€ : open source MIT
Conséquences
Positives
- ✅ Coût infrastructure : 5-20€/mois (stockage S3 backups uniquement)
- ✅ Souveraineté : 100% self-hosted OVH France
- ✅ Alerting multi-canal : Email + Slack/Discord (extensible SMS Phase 2)
- ✅ Observabilité complète : métriques + logs + uptime externe
- ✅ Conformité RGPD : logs anonymisés, rétention 7-15j
Négatives
- ⚠️ Maintenance : Stack à gérer (mises à jour Prometheus, Grafana, Loki)
- ⚠️ Stockage : Prometheus TSDB consomme ~1-2 GB/mois @ 1000 RPS
- ❌ Pas d'on-call automatique au MVP (Slack manual, SMS Phase 2)
- ❌ Courbe d'apprentissage : PromQL à maîtriser
Dashboards Grafana
Dashboard principal :
- Latency p50/p95/p99 API (5 min, 1h, 24h)
- Error rate 5xx/4xx (seuil alerte >1%)
- Throughput requests/sec
- Infra : CPU, RAM, Disk I/O
- Business : DAU, streams actifs, signalements modération
Dashboard PostgreSQL :
- Slow queries (>100ms)
- Connections actives vs max
- Cache hit ratio (cible >95%)
- Deadlocks count
Dashboard Redis :
- Memory usage
- Evictions count
- Commands/sec
- Keyspace hits/misses ratio
Alerting Rules
Alertes critiques (Slack + Email immédiat) :
- API Down : Job API indisponible pendant >1 min → Notification immédiate
- High Error Rate : Taux erreurs 5xx >1% pendant >5 min → Notification immédiate
- Database Down : PostgreSQL indisponible pendant >1 min → Notification immédiate
Alertes warnings (Email uniquement) :
- High Latency : Latency p99 >100ms pendant >10 min → Investigation requise
- Disk Space Running Out : Espace disque <10% pendant >30 min → Nettoyage requis
Backup & Disaster Recovery
PostgreSQL WAL-E :
- Méthode : Backup continu Write-Ahead Log (WAL)
- Rétention : 7 jours full + WAL incrémentaux
- Stockage : S3 OVH région GRA (France)
- Chiffrement : AES-256 server-side
RTO (Recovery Time Objective) : 1h
- Restore depuis S3 : ~30 min (DB 10 GB)
- Validation + relance services : ~30 min
RPO (Recovery Point Objective) : 15 min
- Fréquence archivage WAL : toutes les 15 min
- Perte maximale : 15 min de transactions
Tests DR : Mensuel (restore backup sur environnement staging)
Runbooks Incidents
API Down (5xx errors spike)
- Vérifier : Grafana dashboard → onglet Errors
- Logs : Requête Loki filtrée sur app roadwave-api + niveau error
- Actions :
- Si OOM : restart container + augmenter RAM
- Si DB connexions saturées : vérifier slow queries
- Si réseau : vérifier OVH status page
- Escalade : Si non résolu en 15 min → appel admin senior
Database Slow Queries
- Identifier : Grafana → PostgreSQL dashboard → Top slow queries
- Analyser : Utiliser EXPLAIN ANALYZE sur query problématique
- Actions :
- Index manquant : créer index (migration rapide)
- Lock contention : identifier transaction longue et kill si bloquante
- Prevention : Ajouter alerte Grafana si query >100ms P95
High Load (CPU >80%)
- Vérifier : Grafana → Node Exporter → CPU usage
- Top processus : Consulter htop ou docker stats
- Actions :
- Si Whisper (modération) : réduire concurrence workers
- Si API : scale horizontal (ajouter instance)
- Prévention : Auto-scaling (Phase 2)
Métriques de Succès
- Uptime > 99.9% (8.76h downtime/an max)
- MTTD (Mean Time To Detect) < 5 min
- MTTR (Mean Time To Recover) < 30 min
- Alerts faux positifs < 5%
Migration et Rollout
Phase 1 (MVP - Sprint 2-3)
- Deploy Prometheus + Grafana + Loki (Docker Compose)
- Instrumenter API Go (Fiber middleware metrics)
- Configure exporters : PostgreSQL, Redis, Node
- Dashboard principal + 5 alertes critiques
- Setup WAL-E backup PostgreSQL
Phase 2 (Post-MVP - Sprint 6-8)
- Ajouter Tempo (tracing distribué)
- SMS alerting (Twilio) pour incidents critiques
- Auto-scaling basé métriques Prometheus
- Post-mortem process (template Notion)
Références
- TECHNICAL.md (SLO 99.9%, latency p99 <100ms)
- ADR-001 : Langage Backend (Go, Fiber)
- ADR-005 : Base de données (PostgreSQL)
- ADR-015 : Hébergement (OVH France, self-hosted)
- Prometheus Documentation
- Grafana Loki
- WAL-E PostgreSQL Archiving