Doctrine posee par l exploitant : des lors que le site a son Loki, la journalisation de la frontiere et des hyperviseurs doit y etre dirigee. CE QUI ETAIT CASSE. La destination syslog d OPNsense pointait 10.17.20.11:3100 - une adresse de TENANT, sur le port de Loki, en UDP, ce que Loki ne sait pas lire. La VM a ete rasee ; une cible morte a arrete TOUTE la journalisation pendant dix jours. La destination a ete eteinte pour reparer et jamais remplacee. Deux fautes en une : plus de journaux, et une cible chez un locataire, ce que D-87 refuse dans l autre sens. L intention etait juste - bonnes facilites, info et au-dessus. On l a REPRISE telle quelle et change uniquement la destination : ces choix avaient ete faits, ce n etait pas a nous de les redecider. UN TRADUCTEUR, parce que Loki ne parle pas syslog : loki.source.syslog dans l Alloy qui tourne DEJA sur le collecteur. Port 1514 et non 514, donc ecoute sans privilege - un collecteur qui aurait besoin des droits du systeme pour entendre un equipement serait un mauvais echange. UNE REGLE DE RELABEL SANS GARDE N IGNORE PAS : ELLE EFFACE. Trois quarts d heure sur un symptome absurde - la configuration deposee portait host = "bifrost-1", visible dans le fichier, et le flux arrivait sans etiquette. Sans regex, la regle correspond TOUJOURS, meme quand sa source n existe pas, et pose host = "". Loki jette une etiquette vide, et celle de l ecouteur disparaissait avec elle. Et la verification finale a corrige une seconde erreur, la mienne : label/host/values rendait une liste en CACHE. La requete directe rendait bien un flux. Un index qui ne montre pas une chose ne prouve pas qu elle n existe pas. LA GARDE, qui manquait depuis l incident. journaux-frontiere demande a LOKI ce qu il a RECU, pas a la frontiere ce qu elle croit avoir envoye : la destination est le seul juge, et un emetteur qui parle a un trou noir se porte tres bien. La fenetre est DERIVEE du debit observe - environ 1500 lignes par minute - pas choisie. Trois etats eprouves sur une copie : frontiere muette rc=2, Loki injoignable rc=3, debit normal rc=0. Le 3 compte autant que le 2 : « je ne peux rien affirmer » n est pas « c est casse ». Mesure : 46 681 lignes recues en 30 min, site a 68 services tous OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
54 lines
2.3 KiB
Django/Jinja
54 lines
2.3 KiB
Django/Jinja
#!/bin/bash
|
|
# GENERE par Set-OPS (role serveur_loki). Ne pas editer a la main.
|
|
#
|
|
# SONDE « journaux-frontiere » — l'equipement qui voit TOUT parle-t-il encore ?
|
|
#
|
|
# Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2.
|
|
# Mise en defaut PAR PARAMETRE : `serveur_loki_sonde_frontiere_etiquette` (nom inconnu).
|
|
#
|
|
# POURQUOI CETTE SONDE EXISTE, ET POURQUOI ELLE EST LA PLUS IMPORTANTE DU LOT.
|
|
#
|
|
# La destination syslog de la frontiere a pointe une VM de TENANT, rasee depuis. Une cible
|
|
# morte a arrete TOUTE la journalisation d'OPNsense pendant DIX JOURS, et rien ne l'a
|
|
# signale : le boitier fonctionnait, le pare-feu filtrait, les regles s'appliquaient — il
|
|
# n'ecrivait simplement plus nulle part. On ne l'a su qu'en allant chercher un evenement
|
|
# qui n'avait jamais ete ecrit.
|
|
#
|
|
# Remettre la destination sans poser cette garde, ce serait reconstruire la meme panne en
|
|
# esperant s'en souvenir. Un equipement muet ne se plaint pas.
|
|
set -uo pipefail
|
|
|
|
URL={{ serveur_loki_sonde_url }}
|
|
ETIQ="{{ serveur_loki_sonde_frontiere_etiquette }}"
|
|
FENETRE={{ serveur_loki_sonde_frontiere_fenetre }}
|
|
|
|
# ON DEMANDE A LOKI CE QU'IL A RECU, pas a la frontiere ce qu'elle croit avoir envoye.
|
|
# La destination est le seul juge : un emetteur qui « envoie » vers un trou noir se porte
|
|
# tres bien, et c'est exactement ce qui s'est passe.
|
|
rep=$(curl -sk --max-time 15 -G "${URL}/loki/api/v1/query" \
|
|
--data-urlencode "query=count_over_time({host=\"${ETIQ}\", job=\"syslog\"}[${FENETRE}])" \
|
|
2>/dev/null)
|
|
[[ -n "${rep}" ]] || { echo "Loki ne repond pas sur ${URL} — la sonde ne peut rien affirmer."; exit 3; }
|
|
|
|
n=$(printf '%s' "${rep}" | python3 -c '
|
|
import json, sys
|
|
try:
|
|
d = json.load(sys.stdin)
|
|
except Exception:
|
|
print("-1"); raise SystemExit
|
|
r = (d.get("data") or {}).get("result") or []
|
|
print(int(sum(float(x.get("value", [0, 0])[1]) for x in r)))
|
|
' 2>/dev/null)
|
|
: "${n:=-1}"
|
|
|
|
perf="lignes=${n} fenetre=${FENETRE}"
|
|
if (( n < 0 )); then
|
|
echo "Reponse illisible de Loki — impossible de dire si la frontiere journalise. | ${perf}"
|
|
exit 3
|
|
fi
|
|
if (( n == 0 )); then
|
|
echo "LA FRONTIERE NE JOURNALISE PLUS : aucune ligne de « ${ETIQ} » depuis ${FENETRE}. | ${perf}"
|
|
exit 2
|
|
fi
|
|
echo "Frontiere journalise : ${n} ligne(s) recue(s) en ${FENETRE}. | ${perf}"
|
|
exit 0
|