Set-OPS-Public/roles/serveur_redis/templates/sonde-cache.sh.j2
Daniel Allaire 050b8b267e serveur_redis : la sonde qui manquait, et la panne qu elle voit
Redis est le premier des treize roles serveur_* sans supervision declaree.

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 — il ne repond pas, ou il repond et n a
rien a dire. Le second est le couteux : 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. La panne se presente
comme un defaut d application.

Le compteur d evictions est cumulatif : la sonde en fait un DEBIT, sinon une
seule mauvaise journee laisserait le voyant rouge pour toujours.

Pas d occupation memoire ni de taux de succes ici — ce sont des series, elles
appartiennent a Prometheus. Icinga repond a une seule question.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 09:20:10 -04:00

70 lines
3.3 KiB
Django/Jinja

#!/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