Skip to Content
DevOpsMonitoring — Logs, métriques, alertes

Monitoring — Logs, métriques, alertes

Observer la santé d’un serveur en production : lire les logs, vérifier les ressources, recevoir une alerte quand un seuil est franchi.

Ce guide couvre les outils natifs Linux et des exporters minimaux en Docker. Pas de Prometheus + Grafana complet — juste ce qui permet de détecter un problème avant qu’il ne devienne critique.

1. Logs

journalctl — systemd

Systemd centralise les logs de tous les services.

# Dernières lignes d'un service journalctl -u nom-du-service --no-pager -n 50 # Logs de la session en cours (temps réel) journalctl -f -u nom-du-service # Logs d'aujourd'hui, triés du plus récent au plus ancien journalctl --since today -p err --no-pager # Filtre par niveau de priorité # emerg(0) alert(1) crit(2) err(3) warning(4) notice(5) info(6) debug(7) journalctl -p err --no-pager

--no-pager évite le pageSize qui casse le copier-coller dans un terminal.

docker logs

# Dernières lignes (pas de follow) docker logs mon-conteneur --tail 100 # Temps réel docker logs -f mon-conteneur # Logs avec timestamps docker logs --timestamps mon-conteneur 2>&1

Les logs Docker ne sont pas persistants par défaut. Si le conteneur redémarre, les anciens logs sont perdus sauf configuration de logging driver dans docker-compose.yml ou daemon.json.

Rotation avec logrotate

Sans rotation, /var/log peut remplir le disque en quelques jours.

Fichier /etc/logrotate.d/mon-service :

