◀ Retour au blog
Linux

Monitoring des performances Linux

Publié le 15 Mar 2024· 9 min de lecture
#Linux#Monitoring#Performance

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 :

  • htop affiche l'usage par cœur, la mémoire et le swap. Triez par colonne avec F6 et affichez l'arborescence des processus avec F5 pour voir quel parent a lancé quels enfants.
  • iostat -x 1 (paquet sysstat) rafraîchit chaque seconde. Surveillez %util (occupation du périphérique), r_await et w_await (latence moyenne en millisecondes) et aqu-sz (taille moyenne de la file d'attente). Une latence qui grimpe signale une saturation.
  • iftop montre le débit par connexion. Adaptez le nom d'interface : sur les distributions récentes, elle s'appelle souvent ens3 ou enp0s3 plutôt que eth0 (vérifiez avec ip -br link).
  • ps aux --sort=-%mem liste les processus les plus gourmands en mémoire. Remplacez par --sort=-%cpu pour 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_linear de 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.