Files
roadwave/docs/adr/024-monitoring-observabilite.md
jpgiannetti 35aaa105d0 docs: améliorer rendu markdown et navigation mkdocs
- Ajouter ADR-018 (librairies Go) dans TECHNICAL.md
- Transformer Shared en menu dépliable dans mkdocs (cohérence avec autres domaines)
- Corriger listes markdown (ajout lignes vides avant listes)
- Corriger line breaks dans génération BDD (étapes "Et" sur nouvelles lignes)
- Ajouter script fix-markdown-lists.sh pour corrections futures

Impacte 86 fichiers de documentation et 164 fichiers BDD générés.
2026-02-09 20:49:52 +01:00

10 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 :

  • 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) + Telegram Bot - Multi-canal, pas de coût SMS
Uptime monitoring Uptime Kuma MIT Self-hosted, SSL checks, incidents page

Architecture

graph TB
    subgraph Services["Services RoadWave"]
        API["Backend Go API<br/>(Fiber metrics)"]
        DB["PostgreSQL<br/>(pg_exporter)"]
        Redis["Redis<br/>(redis_exporter)"]
        Zitadel["Zitadel<br/>(metrics endpoint)"]
    end

    subgraph Monitoring["Stack Monitoring"]
        Prom["Prometheus<br/>(scrape + TSDB)"]
        Grafana["Grafana<br/>(dashboards)"]
        Loki["Loki<br/>(logs aggregation)"]
        Alert["Alertmanager<br/>(routing)"]
        Uptime["Uptime Kuma<br/>(external checks)"]
    end

    subgraph Notifications["Alerting"]
        Email["Email (Brevo)"]
        Telegram["Telegram Bot"]
    end

    subgraph Storage["Stockage"]
        PromStorage["Prometheus TSDB<br/>(15j retention)"]
        LokiStorage["Loki Chunks<br/>(7j retention)"]
        Backups["Backups PostgreSQL<br/>(S3 OVH)"]
    end

    API --> Prom
    DB --> Prom
    Redis --> Prom
    Zitadel --> Prom

    API -.->|logs stdout| Loki
    Prom --> Grafana
    Loki --> Grafana
    Prom --> Alert

    Alert --> Email
    Alert --> Telegram

    Uptime -.->|external HTTP checks| API
    Uptime --> Alert

    Prom --> PromStorage
    Loki --> LokiStorage
    DB -.->|WAL-E continuous| Backups

    classDef serviceStyle fill:#e3f2fd,stroke:#1565c0
    classDef monitoringStyle fill:#fff3e0,stroke:#e65100
    classDef notifStyle fill:#f3e5f5,stroke:#6a1b9a
    classDef storageStyle fill:#e8f5e9,stroke:#2e7d32

    class Services,API,DB,Redis,Zitadel serviceStyle
    class Monitoring,Prom,Grafana,Loki,Alert,Uptime monitoringStyle
    class Notifications,Email,Telegram notifStyle
    class Storage,PromStorage,LokiStorage,Backups storageStyle

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
Telegram Bot 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 + Telegram (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 (Telegram 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 (Telegram + 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)

  1. Vérifier : Grafana dashboard → onglet Errors
  2. Logs : Requête Loki filtrée sur app roadwave-api + niveau error
  3. Actions :
    • Si OOM : restart container + augmenter RAM
    • Si DB connexions saturées : vérifier slow queries
    • Si réseau : vérifier OVH status page
  4. Escalade : Si non résolu en 15 min → appel admin senior

Database Slow Queries

  1. Identifier : Grafana → PostgreSQL dashboard → Top slow queries
  2. Analyser : Utiliser EXPLAIN ANALYZE sur query problématique
  3. Actions :
    • Index manquant : créer index (migration rapide)
    • Lock contention : identifier transaction longue et kill si bloquante
  4. Prevention : Ajouter alerte Grafana si query >100ms P95

High Load (CPU >80%)

  1. Vérifier : Grafana → Node Exporter → CPU usage
  2. Top processus : Consulter htop ou docker stats
  3. Actions :
    • Si Whisper (modération) : réduire concurrence workers
    • Si API : scale horizontal (ajouter instance)
  4. 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)

  1. Deploy Prometheus + Grafana + Loki (Docker Compose)
  2. Instrumenter API Go (Fiber middleware metrics)
  3. Configure exporters : PostgreSQL, Redis, Node
  4. Dashboard principal + 5 alertes critiques
  5. Setup WAL-E backup PostgreSQL

Phase 2 (Post-MVP - Sprint 6-8)

  1. Ajouter Tempo (tracing distribué)
  2. SMS alerting (Twilio) pour incidents critiques
  3. Auto-scaling basé métriques Prometheus
  4. Post-mortem process (template Notion)

Références