/var/log/mon-service/*.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate }

Tester sans appliquer :

sudo logrotate -d /etc/logrotate.d/mon-service

Appliquer immédiatement (en cas de disque plein) :

sudo logrotate -f /etc/logrotate.d/mon-service

copytruncate permet de tourner un log sans redémarrer le service (contrairement à postrotate { service X restart }). L’inconvénient : il y a un court laps de temps où le service écrit dans l’ancien fichier.

2. Métriques système

Commandes d’observation

# Vue globale en temps réel (CPU, RAM, processus) htop # CPU pastille par pastille vmstat 2 # IO disque toutes les 2 secondes iostat -x 2

vmstat donne un état snapshot toutes les N secondes. Le champ si/so (swap in/out) non nul indique une RAM saturée.

# RAM en détails free -h # Top consommation mémoire (10 processus) ps aux --sort=-%mem | head -11

Vérifier l’espace disque

# Tailles des répertoires sous /var (format lisible) du -sh /var/* | sort -rh | head -10 # Fichiers gros (> 100 Mo) dans /tmp find /tmp -type f -size +100M -exec ls -lh {} \;

Un df -h qui montre / à 95 % est souvent une urgence. Un du rapide pour identifier le coupable avant de supprimer aveuglément.

Exporters Docker (métriques JSON)

Pour extraire les métriques d’un conteneur sans agent lourd :

docker stats --no-stream --format \ "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"

Export JSON brut (utile pour un script de parsing) :

docker stats --no-stream --format "{{json .}}"

3. Alertes bash — seuils minimaux

Des scripts d’alerte qui préviennent par e-mail ou Telegram avant qu’un opérateur ne découvre le problème.

Formatage du message d’alerte

#!/bin/bash # alert.sh — génère un message compact HOSTNAME=$(hostname) DATE=$(date '+%Y-%m-%d %H:%M') send_alert() { local severity="$1" local message="$2" echo "[$severity] $DATE$HOSTNAME$message" } # Exemple d'utilisation DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%') if [ "$DISK_USAGE" -gt 90 ]; then send_alert "CRITIQUE" "Disque racine à ${DISK_USAGE}%" fi

Envoi par e-mail (mailx/postfix)

# Installer un client mail minimal sudo apt install -y mailutils # Envoyer une alerte echo "$MESSAGE" | mail -s "[ALERT] $HOSTNAME" admin@example.com

mailutils nécessite un MTA configuré (postfix, nullmailer). Pour un serveur de dev sans accès SMTP externe, utiliser un webhook vers un service de notification à la place.

Envoi vers Telegram bot

#!/bin/bash # send-telegram-alert.sh BOT_TOKEN="123456:ABC-DEF..." CHAT_ID="-100123456789" MESSAGE="$1" curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \ -d chat_id="$CHAT_ID" \ -d text="$MESSAGE" \ -d parse_mode="Markdown"

Stocker le BOT_TOKEN dans un fichier hors du dépôt (/etc/mon-service/telegram-token) avec chmod 600. Ne jamais le committer.

4. Dashboards rapides avec Docker

CAdvisor — métriques conteneurs

docker run -d \ --name=cadvisor \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:ro \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --volume=/dev/disk/:/dev/disk:ro \ --publish=8080:8080 \ --detach=true \ --stop-signal=SIGTERM \ gcr.io/cadvisor/cadvisor:latest

Interface web accessible sur http://<IP>:8080. API JSON sur http://<IP>:8080/metrics.

CAdvisor est maintenu par Google mais les releases sont rares. Pour un usage production, Prometheus avec node_exporter + cadvisor comme scrape target est plus robuste. Ici, c’est un dépannage rapide, pas un remplacement.

Node Exporter — métriques hôte

docker run -d \ --name=node_exporter \ --net=host \ --pid=host \ -v "/:/host:ro,rslave" \ prom/node-exporter \ --path.rootfs=/host

Métriques accessibles sur http://<IP>:9100/metrics.

--net=host est nécessaire pour que Node Exporter écoute directement sur l’hôte. --pid=host permet de lire les processus depuis l’hôte. Le volume rootfs expose le système de fichiers avec les bons chemins internes.

Uptime Kuma — disponibilité des services

Un outil léger qui surveille si un service répond (HTTP, TCP, ping, DNS) et envoie une alerte en cas d’indisponibilité. Dashboard web + status page intégrée.

docker run -d \ --restart=unless-stopped \ -v uptime-kuma:/app/data \ -p 3001:3001 \ lscr.io/linuxserver/uptime-kuma

Dashboard accessible sur http://<IP>:3001. Première connexion : création d’un compte admin.

Ajouter une sonde :

  1. Cliquer Ajouter un nouveau monitoring (bouton vert en haut à droite).
  2. Choisir le type : HTTP(s) pour un site web, TCP Port pour un port, Ping pour un host.
  3. Remplir l’URL ou l’hôte, définir l’intervalle (minimum 1 minute).
  4. Dans l’onglet Notification, sélectionner un canal (Telegram, email, webhook).

L’image lscr.io/linuxserver/uptime-kuma inclut Node.js et les dépendances — pas besoin de Dockerfile custom. Le volume /app/data persiste les configurations et l’historique des sondes.

Pour une status page publique (ex. monservice.mondomain.com/status) :

  1. Dans les paramètres d’une sonde, activer Status Page.
  2. Un lien public est généré automatiquement.
  3. Personnaliser le titre, le logo et la description depuis Paramètres → Status Page.

Uptime Kuma envoie une alerte dès la première défaillance (pas d’atténuation). Pour réduire le bruit, configurer un délai avant notification (Notification Delay) de 2-5 minutes dans les paramètres de la sonde.

5. Alertmanager — notifications structurées

Pour recevoir des alertes plus élaborées qu’un simple curl vers Telegram.

docker-compose.yml

Un seul conteneur suffit grâce au receiver Telegram natif d’Alertmanager.

version: "3.8" services: alertmanager: image: prom/alertmanager:latest ports: - "9093:9093" volumes: - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro restart: unless-stopped

alertmanager.yml

global: resolve_timeout: 5m route: receiver: telegram group_by: [alertname] group_wait: 10s group_interval: 10s repeat_interval: 1h receivers: - name: telegram telegram_configs: - api_url: "https://api.telegram.org" bot_token: "123456:ABC-DEF..." chat_id: "-100123456789" parse_mode: Markdown

Copier le bot_token depuis la configuration du bot Telegram (@BotFather). Le chat_id d’un groupe commence par -100 ; celui d’un particulier est un entier positif.

Vérifier qu’Alertmanager tourne

curl -s http://localhost:9093/api/v1/status | jq '.cluster.status' # → "healthy"

Tester l’envoi d’une alerte manuelle

curl -X POST http://localhost:9093/api/v1/alerts \ -H 'Content-Type: application/json' \ -d '[{ "labels": { "alertname": "test", "severity": "warning" }, "annotations": { "summary": "Test de notification" } }]'

Le Telegram natif d’Alertmanager gère le formatage Markdown sans conteneur intermédiaire. Plus de dépendance à une image tierce, plus de risque de casser lors d’une mise à jour.

6. Checklist monitoring complet

# Logs récents du service critique journalctl -u mon-service -n 20 --no-pager # Dashboard rapide (si cadvisor tourne) curl -s http://localhost:8080/api/v1.3/containers/ | jq 'keys' # Espace disque df -h / # RAM free -h # Processus qui consomment le plus ps aux --sort=-%mem | head -5

Dépannage rapide

# Le service ne crée plus de logs ? systemctl status mon-service # Le disque est plein, on identifie le coupable ? du -sh /* 2>/dev/null | sort -rh | head -5 # Le service ne répond plus ? curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health # Une alerte est reçue en boucle ? # Vérifier que le service est réellement en erreur (pas juste un seuil temporaire) journalctl -u mon-service -p err --since "10 minutes ago" --no-pager

Pitfalls fréquents

PiègeCauseSolution
docker logs vide après redémarrageLogs stockés dans un driver éphémèreConfigurer un logging driver persistant (json-file avec max-size)
journalctl occupe des GoRotation désactivée par défaut sur certaines distrosAjouter MaxUse=500M dans /etc/systemd/journald.conf puis systemctl restart systemd-journald
Alertmanager envoie des alertes en bouclerepeat_interval trop court ou pas de group_byAugmenter repeat_interval ou grouper par alertname
Node Exporter ne donne pas de métriquesMauvais volume ou port non exposéVérifier --path.rootfs=/host et --net=host
CAdvisor crash au démarragePermissions refusées sur /sys ou /dev/diskAjouter les volumes --volume=/sys:/sys:ro et --volume=/dev/disk/:/dev/disk:ro
Telegram ne reçoit rienBOT_TOKEN invalide ou CHAT_ID manquantTester avec curl direct vers api.telegram.org
logrotate ne tourne pasLe cron daily inactif ou le fichier mal placéVérifier /etc/cron.daily/logrotate et lancer logrotate -d pour diagnostiquer

Ressources