#38 — prometheus-alert
EN COURS DE DÉPLOIEMENT
Priorité: 🔴 CRITIQUE · Type: TYPE F · Conteneurs: rgz-prometheus + rgz-alertmanager · Code: config/prometheus/
Dépendances: aucune (déployer en premier)
Description
prometheus-alert regroupe deux composants indissociables : Prometheus 2.x (collecte et stockage des métriques par scraping HTTP) et Alertmanager (routage et déduplication des alertes vers les récepteurs appropriés). C'est la fondation de tout le monitoring RGZ — aucune autre catégorie de monitoring ne fonctionne sans lui. Il n'a aucune dépendance externe au sein du projet, ce qui en fait l'outil à déployer en tout premier dans la phase monitoring.
Prometheus utilise le mode pull : il scrape périodiquement (toutes les 15 secondes) chaque service qui expose un endpoint /metrics au format OpenMetrics. Côté FastAPI, la librairie prometheus-fastapi-instrumentator expose automatiquement les métriques HTTP (latence P50/P95/P99, taux d'erreur, requêtes actives). Les autres services (PostgreSQL, Redis, gateway) utilisent des exporters dédiés déployés en side-car ou sur l'hôte.
Alertmanager reçoit les alertes déclenchées par les règles Prometheus, les déduplique (une seule notification pour une alerte continue), les route selon leur sévérité (P0 → SMS Letexto immédiat, P1 → SMS + email, P2 → email uniquement), et gère les silences durant les maintenances planifiées. Les templates d'alerte sont en français, conformément aux standards du projet.
Les données Prometheus sont conservées selon la durée configurée par PROMETHEUS_RETENTION (par défaut 15 jours). Les données longue durée (>15j) sont répliquées dans TimescaleDB via les tâches de monitoring Celery (#39, #43).
Architecture Interne
Exporters (pull toutes les 15s)
│
├── rgz-api:8000/metrics (prometheus-fastapi-instrumentator)
├── postgres_exporter:9187/metrics (connexions, requêtes, cache hit)
├── redis_exporter:9121/metrics (used_memory, hit_rate, connected_clients)
├── node_exporter:9100/metrics (CPU, RAM, disk I/O, réseau hôte)
├── freeradius_exporter/metrics (auth/acct rate, rejets, sessions)
└── rgz-gateway:9100/metrics (nftables counters, QoS stats)
│
▼
rgz-prometheus:9090
│
├── TSDB (stockage métriques — retention configurable)
├── Règles d'alerte (config/prometheus/alerts/*.yml)
│ ├── infrastructure.yml (CPU, RAM, disk, réseau)
│ ├── radius.yml (auth failures, sessions)
│ ├── api.yml (latence, error rate)
│ ├── sla.yml (uptime, latence probes)
│ └── ssl.yml (expiration certificats)
│
└── Alertes déclenchées → rgz-alertmanager:9093
│
┌──────────────┴──────────────┐
▼ ▼
Route P0/P1 Route P2
SMS Letexto (immédiat) Email SMTP (J+1)Configuration
Variables d'environnement
| Variable | Exemple | Description |
|---|---|---|
PROMETHEUS_RETENTION | 15d | Durée de rétention des métriques TSDB |
ALERTMANAGER_SMTP_HOST | smtp.host:587 | Serveur SMTP pour notifications email |
ALERTMANAGER_SMTP_FROM | alertes@rgz.bj | Adresse expéditeur |
ALERTMANAGER_RECEIVER_EMAIL | noc@rgz.bj | Email destinataire NOC |
ALERTMANAGER_LETEXTO_KEY | ... | Clé Letexto pour SMS alertes |
ALERTMANAGER_SMS_RECIPIENT | +22997000001 | Numéro NOC pour SMS urgents |
PROMETHEUS_EXTERNAL_URL | http://rgz-prometheus:9090 | URL externe Prometheus |
Fichier prometheus.yml
# config/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: 'rgz-production'
region: 'benin'
rule_files:
- "alerts/*.yml"
alerting:
alertmanagers:
- static_configs:
- targets: ['rgz-alertmanager:9093']
scrape_configs:
- job_name: 'rgz-api'
static_configs:
- targets: ['rgz-api:8000']
metrics_path: '/metrics'
- job_name: 'postgres'
static_configs:
- targets: ['postgres-exporter:9187']
- job_name: 'redis'
static_configs:
- targets: ['redis-exporter:9121']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'freeradius'
static_configs:
- targets: ['freeradius-exporter:9812']
- job_name: 'gateway'
static_configs:
- targets: ['rgz-gateway:9100']Alertes définies — Infrastructure
# config/prometheus/alerts/infrastructure.yml
groups:
- name: infrastructure
rules:
- alert: HighCPU
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 5m
labels:
severity: P1
annotations:
summary: "CPU élevé sur {{ $labels.instance }}"
description: "CPU à {{ $value }}% depuis 5min"
- alert: HighMemory
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
for: 2m
labels:
severity: P1
annotations:
summary: "RAM élevée sur {{ $labels.instance }}"
description: "RAM à {{ $value }}% utilisée"
- alert: DiskSpaceWarning
expr: (1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 80
for: 10m
labels:
severity: P2
annotations:
summary: "Disque presque plein sur {{ $labels.instance }}"
description: "{{ $value }}% utilisé sur {{ $labels.mountpoint }}"Alertes définies — RADIUS & Sessions
# config/prometheus/alerts/radius.yml
groups:
- name: radius
rules:
- alert: RadiusAuthFailureRate
expr: rate(freeradius_authentication_responses_total{code="Access-Reject"}[5m]) /
rate(freeradius_authentication_responses_total[5m]) > 0.05
for: 2m
labels:
severity: P0
annotations:
summary: "Taux d'échec RADIUS > 5%"
description: "{{ $value | humanizePercentage }} d'échecs d'authentification"
- alert: SessionCountDrop
expr: delta(rgz_active_sessions_total[5m]) / rgz_active_sessions_total < -0.3
for: 5m
labels:
severity: P0
annotations:
summary: "Chute brutale des sessions actives (> 30%)"Endpoints API
| Méthode | Route | Description |
|---|---|---|
GET | http://rgz-prometheus:9090/api/v1/query?query=... | Requête PromQL instantanée |
GET | http://rgz-prometheus:9090/api/v1/query_range?... | Requête PromQL sur plage temps |
GET | http://rgz-prometheus:9090/api/v1/alerts | Alertes actives |
GET | http://rgz-prometheus:9090/-/healthy | Healthcheck |
GET | http://rgz-alertmanager:9093/api/v2/alerts | Alertes en cours (Alertmanager) |
POST | http://rgz-alertmanager:9093/api/v2/silences | Créer un silence maintenance |
Commandes Utiles
# Vérifier que Prometheus est UP
docker exec rgz-prometheus wget -qO- http://127.0.0.1:9090/-/healthy
# Réponse: Prometheus Server is Healthy.
# Vérifier Alertmanager
docker exec rgz-alertmanager wget -qO- http://127.0.0.1:9093/-/healthy
# Lister les targets scrappées et leur statut
curl -s http://127.0.0.1:9090/api/v1/targets | jq '.data.activeTargets[] | {job:.job, health:.health, lastScrape:.lastScrape}'
# Requête PromQL — CPU actuel
curl -s 'http://127.0.0.1:9090/api/v1/query?query=100-(avg(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100)' | jq '.data.result'
# Lister les alertes actives
curl -s http://127.0.0.1:9090/api/v1/alerts | jq '.data.alerts[] | {name:.labels.alertname, severity:.labels.severity, state:.state}'
# Recharger la configuration Prometheus (sans restart)
curl -s -X POST http://127.0.0.1:9090/-/reload
# Logs Prometheus
docker logs rgz-prometheus -f --tail=50
# Logs Alertmanager
docker logs rgz-alertmanager -f --tail=50
# Restart stack monitoring
docker compose -f /home/claude-dev/RGZ/docker-compose.monitoring.yml restart rgz-prometheus rgz-alertmanagerSécurité
| Règle | Implémentation |
|---|---|
| SEC-07 | Prometheus sans auth par défaut — accès restreint au réseau rgz-net uniquement (pas de port exposé publiquement) |
| SEC-08 | Connexion postgres_exporter via rôle PostgreSQL ro (lecture seule) |
| LL#27 | Logs Docker : max-size: 10m, max-file: 3 — Prometheus peut générer beaucoup de logs |
| LL#33 | restart: unless-stopped dans docker-compose.monitoring.yml |
| LL#43 | Healthchecks : wget -qO- http://127.0.0.1:9090/-/healthy (127.0.0.1 explicite) |
# Fragment docker-compose.monitoring.yml
rgz-prometheus:
image: prom/prometheus:v2.x.x
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-15d}'
- '--web.enable-lifecycle'
volumes:
- ./config/prometheus:/etc/prometheus:ro
- prometheus_data:/prometheus
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9090/-/healthy || exit 1"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
- rgz-netImplémentation TODO
- [x] Services
rgz-prometheusetrgz-alertmanagerdansdocker-compose.monitoring.yml - [ ]
config/prometheus/prometheus.yml— configuration scrape complète (6 targets) - [ ]
config/prometheus/alerts/infrastructure.yml— CPU, RAM, disk - [ ]
config/prometheus/alerts/radius.yml— auth failures, sessions - [ ]
config/prometheus/alerts/api.yml— latence P95, error rate - [ ]
config/prometheus/alerts/sla.yml— uptime targets - [ ]
config/prometheus/alerts/ssl.yml— expiration certificats - [ ]
config/prometheus/alertmanager.yml— routes P0/P1/P2 + templates - [ ] Déployer
postgres_exporteren side-car dans docker-compose - [ ] Déployer
redis_exporteren side-car - [ ] Déployer
node_exportersur l'hôte - [ ] Configurer
prometheus-fastapi-instrumentatordansapp/main.py - [ ] Tester les alertes avec
amtool(alertmanager CLI) - [ ] Documenter les silences de maintenance planifiés
Dernière mise à jour: 2026-02-21