Aller au contenu
TAAF-OPS --:-- UTC

TP 4 - Alerting : Configuration d'alertes TAAF avec webhooks

📡 Poste SOC · La Réunion — vous supervisez Port-aux-Français (Kerguelen), à ~3 300 km. Liaison SATCOM nominale.

🎯 Objectif métier — être prévenu d’un incident TAAF avant l’utilisateur, par une alerte qui tombe au bon endroit.

Le jour J, l’attaque s’est déroulée en heures ouvrées, pendant que personne ne fixait le bon écran. Une équipe TAAF réduite n’a pas de SOC 24/7 : l’alerte automatique est le seul veilleur qui ne dort jamais. Mal réglée, elle noie le signal ; bien réglée, elle réveille au bon moment. Ce TP clôt l’Acte 1 — Voir devient être prévenu.

Ce TP vous apprend à :

  1. Créer des règles d’alerte Prometheus personnalisées
  2. Configurer Alertmanager pour l’envoi de notifications
  3. Intégrer des webhooks (Discord, Google Chat)
  4. Tester et simuler des incidents
  5. Analyser les métriques pour définir des seuils pertinents

graph LR
 subgraph Sources[" Sources de Données"]
 direction TB
 CAD[cAdvisor
Conteneurs] PEXP[postgres_exporter
PostgreSQL] NEXP[node_exporter
Système] ALLOY[Grafana Alloy
Logs Apps] end subgraph Evaluation[" Collecte & Évaluation"] direction TB PROM[Prometheus
+ Rules] LOKI[Loki
+ Ruler] end subgraph Routing[" Gestion des Alertes"] AM[Alertmanager
Routing & Grouping] end subgraph Notif[" Notifications"] direction TB DISC[Discord] GCHAT[Google Chat] EMAIL[Email] end CAD -->|métriques|PROM PEXP -->|métriques|PROM NEXP -->|métriques|PROM ALLOY -->|logs|LOKI PROM -->|alertes
métriques|AM LOKI -->|alertes
logs|AM AM -->|webhook|DISC AM -->|webhook|GCHAT AM -->|SMTP|EMAIL classDef sourceStyle fill:#e3f2fd,stroke:#1976d2,stroke-width:2px,color:#000 classDef evalStyle fill:#e8f5e9,stroke:#388e3c,stroke-width:2px,color:#000 classDef alertStyle fill:#fff3e0,stroke:#f57c00,stroke-width:2px,color:#000 classDef notifStyle fill:#fce4ec,stroke:#c2185b,stroke-width:2px,color:#000 class CAD,PEXP,NEXP,ALLOY sourceStyle class PROM,LOKI evalStyle class AM alertStyle class DISC,GCHAT,EMAIL notifStyle

Flux d’alerting hybride (gauche → droite) :

  1. 📊 Sources : Collecte des données

    • Métriques : cAdvisor, postgres_exporter, node_exporter → Prometheus
    • Logs : Grafana Alloy → Loki
  2. ⚙️ Évaluation : Analyse et détection

    • Prometheus évalue les règles PromQL (alert_rules.yml)
    • Loki Ruler évalue les règles LogQL (loki_rules.yml)
  3. 🔔 Routing : Gestion centralisée

    • Alertmanager reçoit toutes les alertes (métriques + logs)
    • Grouping, throttling, routing par sévérité
  4. 📢 Notifications : Envoi multi-canal

    • Discord & Google Chat (webhooks)
    • Email (SMTP)

OBLIGATOIRE - TPs précédents :

  • TP 1 - Grafana Metric terminé : Dashboard supervision conteneurs
  • TP 2 - Grafana Data terminé : Dashboards données métier TAAF
  • TP 3 - Loki Integration terminé : Logs intégrés à Grafana
  • Stack de supervision complète avec métriques + logs démarrée

