Surveiller les performances système
Un bon monitoring est essentiel pour détecter les problèmes avant qu'ils n'impactent les utilisateurs. Un disque qui se remplit, une fuite mémoire dans un worker PHP ou un processus qui monopolise le CPU se voient presque toujours dans les métriques des heures, voire des jours, avant la panne. Encore faut-il savoir quoi regarder, avec quels outils, et à partir de quel seuil réagir.
Cet article couvre deux niveaux complémentaires : le diagnostic en direct, quand vous êtes connecté en SSH sur une machine qui rame, et la surveillance continue, avec des métriques historisées et des alertes automatiques.
Une méthode avant les outils
Face à un serveur lent, la tentation est de lancer htop et de fixer l'écran. Une approche plus efficace consiste à passer en revue chaque ressource (CPU, mémoire, disque, réseau) en se posant trois questions, selon la méthode USE popularisée par Brendan Gregg :
- Utilisation : quel pourcentage du temps la ressource est-elle occupée ?
- Saturation : y a-t-il du travail en file d'attente, faute de capacité ?
- Erreurs : la ressource signale-t-elle des erreurs (paquets perdus, erreurs d'E/S) ?
Une ressource peut être utilisée à 100 % sans problème, tant qu'il n'y a pas de saturation. À l'inverse, un disque utilisé à 60 % avec une longue file d'attente est déjà un goulot d'étranglement.
Outils essentiels
# CPU et mémoire en temps réel
htop
# Statistiques disque
iostat -x 1
# Trafic réseau
iftop -i eth0
# Processus gourmands
ps aux --sort=-%mem | head -20
Quelques repères pour lire ces sorties :
htopaffiche l'usage par cœur, la mémoire et le swap. Triez par colonne avecF6et affichez l'arborescence des processus avecF5pour voir quel parent a lancé quels enfants.iostat -x 1(paquetsysstat) rafraîchit chaque seconde. Surveillez%util(occupation du périphérique),r_awaitetw_await(latence moyenne en millisecondes) etaqu-sz(taille moyenne de la file d'attente). Une latence qui grimpe signale une saturation.iftopmontre le débit par connexion. Adaptez le nom d'interface : sur les distributions récentes, elle s'appelle souventens3ouenp0s3plutôt queeth0(vérifiez avecip -br link).ps aux --sort=-%memliste les processus les plus gourmands en mémoire. Remplacez par--sort=-%cpupour le processeur.
Lire la mémoire et la charge correctement
Deux indicateurs sont très souvent mal interprétés. D'abord la mémoire : Linux utilise la RAM libre comme cache disque. Une valeur free proche de zéro est donc normale. La colonne qui compte est available, l'estimation de la mémoire utilisable sans recourir au swap.
Ensuite le load average : les trois valeurs affichées par uptime sont des moyennes sur 1, 5 et 15 minutes du nombre de processus en cours d'exécution ou en attente. Sous Linux, elles incluent aussi les processus bloqués en attente d'E/S. Une charge de 4 sur une machine à 4 cœurs signifie que le processeur est pleinement occupé ; au-delà, des tâches attendent.
# Mémoire : regarder la colonne "available", pas "free"
free -h
# Charge moyenne sur 1, 5 et 15 minutes, et nombre de cœurs
uptime
nproc
# Vue synthétique toutes les secondes, 5 fois :
# r = processus en attente de CPU, si/so = swap, wa = attente E/S
vmstat 1 5
# Pression sur les ressources (noyau 4.20+)
cat /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io
Dans la sortie de vmstat, une colonne r durablement supérieure au nombre de cœurs indique une saturation CPU, et des valeurs non nulles en si/so indiquent que la machine swappe activement, ce qui dégrade fortement les performances. Les fichiers /proc/pressure/* (PSI) donnent directement le pourcentage de temps pendant lequel des tâches ont été retardées faute de ressource.
Monitoring avec Prometheus et Node Exporter
Les outils interactifs ne montrent que l'instant présent. Pour comprendre une dégradation progressive ou analyser un incident survenu la nuit, il faut des métriques historisées. Le couple Prometheus et Node Exporter est devenu le standard : Node Exporter expose les métriques du système (CPU, mémoire, disques, réseau, systèmes de fichiers) sur le port 9100, et Prometheus vient les collecter à intervalle régulier.
# Installation Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvfz node_exporter-*.tar.gz
sudo mv node_exporter-*/node_exporter /usr/local/bin/
Vérifiez la dernière version publiée sur la page des releases du projet avant d'installer. Ensuite, plutôt que de lancer le binaire à la main, faites-le tourner comme un service systemd, sous un utilisateur dédié sans shell :
sudo useradd --system --no-create-home --shell /usr/sbin/nologin node_exporter
# /etc/systemd/system/node_exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network-online.target
Wants=network-online.target
[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter --web.listen-address=127.0.0.1:9100
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://127.0.0.1:9100/metrics | grep node_load1
L'écoute sur 127.0.0.1 évite d'exposer les métriques sur Internet. Si Prometheus tourne sur une autre machine, écoutez sur l'interface privée et limitez l'accès au port 9100 avec le pare-feu. Côté Prometheus, il suffit d'ajouter une cible :
# prometheus.yml
scrape_configs:
- job_name: node
scrape_interval: 15s
static_configs:
- targets: ['10.0.0.5:9100']
Alertes système
Configurez des alertes pour les métriques critiques :
- CPU : alerte au-dessus de 80% pendant 5 minutes
- Mémoire : alerte au-dessus de 90%
- Disque : alerte au-dessus de 85%
- Load average : alerte au-dessus du nombre de CPUs
Traduits en règles Prometheus, ces seuils donnent le fichier suivant. La clause for impose que la condition reste vraie pendant une durée minimale, ce qui évite d'être réveillé par un pic de quelques secondes :
# /etc/prometheus/rules/node.yml
groups:
- name: node
rules:
- alert: HighCpuUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
- alert: HighMemoryUsage
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
for: 5m
labels:
severity: critical
- alert: DiskAlmostFull
expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100 > 85
for: 10m
labels:
severity: warning
- alert: HighLoadAverage
expr: node_load5 > on (instance) count by (instance) (node_cpu_seconds_total{mode="idle"})
for: 10m
labels:
severity: warning
La règle mémoire s'appuie sur MemAvailable et non sur la mémoire libre, pour les raisons expliquées plus haut. La règle de charge compare node_load5 au nombre de cœurs, compté à partir des séries CPU de chaque instance. Validez le fichier avec promtool check rules /etc/prometheus/rules/node.yml avant de recharger Prometheus, puis confiez l'envoi des notifications (e-mail, Slack…) à Alertmanager.
Scripts de monitoring personnalisés
Sur un petit serveur isolé, sans stack Prometheus, un script lancé par cron peut suffire à donner l'alerte :
#!/bin/bash
# check_resources.sh
CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
MEM=$(free -m | awk 'NR==2{printf "%.1f", $3*100/$2}')
DISK=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')
echo "CPU: ${CPU}% | MEM: ${MEM}% | DISK: ${DISK}%"
if (( $(echo "$CPU > 80" | bc -l) )); then
echo "ALERTE: CPU élevé !" | mail -s "Alerte serveur" [email protected]
fi
Ce script a quelques limites à connaître. La valeur CPU extraite de top correspond au temps utilisateur uniquement (us), et le format de la ligne dépend de la version et de la locale. La mémoire calculée est la mémoire « utilisée », qui exclut le cache. Enfin, la commande mail suppose un agent de messagerie configuré sur la machine. Il se planifie dans la crontab :
*/5 * * * * /usr/local/bin/check_resources.sh >> /var/log/check_resources.log 2>&1
Pièges courants
- Trop d'alertes : une alerte qui se déclenche tous les jours sans action est vite ignorée. Chaque alerte doit correspondre à une action concrète.
- Surveiller seulement l'intérieur : un serveur peut avoir d'excellentes métriques et être injoignable. Complétez avec une sonde externe sur vos URL publiques.
- Oublier les inodes : un disque peut être plein d'inodes avec de l'espace libre, typiquement à cause de millions de petits fichiers de session ou de cache. Vérifiez avec
df -i. - Ignorer la tendance : un disque à 70 % qui gagne 5 % par jour est plus urgent qu'un disque stable à 88 %. La fonction
predict_linearde Prometheus permet d'alerter sur la date de remplissage prévue.
En résumé
Pour le diagnostic, suivez une méthode (utilisation, saturation, erreurs) et lisez correctement la mémoire disponible et la charge. Pour la durée, installez Node Exporter comme service, collectez avec Prometheus et définissez un petit nombre d'alertes avec des seuils et des durées réalistes. Le meilleur monitoring n'est pas celui qui mesure tout, mais celui qui vous prévient à temps, et seulement quand c'est utile.