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>&1Les logs Docker ne sont pas persistants par défaut. Si le conteneur redémarre, les anciens logs sont perdus sauf configuration de
logging driverdansdocker-compose.ymloudaemon.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-serviceAppliquer immédiatement (en cas de disque plein) :
sudo logrotate -f /etc/logrotate.d/mon-service
copytruncatepermet 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 2vmstat 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 -11Vé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 -hqui montre/à 95 % est souvent une urgence. Undurapide 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}%"
fiEnvoi 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
mailutilsné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_TOKENdans un fichier hors du dépôt (/etc/mon-service/telegram-token) avecchmod 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:latestInterface 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=/hostMétriques accessibles sur http://<IP>:9100/metrics.
--net=hostest nécessaire pour que Node Exporter écoute directement sur l’hôte.--pid=hostpermet de lire les processus depuis l’hôte. Le volumerootfsexpose 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-kumaDashboard accessible sur http://<IP>:3001. Première connexion : création d’un compte admin.
Ajouter une sonde :
- Cliquer Ajouter un nouveau monitoring (bouton vert en haut à droite).
- Choisir le type : HTTP(s) pour un site web, TCP Port pour un port, Ping pour un host.
- Remplir l’URL ou l’hôte, définir l’intervalle (minimum 1 minute).
- Dans l’onglet Notification, sélectionner un canal (Telegram, email, webhook).
L’image
lscr.io/linuxserver/uptime-kumainclut Node.js et les dépendances — pas besoin de Dockerfile custom. Le volume/app/datapersiste les configurations et l’historique des sondes.
Pour une status page publique (ex. monservice.mondomain.com/status) :
- Dans les paramètres d’une sonde, activer Status Page.
- Un lien public est généré automatiquement.
- 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-stoppedalertmanager.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: MarkdownCopier le
bot_tokendepuis la configuration du bot Telegram (@BotFather). Lechat_idd’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 -5Dé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-pagerPitfalls fréquents
| Piège | Cause | Solution |
|---|---|---|
docker logs vide après redémarrage | Logs stockés dans un driver éphémère | Configurer un logging driver persistant (json-file avec max-size) |
journalctl occupe des Go | Rotation désactivée par défaut sur certaines distros | Ajouter MaxUse=500M dans /etc/systemd/journald.conf puis systemctl restart systemd-journald |
| Alertmanager envoie des alertes en boucle | repeat_interval trop court ou pas de group_by | Augmenter repeat_interval ou grouper par alertname |
| Node Exporter ne donne pas de métriques | Mauvais volume ou port non exposé | Vérifier --path.rootfs=/host et --net=host |
| CAdvisor crash au démarrage | Permissions refusées sur /sys ou /dev/disk | Ajouter les volumes --volume=/sys:/sys:ro et --volume=/dev/disk/:/dev/disk:ro |
| Telegram ne reçoit rien | BOT_TOKEN invalide ou CHAT_ID manquant | Tester avec curl direct vers api.telegram.org |
logrotate ne tourne pas | Le cron daily inactif ou le fichier mal placé | Vérifier /etc/cron.daily/logrotate et lancer logrotate -d pour diagnostiquer |