#!/bin/bash # GENERE par Set-OPS (role serveur_icinga). Ne pas editer a la main. # # SONDE « moteur » — l'etat des controles arrive frais jusqu'a IcingaDB # # Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2. # Mise en defaut PAR PARAMETRE : `serveur_icinga_sonde_age_crit` (age impossible). set -uo pipefail CONF={{ serveur_icinga_sonde_config_db }} AVERT={{ serveur_icinga_sonde_age_avert }} CRIT={{ serveur_icinga_sonde_age_crit }} systemctl is-active --quiet icinga2 || { echo "Le moteur Icinga n'est pas actif."; exit 2; } systemctl is-active --quiet icingadb || { echo "La synchronisation IcingaDB n'est pas active."; exit 2; } # ON NE SE FIE PAS A `is-active` SEUL — c'est le mensonge que ce depot a deja paye avec # les sauvegardes : un service vert sur un travail qui n'aboutit pas. On demande a la BASE # depuis combien de temps elle n'a pas ete rafraichie. hote=$(grep -m1 -A5 '^database:' "${CONF}" 2>/dev/null | grep -m1 'host:' | awk '{print $2}') mdp=$(grep -m1 'password:' "${CONF}" 2>/dev/null | awk '{print $2}') base=$(grep -m1 -A5 '^database:' "${CONF}" 2>/dev/null | grep -m1 'database:' | awk '{print $2}') util=$(grep -m1 -A6 '^database:' "${CONF}" 2>/dev/null | grep -m1 'user:' | awk '{print $2}') [[ -n "${hote}" && -n "${mdp}" ]] || { echo "Configuration IcingaDB illisible (${CONF})."; exit 2; } # LE BATTEMENT D'ICINGADB, PAS LA FRAICHEUR DES ETATS (correction du 2026-09-10). # # La premiere version lisait `max(last_update)` de `service_state`. Mesure : IcingaDB # n'ECRIT QUE SUR CHANGEMENT D'ETAT. Un resultat identique repete ne produit aucune # ecriture — verifie en poussant un OK (rien ne bouge) puis un AVERTISSEMENT (ecrit en # 13 s). # # La sonde mesurait donc le CHANGEMENT, pas la fraicheur. Sur un ecosysteme parfaitement # STABLE — celui qu'on veut — plus rien ne change, `last_update` vieillit, et la sonde # serait passee en avertissement a 15 min puis en critique a 90 min. Une alarme qui se # declenche PARCE QUE tout va bien : exactement le piege que ce document interdit, avec # un delai qui l'aurait rendue difficile a comprendre. # # `icingadb_instance` porte le battement du synchroniseur, ecrit en continu qu'il y ait # ou non des changements. C'est lui qui dit « la chaine moteur -> Redis -> base est # vivante » — releve a 1 seconde sur un systeme sain. age=$(PGPASSWORD="${mdp}" psql -h "${hote}" -U "${util:-icingadb}" -d "${base:-icingadb}" -Atc \ "select coalesce((extract(epoch from now()) - max(heartbeat)/1000)::bigint, 999999) from icingadb_instance" 2>/dev/null) [[ "${age}" =~ ^-?[0-9]+$ ]] || { echo "La base de supervision ne repond pas (${hote})."; exit 2; } (( age < 0 )) && age=0 if (( age >= CRIT )); then echo "Synchronisation FIGEE : IcingaDB n'a pas battu depuis ${age} s — la supervision montre le passe.|age=${age}s;${AVERT};${CRIT};0;" exit 2 fi if (( age >= AVERT )); then echo "Battement d'IcingaDB vieillissant : ${age} s (seuil ${AVERT}).|age=${age}s;${AVERT};${CRIT};0;" exit 1 fi echo "Moteur et synchronisation vivants : IcingaDB a battu il y a ${age} s.|age=${age}s;${AVERT};${CRIT};0;"