## Introduction La surveillance et les alertes avec Bash sont essentielles pour maintenir la santé et la fiabilité des systèmes Linux, des applications et de l'infrastructure. Alors que les piles d'observabilité modernes offrent des tableaux de bord sophistiqués et des gestionnaires d'alertes, Bash reste un outil indispensable pour les vérifications rapides, les métriques personnalisées et l'automatisation légère. C'est le ciment qui relie des systèmes disparates, et un script Bash bien conçu peut détecter les problèmes avant qu'ils ne dégénèrent en pannes. Ce guide est conçu pour les développeurs, les consultants DevOps et les équipes techniques de startups qui doivent mettre en œuvre une surveillance et des alertes pratiques avec Bash. Il couvre le cycle de vie complet : de l'inventaire de votre environnement et de la configuration sécurisée des scripts de surveillance, à la vérification des diagnostics, à la gestion des pannes et au suivi d'une liste de contrôle opérationnelle. Chaque recommandation est versionnée, observable et réversible lorsque cela est possible. Vous trouverez des commandes concrètes, des extraits de configuration et des exemples avec les sorties attendues, afin de pouvoir les adapter à votre propre infrastructure. Tout au long de l'article, nous mettons l'accent sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'action, utiliser des espaces réservés au lieu de secrets réels, vérifier les résultats et documenter les chemins de récupération. Nous abordons également les pièges courants qui font trébucher même les administrateurs expérimentés, et comment les éviter. À la fin, vous disposerez d'un cadre robuste pour la surveillance et les alertes basées sur Bash que vous pourrez déployer en toute confiance. ## Inventaire des versions et de l'environnement Avant d'écrire le moindre script de surveillance, vous devez comprendre votre environnement. Un inventaire fiable vous indique ce qui est installé, quelles versions vous exécutez et comment les composants sont connectés. Ces informations sont essentielles pour choisir les bonnes commandes, interpréter les sorties et dépanner en cas de problème. Commencez par identifier le système d'exploitation et la version du noyau. Ces commandes sont en lecture seule et sûres à exécuter sur n'importe quel système : uname -a cat /etc/os-release Exemple de sortie de uname -a : Linux monitor-prod-01 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 13:30:08 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux Cela vous indique la version du noyau (5.15), la distribution (Ubuntu) et l'architecture (x86_64). Le fichier /etc/os-release fournit les détails de la distribution : NAME="Ubuntu" VERSION="20.04.6 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.6 LTS" VERSION_ID="20.04" Connaître la version exacte du système d'exploitation est crucial car la syntaxe des commandes et les outils disponibles varient selon les versions. Par exemple, ss a remplacé netstat dans les distributions récentes, et systemd n'est pas disponible sur les anciens systèmes d'init. Ensuite, inventoriez les outils de surveillance eux-mêmes. Vérifiez si les utilitaires courants sont installés et leurs versions : bash --version | head -1 curl --version | head -1 jq --version awk --version | head -1 Si un outil manque, notez-le. Les scripts de surveillance s'appuient souvent sur curl pour les vérifications d'API, jq pour l'analyse JSON et awk pour le traitement de texte. Installez les paquets manquants à l'aide de votre gestionnaire de paquets uniquement après avoir vérifié que le changement est sûr. Pour les systèmes exécutant des charges de travail conteneurisées, vérifiez les versions de Docker et Docker Compose : docker --version docker compose version Exemple de sortie : Docker version 24.0.7, build afdd53b Docker Compose version v2.21.0 Si vous utilisez Kubernetes, vérifiez l'accès au cluster et la version : kubectl version --short Cela inventorie les versions du client et du serveur, ce qui est essentiel pour la compatibilité des API. Utilisez ces commandes d'inventaire pour documenter votre base de référence. Stockez la sortie dans un fichier sous contrôle de version ou dans une base de données de gestion de configuration. Cette base de référence vous aidera à détecter les dérives et à résoudre les problèmes ultérieurement. Lors de l'écriture de scripts de surveillance, utilisez toujours des espaces réservés explicites pour les noms d'hôtes, les chemins et les informations d'identification. Par exemple, au lieu de coder en dur https://api.production.example.com , utilisez une variable comme API_ENDPOINT="https://${API_HOST}:${API_PORT}/health" . Cela rend les scripts portables et évite l'exposition accidentelle d'informations sensibles. ## Chemin de configuration sécurisé Une fois que vous comprenez votre environnement, vous avez besoin d'un chemin de configuration sécurisé pour vos scripts de surveillance. Cela signifie séparer l'observation de l'intervention, protéger les informations d'identification et effectuer des modifications petites et réversibles. Un chemin de configuration bien conçu réduit le risque de casser les systèmes de production pendant que vous mettez en place la surveillance. Commencez par créer un répertoire dédié pour vos scripts de surveillance et vos fichiers de configuration. Utilisez un utilisateur non root avec des autorisations limitées : sudo mkdir -p /opt/monitoring/scripts sudo chown -R monitor:monitor /opt/monitoring Ensuite, créez un fichier de configuration qui stocke les valeurs spécifiques à l'environnement. Ce fichier ne doit être lisible que par l'utilisateur de surveillance : sudo touch /opt/monitoring/config.env sudo chmod 600 /opt/monitoring/config.env sudo chown monitor:monitor /opt/monitoring/config.env Dans config.env , définissez des variables pour les points de terminaison, les seuils et les cibles de notification. Ne stockez jamais de véritables informations d'identification en texte clair ; utilisez des variables d'environnement ou un gestionnaire de secrets. Exemple de fichier de configuration : # /opt/monitoring/config.env API_HOST="api.example.com" API_PORT="443" DISK_THRESHOLD_PERCENT="85" CPU_THRESHOLD_PERCENT="90" ALERT_EMAIL="ops@example.com" Vos scripts de surveillance doivent sourcer ce fichier pour charger les variables : #!/bin/bash # /opt/monitoring/scripts/check_api.sh source /opt/monitoring/config.env response=$(curl -s -o /dev/null -w "%{http_code}" "https://${API_HOST}:${API_PORT}/health") if [ "$response" -ne 200 ]; then echo "La vérification de santé de l'API a échoué avec HTTP $response" exit 1 fi echo "La vérification de santé de l'API a réussi" Ce script est en lecture seule : il effectue une requête HTTP GET et vérifie le code d'état. Il ne modifie aucun état. Le fichier de configuration sépare les paramètres du code, ce qui facilite la gestion entre les environnements. Lorsque vous devez apporter une modification, suivez ce modèle : - Sauvegardez la configuration actuelle avant de modifier : cp /opt/monitoring/config.env /opt/monitoring/config.env.bak.$(date +%Y%m%d) - Modifiez un élément à la fois . Par exemple, si vous devez changer le seuil de disque, ne modifiez que cette ligne. - Vérifiez le changement en exécutant le script en mode test. Ajoutez un drapeau --dry-run à vos scripts pour simuler des actions sans effets secondaires. - Documentez le chemin de récupération : si le changement provoque un comportement inattendu, restaurez la sauvegarde : cp /opt/monitoring/config.env.bak.20231015 /opt/monitoring/config.env Pour les environnements conteneurisés, assurez-vous que vos scripts de surveillance sont inclus dans l'image du conteneur ou montés en tant que volume. Dans Docker Compose, vous pouvez définir un service de surveillance qui exécute des vérifications périodiquement : # extrait de docker-compose.yml services: monitor: image: alpine:latest volumes: - /opt/monitoring/scripts:/scripts - /opt/monitoring/config.env:/config.env:ro command: ["/bin/sh", "/scripts/check_api.sh"] environment: - CONFIG_FILE=/config.env Cela maintient la surveillance près de l'application et simplifie le déploiement. Testez toujours les changements de configuration dans un environnement de préproduction avant de les appliquer à la production. ## Vérification et diagnostics La vérification et les diagnostics sont au cœur de tout système de surveillance. Vous devez savoir non seulement que quelque chose ne va pas, mais aussi pourquoi et comment le confirmer. Bash excelle à exécuter des vérifications rapides et ciblées qui révèlent l'état de votre système. Commençons par les vérifications de santé courantes du système. L'espace disque est une source fréquente de problèmes. Utilisez df pour vérifier l'utilisation : df -h / Sortie attendue : Filesystem Size Used Avail Use% Mounted on /dev/sda1 50G 20G 28G 42% / Pour alerter automatiquement lorsque l'utilisation du disque dépasse un seuil, écrivez un script : #!/bin/bash THRESHOLD=85 USAGE=$(df -h / | awk 'NR==2 {gsub("%","",$5); print $5}') if [ "$USAGE" -ge "$THRESHOLD" ]; then echo "L'utilisation du disque est de ${USAGE}%, dépassant le seuil de ${THRESHOLD}%" exit 1 else echo "L'utilisation du disque est de ${USAGE}%, dans la limite" fi Exécutez-le : ./check_disk.sh Sortie lorsque tout va bien : L'utilisation du disque est de 42%, dans la limite Lorsque le seuil est dépassé : L'utilisation du disque est de 87%, dépassant le seuil de 85% Le script se termine avec le code 1 en cas d'échec, ce qui est utile pour l'intégration avec cron ou les systèmes CI. La charge CPU est une autre métrique critique. Utilisez uptime pour voir les moyennes de charge : uptime Sortie : 14:32:10 up 30 days, 5:12, 1 user, load average: 0.80, 0.60, 0.55 Les trois nombres représentent la moyenne de charge sur 1, 5 et 15 minutes. Comparez-les au nombre de cœurs CPU. Une moyenne de charge constamment supérieure au nombre de cœurs indique une surcharge. Utilisez nproc pour obtenir le nombre de cœurs : nproc # Sortie : 4 Un script peut vérifier si la moyenne de charge sur 1 minute dépasse 80 % du nombre de cœurs : #!/bin/bash CORES=$(nproc) LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | tr -d ' ') THRESHOLD=$(echo "$CORES * 0.8" | bc) if (( $(echo "$LOAD > $THRESHOLD" | bc -l) )); then echo "Charge élevée : $LOAD dépasse le seuil $THRESHOLD" exit 1 fi echo "Charge normale : $LOAD" Cela utilise bc pour l'arithmétique à virgule flottante. Assurez-vous que bc est installé ou utilisez des mathématiques entières. L'utilisation de la mémoire peut être vérifiée avec free : free -h Sortie : total used free shared buff/cache available Mem: 7.7Gi 2.1Gi 3.2Gi 120Mi 2.4Gi 5.3Gi Swap: 2.0Gi 0B 2.0Gi La colonne available est essentielle : elle montre la mémoire disponible pour les nouveaux processus. Alertez si la mémoire disponible tombe en dessous d'un seuil, disons 10 % de la mémoire totale. Pour les vérifications spécifiques à l'application, simulez ce qu'un utilisateur ferait. Si vous avez un service web, utilisez curl pour tester le temps de réponse et le statut : curl -o /dev/null -s -w 'HTTP %{http_code} in %{time_total}s\n' https://api.example.com/health Sortie : HTTP 200 in 0.321s Les diagnostics de journaux sont essentiels. Vérifiez les erreurs récentes dans les journaux système ou les journaux d'application. Utilisez journalctl pour les services systemd : journalctl -u myapp.service -n 20 --no-pager Si vous voyez des erreurs répétées, approfondissez l'enquête. Vous pouvez également utiliser grep pour rechercher des motifs spécifiques : grep -i "error" /var/log/myapp/app.log | tail -10 Corrélez toujours les diagnostics avec les métriques. Par exemple, si l'utilisation du disque est élevée, trouvez quels fichiers consomment de l'espace : sudo du -ah /var/log | sort -rh | head -10 Cela montre les plus gros fichiers et répertoires, vous aidant à décider quoi faire pivoter ou supprimer. ## Modes de défaillance et récupération Aucun système de surveillance n'est parfait. Les choses échouent : les scripts plantent, les seuils sont mal configurés, les alertes disparaissent. Comprendre les modes de défaillance courants et avoir un plan de récupération est crucial pour la résilience opérationnelle. Mode de défaillance 1 : Le script se termine de manière inattendue en raison de dépendances manquantes. Votre script de surveillance peut dépendre de jq ou curl , mais ces outils peuvent ne pas être installés sur un nouveau serveur. Le script échoue avec une erreur « commande introuvable » et aucune alerte n'est envoyée. Récupération : Ajoutez des vérifications de dépendances au début de chaque script. Utilisez une fonction pour vérifier les commandes requises : #!/bin/bash REQUIRED_CMDS=("curl" "jq" "awk") for cmd in "${REQUIRED_CMDS[@]}"; do if ! command -v $cmd &> /dev/null; then echo "Erreur : $cmd n'est pas installé" exit 127 fi done Cela garantit un message d'erreur clair et un code de sortie non nul. Incluez des instructions d'installation dans votre manuel d'exploitation. Mode de défaillance 2 : Les seuils sont trop sensibles ou trop laxistes. Si votre seuil de disque est fixé à 70 % sur un système qui utilise habituellement 75 % pour des travaux par lots, vous obtiendrez de fausses alarmes. Inversement, s'il est fixé à 95 %, vous risquez de manquer d'espace avant qu'une alerte ne se déclenche. Récupération : Établissez une base de référence de vos métriques sur une période (par exemple, 30 jours) pour comprendre les plages normales. Utilisez des outils comme sar ou des scripts de collecte personnalisés pour rassembler des données historiques. Ensuite, fixez des seuils avec hystérésis : alertez lorsque l'utilisation dépasse 85 % pendant trois vérifications consécutives, et effacez lorsqu'elle descend en dessous de 80 %. Cela évite les fluctuations. Mode de défaillance 3 : Les alertes ne sont pas livrées. Votre script envoie un e-mail via mailx , mais le serveur SMTP est mal configuré ou l'e-mail est marqué comme spam. Vous pensez que tout va bien, mais personne ne reçoit les alertes. Récupération : Testez régulièrement la livraison des alertes. Utilisez un mécanisme d'alerte dédié comme un webhook vers une plateforme de chat (Slack, Discord) ou un service de notification push. Par exemple, envoyez une charge utile JSON à un webhook Slack : #!/bin/bash WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" MESSAGE="Utilisation du disque critique sur $(hostname)" curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$MESSAGE\"}" "$WEBHOOK_URL" Stockez l'URL du webhook dans un fichier de configuration sécurisé, pas dans le script. Testez le webhook indépendamment avant de vous y fier. Mode de défaillance 4 : Le script de surveillance consomme lui-même trop de ressources. Un script mal écrit qui s'exécute toutes les minutes et engendre plusieurs processus peut ajouter de la charge au système, aggravant les problèmes qu'il est censé détecter. Récupération : Optimisez les scripts. Utilisez les fonctionnalités intégrées de Bash au lieu de commandes externes lorsque c'est possible. Par exemple, utilisez [[ ]] pour les tests au lieu d'appeler test . Utilisez awk efficacement et évitez les tuyaux lorsque vous le pouvez. Planifiez les vérifications avec cron à des intervalles appropriés : vérifications de disque toutes les 15 minutes, vérifications d'API toutes les minutes si nécessaire. Surveillez le moniteur : vérifiez l'utilisation des ressources du script lui-même avec time ou ps . Mode de défaillance 5 : Dérive de configuration. Avec le temps, les serveurs sont patchés, les applications sont mises à jour et les chemins changent. Vos scripts de surveillance peuvent référencer d'anciens chemins ou versions, entraînant des faux négatifs. Récupération : Traitez la configuration de surveillance comme du code. Stockez les scripts et les configurations dans un contrôle de version (Git). Utilisez des outils de gestion de configuration (Ansible, Puppet, Chef) pour les déployer et les mettre à jour. Exécutez un script d'audit périodique qui compare la configuration déployée avec l'état prévu du contrôle de version. Ayez toujours un plan de retour en arrière. Conservez des sauvegardes des configurations et scripts précédents. Documentez les étapes exactes pour restaurer le service si un changement casse la surveillance. Testez les procédures de récupération dans un environnement de préproduction. ## Liste de contrôle opérationnelle Pour garantir que votre système de surveillance Bash reste efficace, suivez une liste de contrôle opérationnelle de routine. Cette liste vous aide à détecter les problèmes tôt, à maintenir la cohérence et à vous améliorer continuellement. Attribuez un responsable unique à chaque élément pour assurer la responsabilité. Passez en revue la liste chaque semaine ou après tout changement d'infrastructure significatif. Voici une liste de contrôle pratique que vous pouvez adapter :
| Vérification | Commande / Méthode | Résultat attendu | Responsable | Fréquence |
|---|---|---|---|---|
| Utilisation du disque sur la racine | df -h / | Utilisation inférieure à 85 % | Priya Shah, Administrateur système | Quotidienne |
| Charge moyenne CPU | uptime | Charge sur 1 min < 80 % des cœurs | Priya Shah | Quotidienne |
| Mémoire disponible | free -h | Disponible > 10 % du total | Priya Shah | Quotidienne |
| Point de terminaison de santé de l'API | curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health | HTTP 200 | Marcus Chen, DevOps | Toutes les 15 min |
| Erreurs critiques dans les journaux | grep -i "error" /var/log/myapp/app.log | tail -10 | Aucune nouvelle erreur critique | Elena Rodriguez, Support applicatif | Horaire |
| Test de livraison d'alerte | Envoyer un webhook/e-mail de test | Reçoit l'alerte de test | Marcus Chen | Hebdomadaire |
| Syntaxe des scripts de surveillance | bash -n /opt/monitoring/scripts/*.sh | Aucune erreur de syntaxe | Priya Shah | Après tout changement |
| Permissions du fichier de configuration | ls -l /opt/monitoring/config.env | -rw------- (600) | Priya Shah | Mensuelle |
| Disponibilité des dépendances | for cmd in curl jq awk; do command -v $cmd; done | Toutes les commandes trouvées | Elena Rodriguez | Mensuelle |
| Révision des seuils | Comparer l'historique des métriques | Seuils appropriés | Marcus Chen | Trimestrielle |