Configuration externe :

  • Accès à Discord ou Google Chat pour webhooks
  • URL de webhook configurée sur votre plateforme de chat

  1. Créer un webhook Discord :

    • Allez dans Paramètres serveur → Intégrations → Webhooks
    • Créez un nouveau webhook
    • Copiez l’URL générée
  2. Format de l’URL :

    https://discord.com/api/webhooks/VOTRE_ID/VOTRE_TOKEN
  1. Créer un webhook Google Chat :

    • Ouvrez Google Chat dans un espace
    • Allez dans Gérer les webhooks et bots
    • Créez un nouveau webhook
    • Copiez l’URL générée
  2. Format de l’URL (exemple) :

    https://chat.googleapis.com/v1/spaces/AAAA/messages?key=BBBB&token=CCCC

    (L’URL complète inclut déjà la clé et le token. Copiez l’URL telle quelle depuis Google Chat.)


  1. Créer le fichier de configuration Alertmanager :
Fenêtre de terminal
# Créer le répertoire
mkdir -p alertmanager
# Créer le fichier de configuration
nano alertmanager/alertmanager.yml
alertmanager/alertmanager.yml
global:
smtp_smarthost: 'localhost:587'
route:
group_by: ['mission', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 24h
receiver: 'taaf-webhook'
routes:
- match:
severity: critical
receiver: 'taaf-critical'
- match:
severity: warning
receiver: 'taaf-warning'
receivers:
# Webhook pour alertes critiques
- name: 'taaf-critical'
webhook_configs:
- url: 'VOTRE_WEBHOOK_URL'
title: 'ALERTE CRITIQUE TAAF'
text: |
**{{ .GroupLabels.mission | title }}**
{{ range .Alerts }}
**Incident:** {{ .Annotations.summary }}
**Description:** {{ .Annotations.description }}
**Sévérité:** {{ .Labels.severity }}
**Timestamp:** {{ .StartsAt }}
{{ end }}
# Webhook pour alertes d'avertissement
- name: 'taaf-warning'
webhook_configs:
- url: 'VOTRE_WEBHOOK_URL'
title: 'Avertissement TAAF'
text: |
**{{ .GroupLabels.mission | title }}**
{{ range .Alerts }}
**Problème:** {{ .Annotations.summary }}
**Détails:** {{ .Annotations.description }}
{{ end }}
# Fallback par défaut
- name: 'taaf-webhook'
webhook_configs:
- url: 'VOTRE_WEBHOOK_URL'
  1. Ajouter Alertmanager au docker-compose.yml :
# Alertmanager
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager-taaf
ports:
- "9093:9093"
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
- alertmanager_data:/alertmanager
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
- '--web.external-url=http://localhost:9093'
networks:
- taaf-monitoring
  1. Modifier prometheus.yml pour pointer vers Alertmanager :
# Ajouter dans prometheus.yml
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093

Étape 3: Créer votre règle d’alerte personnalisée

Section intitulée « Étape 3: Créer votre règle d’alerte personnalisée »

Mission: Surveillance des conditions météo extrêmes

Section intitulée « Mission: Surveillance des conditions météo extrêmes »

Créez une règle d’alerte pour détecter des conditions météorologiques dangereuses :

# À ajouter dans alert_rules.yml
- name: taaf_meteo_alerts
rules:
- alert: ConditionsMeteoExtreme
expr: VOTRE_EXPRESSION_PROMQL_ICI
for: 1m
labels:
severity: critical
mission: taaf
type: meteorologie
base: "{{ $labels.base_name }}"
annotations:
summary: "Conditions météo extrêmes - Base {{ $labels.base_name }}"
description: "Conditions dangereuses détectées: Température {{ $value }}°C ou Vent {{ $labels.wind_speed }}km/h"

Métriques disponibles via postgres_exporter :

Exemples de seuils critiques pour les bases TAAF :

  • Température < -40°C ou > 25°C
  • Vent > 120 km/h
  • Visibilité < 50m

Exemple d’expression PromQL pour la règle :

# Détecter température extrême
pg_stat_meteo_temperature < -40 or pg_stat_meteo_temperature > 25
# Combiner plusieurs conditions (température ET vent)
(pg_stat_meteo_temperature < -40 or pg_stat_meteo_temperature > 25)
and pg_stat_meteo_vitesse_vent > 120

Étape 3bis: Créer des alertes basées sur les logs (Loki Ruler)

Section intitulée « Étape 3bis: Créer des alertes basées sur les logs (Loki Ruler) »

Le Loki ruler évalue périodiquement des requêtes LogQL et envoie les alertes vers Alertmanager, exactement comme Prometheus.

Architecture :

[Logs] → [Loki] → [Loki Ruler évalue rules LogQL] → [Alertmanager] → [Webhooks]

1. Créer le répertoire de règles :

Fenêtre de terminal
# Créer le répertoire s'il n'existe pas déjà
mkdir -p config/loki/rules

2. Créer votre fichier de règles d’alerte LogQL :

Fenêtre de terminal
nano config/loki/rules/taaf_log_alerts.yml
config/loki/rules/taaf_log_alerts.yml
groups:
# Groupe 1 : Alertes sur les erreurs applicatives
- name: taaf_application_errors
interval: 1m
rules:
- alert: TAAFHighErrorRate
expr: |
sum(rate({job=~".+"} |= "ERROR" [5m])) > 0.5
for: 2m
labels:
severity: warning
mission: taaf
type: application
annotations:
summary: "Taux d'erreurs applicatives élevé"
description: "Plus de 0.5 erreurs/sec détectées ({{ $value }} erreurs/sec)"
- alert: TAAFCriticalErrorSpike
expr: |
sum(rate({job=~".+"} |~ "CRITICAL|FATAL" [5m])) > 0.1
for: 1m
labels:
severity: critical
mission: taaf
type: application
annotations:
summary: "Erreurs critiques détectées dans les logs"
description: "Erreurs CRITICAL/FATAL détectées ({{ $value }} erreurs/sec)"
# Groupe 2 : Alertes sur les bases de données
- name: taaf_database_logs
interval: 1m
rules:
- alert: TAAFDatabaseConnectionErrors
expr: |
sum(rate({job="postgresql"} |= "connection" |= "failed" [5m])) > 0.2
for: 2m
labels:
severity: warning
mission: taaf
type: database
annotations:
summary: "Erreurs de connexion PostgreSQL détectées"
description: "Échecs de connexion fréquents sur PostgreSQL ({{ $value }}/sec)"
- alert: TAAFDatabaseDeadlock
expr: |
sum(rate({job="postgresql"} |= "deadlock" [5m])) > 0
for: 1m
labels:
severity: critical
mission: taaf
type: database
annotations:
summary: "Deadlock PostgreSQL détecté"
description: "Un ou plusieurs deadlocks détectés dans PostgreSQL"
# Groupe 3 : Alertes sur les conteneurs Docker
- name: taaf_container_logs
interval: 1m
rules:
- alert: TAAFContainerRestart
expr: |
sum(rate({job="containerlogs"} |= "restart" [5m])) > 0.1
for: 2m
labels:
severity: warning
mission: taaf
type: infrastructure
annotations:
summary: "Redémarrages fréquents de conteneurs"
description: "Un ou plusieurs conteneurs redémarrent fréquemment"
- alert: TAAFContainerOOMKilled
expr: |
sum(count_over_time({job="containerlogs"} |= "OOMKilled" [10m])) > 0
for: 1m
labels:
severity: critical
mission: taaf
type: infrastructure
annotations:
summary: "Conteneur tué par manque de mémoire (OOM)"
description: "Un conteneur a été tué par le kernel (Out Of Memory)"

3. Vérifier la configuration dans loki.yml :

Le fichier config/loki/loki.yml doit déjà contenir la configuration du ruler :

ruler:
storage:
type: local
local:
directory: /loki/rules
rule_path: /loki/rules
alertmanager_url: http://alertmanager-taaf:9093
ring:
kvstore:
store: inmemory
enable_api: true
enable_alertmanager_v2: true

4. Vérifier le montage du volume dans docker-compose.yml :

services:
loki:
image: grafana/loki:latest
volumes:
- ./config/loki/loki.yml:/etc/loki/local-config.yaml
- ./config/loki/rules:/loki/rules # Volume pour les règles
- loki_data:/loki

5. Redémarrer Loki pour charger les nouvelles règles :

Fenêtre de terminal
# Redémarrer le service Loki
docker compose restart loki
# Attendre quelques secondes puis vérifier
sleep 5
# Vérifier que les règles sont chargées
curl http://localhost:3100/loki/api/v1/rules
# Vérifier les alertes actives (si des logs déclenchent les règles)
curl http://localhost:3100/loki/api/v1/alerts
AspectPrometheusLoki
LangagePromQLLogQL
SourceMétriques numériquesLogs textuels
Fichierprometheus/alert_rules.ymlloki/rules/*.yml
ÉvaluationMoteur PrometheusLoki ruler
DestinationAlertmanagerAlertmanager (même instance)
Reloaddocker compose restart prometheusdocker compose restart loki
# Taux d'erreurs global
sum(rate({job=~".+"} |= "ERROR" [5m]))
# Erreurs sur une base spécifique
sum(rate({job="taaf-logs", base="paf"} |= "ERROR" [5m]))
# Recherche de pattern spécifique
sum(rate({job=~".+"} |= "connection refused" [5m]))
# Combinaison de filtres
sum(rate({job="postgresql"} |= "ERROR" |= "could not connect" [5m]))
# Comptage d'événements sur une période
sum(count_over_time({job=~".+"} |= "FATAL" [10m]))

Objectif : Créer une alerte personnalisée pour détecter des pannes de communication satellite dans les logs.

Indices :

  • Les logs de communication sont dans {job="taaf-logs", type="communication"}
  • Chercher les patterns : “satellite”, “connection lost”, “timeout”
  • Seuil suggéré : > 0.1 erreur/sec pendant 2 minutes

Votre règle (à compléter) :

- alert: TAAFSatelliteCommunicationFailure
expr: |
# TODO: Écrire votre requête LogQL ici
for: # TODO: Durée
labels:
severity: # TODO: critical ou warning ?
mission: taaf
type: communication
annotations:
summary: "Panne de communication satellite détectée"
description: # TODO: Description personnalisée

Fenêtre de terminal
# Arrêter un conteneur pour déclencher l'alerte ContainerDown
docker compose stop postgres-af
# Attendre 30 secondes puis vérifier l'alerte
curl http://localhost:9090/api/v1/alerts
Fenêtre de terminal
# Utiliser un conteneur de stress test
docker run --rm -it --name memory-stress \
--memory=2g progrium/stress \
--vm 1 --vm-bytes 1.8g --timeout 300s
-- Insérer des données météo extrêmes via Adminer
INSERT INTO conditions_meteo (base_name, temperature, vitesse_vent, visibilite, timestamp)
VALUES
('Dumont d''Urville', -45.5, 130.0, 25.0, NOW()),
('Alfred Faure', 28.0, 140.0, 15.0, NOW());

Générer des logs d’erreur pour déclencher les alertes :

Fenêtre de terminal
# Créer un répertoire temporaire pour les logs de test
mkdir -p /var/log/test-taaf
# Générer des logs d'erreur
for i in {1..50}; do
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR Test_Application Simulation_erreur_$i" >> /var/log/test-taaf/app.log
sleep 0.5
done
# Vérifier que Loki reçoit les logs
curl -G 'http://localhost:3100/loki/api/v1/query' \
--data-urlencode 'query={job=~".+"} |= "ERROR"' \
--data-urlencode 'limit=10'
# Attendre 2-3 minutes puis vérifier les alertes actives
sleep 180
curl http://localhost:3100/loki/api/v1/alerts
# Vérifier dans Alertmanager
curl http://localhost:9093/api/v2/alerts | jq '.[] | select(.labels.alertname | contains("TAAF"))'

Simuler des erreurs PostgreSQL :

Fenêtre de terminal
# Simuler des tentatives de connexion échouées
for i in {1..20}; do
docker exec postgres-af psql -U wrong_user -d base_af 2>&1 | \
logger -t postgresql -p local0.err
sleep 1
done

Vérifier les alertes déclenchées :

Fenêtre de terminal
# Via Loki API
curl http://localhost:3100/loki/api/v1/alerts | jq '.'
# Via Alertmanager
curl http://localhost:9093/api/v2/alerts | jq '.[] | {alert: .labels.alertname, status: .status.state}'
# Vérifier dans l'interface Alertmanager
# Ouvrir : http://localhost:9093

  1. Accédez à Alertmanager : http://localhost:9093
  2. Consultez les onglets :
    • Alerts : Alertes actives
    • Silences : Alertes mises en sourdine
    • Status : Configuration et statut
  1. Accédez à Prometheus : http://localhost:9090
  2. Consultez l’onglet “Alerts”
  3. Utilisez ces requêtes PromQL :
# Voir toutes les alertes actives
ALERTS{alertname!=""}
# Alertes critiques seulement
ALERTS{severity="critical"}
# Alertes par mission
ALERTS{mission="taaf"}

Objectif : Créer une alerte pour surveiller le nombre de connexions PostgreSQL

# Complétez cette règle :
- alert: TropDeConnexions
expr: # TODO: Écrire l'expression PromQL
for: # TODO: Définir la durée
labels:
severity: # TODO: Choisir la sévérité
annotations:
summary: # TODO: Message de résumé

Objectif : Créer une alerte composite combinant plusieurs métriques

Scénario : Détecter une “Situation d’urgence base” quand :

  • Température < -30°C ET
  • Vitesse vent > 100 km/h ET
  • Visibilité < 100m

Objectif : Configurer des routes d’alertes différentes selon la base

# Exemple à adapter :
routes:
- match:
base: "Dumont d'Urville"
receiver: 'antarctique-team'
- match:
base: "Alfred Faure"
receiver: 'subantarctique-team'

Alertes qui ne se déclenchent pas :

  1. Vérifiez l’expression PromQL dans Prometheus
  2. Contrôlez la période for:
  3. Vérifiez que les métriques existent

Webhooks qui ne fonctionnent pas :

  1. Testez l’URL manuellement avec curl
  2. Vérifiez le format du payload
  3. Consultez les logs d’Alertmanager

Commandes de debug :

Fenêtre de terminal
# Logs Alertmanager
docker logs alertmanager-taaf
# Test webhook manuel
curl -X POST VOTRE_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d '{"text": "Test message"}'
# Recharger configuration Alertmanager
curl -X POST http://localhost:9093/-/reload

Les 10 questions suivantes valident votre compréhension et votre réalisation (difficulté croissante) :

“Combien de règles d’alerte sont définies dans votre fichier alert_rules.yml ?”

Réponse attendue : Nombre total de règles + nom des groupes d’alertes configurés.

“Quel est l’URL de webhook que vous avez configuré pour recevoir les alertes ?”

Réponse attendue : URL masquée (pour sécurité) + type de plateforme (Discord/Google Chat) + capture de configuration.

“Déclenchez manuellement l’alerte ContainerDown en arrêtant un conteneur. Quel message recevez-vous ?”

Réponse attendue : Commande utilisée + capture du message reçu + délai de réception.

“Pourquoi avez-vous choisi un seuil de 85% pour l’alerte HighMemoryUsage ? Justifiez ce choix.”

Réponse attendue : Analyse des métriques existantes + justification technique + impact opérationnel + comparaison avec standards.

“Créez une règle d’alerte qui se déclenche quand un conteneur redémarre plus de 3 fois en 10 minutes.”

Réponse attendue : Expression PromQL complète + configuration YAML + test de fonctionnement + justification du seuil.

“Configurez un routage différent pour les alertes critiques (webhook immédiat) et warnings (email après 5 minutes).”

Réponse attendue : Configuration Alertmanager route + receivers + test des deux types d’alertes + captures de réception.

“Créez une alerte ‘TAAFConditionsMeteoExtreme’ qui se déclenche sur des conditions météo dangereuses à partir des données PostgreSQL.”

Réponse attendue : Règle complète avec expression PromQL + intégration postgres_exporter + test avec données réelles + justification seuils polaires.

“Configurez une inhibition pour éviter le spam d’alertes quand un host entier est down.”

Réponse attendue : Configuration inhibit_rules + test de scénario + explication logique + capture avant/après inhibition.

“Créez une alerte composite qui combine : utilisation mémoire > 90% ET utilisation CPU > 80% ET durée > 2 minutes.”

Réponse attendue : Expression PromQL complexe + configuration alerte + test sur conteneur réel + analyse de corrélation métriques.

“Créez une règle d’alerte Loki qui détecte une dégradation progressive des performances PostgreSQL via l’analyse des logs (requêtes lentes, timeouts, etc.).”

Réponse attendue : Règle complète LogQL + patterns de logs à détecter + seuils justifiés + test avec logs simulés + capture de l’alerte dans Alertmanager.

Question 11 - Optimisation système d’alerting (Expert)

Section intitulée « Question 11 - Optimisation système d’alerting (Expert) »

“Analysez votre système d’alerting hybride (Prometheus + Loki) et proposez 3 améliorations pour réduire les faux positifs tout en maintenant la détection d’incidents critiques.”

Réponse attendue : Analyse complète des alertes générées (métriques + logs) + identification faux positifs + 3 améliorations détaillées + nouveaux seuils + impact sur fiabilité + adaptation contexte polaire TAAF + exemples de corrélation Prometheus-Loki.


  1. alertmanager.yml - Configuration complète Alertmanager
  2. alert_rules_custom.yml - Vos règles Prometheus personnalisées
  3. loki_rules/taaf_log_alerts.yml - Vos règles Loki personnalisées
  4. screenshots/ - Captures d’écran des tests (alertes Prometheus + Loki)
  5. rapport.md - Rapport d’analyse
# Rapport TP Alerting TAAF
## 1. Réponses aux questions de validation
- Questions 1-3 : Configuration et tests de base
- Questions 4-6 : Seuils et routage d'alertes
- Questions 7-9 : Alertes avancées Prometheus
- Question 10 : Alertes Loki avancées
- Question 11 : Analyse et améliorations système hybride
## 2. Configuration réalisée
### 2.1 Alertmanager
- Webhook utilisé (Discord/Google Chat)
- Configuration des routes et receivers
- Tests de connectivité
### 2.2 Règles Prometheus
- Nombre de règles créées
- Types d'alertes (métriques CPU, RAM, PostgreSQL, etc.)
- Seuils définis
### 2.3 Règles Loki
- Nombre de règles créées
- Types d'alertes (logs applicatifs, erreurs, etc.)
- Patterns LogQL utilisés
## 3. Analyse des seuils
- Justification des valeurs choisies (Prometheus et Loki)
- Analyse des faux positifs/négatifs
- Recommandations d'amélioration
- Corrélation entre alertes métriques et logs
## 4. Résultats des tests
### 4.1 Tests Prometheus
- Captures d'écran des alertes métriques reçues
- Temps de réaction observés
- Alertes testées (ContainerDown, HighCPU, etc.)
### 4.2 Tests Loki
- Captures d'écran des alertes logs reçues
- Logs générés pour les tests
- Alertes testées (HighErrorRate, DatabaseErrors, etc.)
### 4.3 Tests hybrides
- Corrélation logs + métriques
- Scénarios d'incidents complets
- Problèmes rencontrés et solutions
## 5. Conclusion
- Points forts du système d'alerting hybride
- Avantages de la corrélation Prometheus + Loki
- Améliorations possibles
- Applicabilité en environnement réel TAAF

# Ajouter des annotations Grafana lors des alertes
- name: grafana-annotations
webhook_configs:
- url: 'http://grafana:3000/api/annotations'
http_config:
basic_auth:
username: admin
password: AdminTAAF2024!
# Pour un environnement de production
- name: pagerduty
pagerduty_configs:
- routing_key: 'VOTRE_CLE_PAGERDUTY'
description: '{{ .GroupLabels.alertname }}'


Plateforme de rendu : Moodle de l’Université de la Réunion

Nommage STRICT : nom-prénom-promo.PDF
Exemple : martin-lucas-but3.PDF

ATTENTION : Tout fichier ne respectant pas ce format de nommage entraînera une pénalité de -5 points sur la note finale.


Bonne chance dans vos expérimentations d’alerting pour les missions polaires !