#!/bin/bash # GENERE par Set-OPS (role serveur_redis). Ne pas editer a la main. # # SONDE « cache » — le cache repond-il, et sert-il encore a quelque chose ? # # Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2. # Mise en defaut PAR PARAMETRE : `serveur_redis_sonde_evictions_crit` (seuil impossible). # # UNE SEULE SONDE, PARCE QU'IL N'Y A QU'UNE CAUSE D'ACTION : « le cache ne sert plus ». # Elle s'atteint par deux chemins, et le verdict appelle le meme geste — aller voir Redis. # # 1. IL NE REPOND PAS. Service mort, mot de passe rejete, ecoute perdue. # 2. IL REPOND ET N'A RIEN A DIRE. Borne a `maxmemory` avec `allkeys-lru`, un Redis # plein n'echoue jamais : il EVICTE. Les sessions disparaissent, les gens sont # deconnectes au hasard, et le service reste vert. C'est la panne la plus trompeuse # de ce composant — elle se presente comme un probleme d'application. # # CE QU'ON NE MESURE PAS ICI, ET C'EST LA DOCTRINE : l'occupation memoire, le taux de # succes du cache, la latence. Ce sont des SERIES ; elles appartiennent a Prometheus. # Icinga repond a une seule question — est-ce casse ? # # LE PORTEUR TOURNE EN root ; `redis-cli` lit le mot de passe dans la configuration que # le role a posee, jamais dans un argument de ligne de commande (il serait visible dans # `ps` de toute la machine). set -uo pipefail CONF={{ serveur_redis_config }} CRIT={{ serveur_redis_sonde_evictions_crit }} SERVICE={{ serveur_redis_service }} systemctl is-active --quiet "${SERVICE}" || { echo "Redis n'est pas actif."; exit 2; } mdp=$(grep -oP '(?<=^requirepass ).*' "${CONF}" 2>/dev/null) cli=(redis-cli --no-auth-warning) [[ -n "${mdp}" ]] && cli+=(-a "${mdp}") # UN `PING`, PAS UN `connect()`. Le port peut repondre alors que l'authentification # echoue : le client obtient une connexion et rien d'autre. `PING` traverse l'auth. pong=$("${cli[@]}" ping 2>&1) [[ "${pong}" == "PONG" ]] || { echo "Redis ne repond pas a PING : ${pong:0:70}"; exit 2; } lire() { "${cli[@]}" info "$1" 2>/dev/null | grep -oP "(?<=^$2:)[0-9]+" | tr -d '\r'; } evictions=$(lire stats evicted_keys) [[ "${evictions}" =~ ^[0-9]+$ ]] || { echo "Redis vivant, compteur d'evictions illisible."; exit 1; } # LE COMPTEUR EST CUMULATIF DEPUIS LE DEMARRAGE — on mesure donc un DEBIT, pas un total, # sinon la sonde vire au rouge pour toujours apres une seule mauvaise journee. etat=/var/lib/setops/sonde-redis-evictions prec=$(cat "${etat}" 2>/dev/null || echo "") mkdir -p "$(dirname "${etat}")" && echo "${evictions}" > "${etat}" memoire=$(lire memory used_memory) plafond=$("${cli[@]}" config get maxmemory 2>/dev/null | tail -1 | tr -d '\r') perf="evictions=${evictions}c memoire=${memoire:-0}B;;;0;${plafond:-0}" if [[ "${prec}" =~ ^[0-9]+$ ]] && (( evictions >= prec )); then depuis=$(( evictions - prec )) if (( depuis >= CRIT )); then echo "Redis evicte : ${depuis} cles depuis le dernier passage — des sessions se perdent en silence.|${perf}" exit 2 fi echo "Cache sain — ${depuis} eviction(s) depuis le dernier passage.|${perf}" exit 0 fi # Premier passage, ou compteur remis a zero par un redemarrage : on ne juge pas un debit # qu'on ne peut pas calculer. Vert, et on le DIT — un « inconnu » muet serait pire. echo "Cache sain — premier releve, debit d'eviction mesurable au prochain passage.|${perf}" exit 0