Aller au contenu principal

Sucre observability

Cette page documenté comment sucre voit le homelab et où il bipe — pas le design sucre (voir Projet Sucre) mais l'architecture de l'observation et la delivery.

sucre est arrêté depuis le 2026-08-25

Cette page décrit une architecture d'observation qui ne tourne plus. Elle est conservée parce que le LXC 105 et sa base sont intacts et qu'un retour en arrière tient en deux commandes — voir Bilan et arrêt. La détection est passée à Pulse Patrol.

Surface d'observation de sucre​

Schéma agrandi
100 %

3 streams Loki que sucre observé :

  1. job=docker : stdout des containers Docker (adguard, traefik, authelia, etc.) shipped par Alloy
  2. job=journald : journalctl des hosts galahad/lancelot/penny shipped par Alloy
  3. job=monitor-alerts (nouveau 2026-05-04) : alertes émises par homelab_monitor.sh (alert() push à Loki en plus du ntfy)

Le 3ème stream est ce qui ferme un gap critique : avant le 04/05, sucre ne voyait pas les alertes "backup stale", "sucre-down", "AdGuard desync" parce qu'elles partaient en ntfy direct. Maintenant elles arrivent dans Loki, sucre peut classifier+drafter dessus.

Loki query filter (sucre.config.loki_query)​

{job=~".+"}
!~ "^\\[EGRESS-"
!~ "martian source"
!~ "auth key pair too old"
| detected_level=~"error|warn|warning|critical|fatal"
| job!~"fail2ban|monitor"

Décomposé :

StageEffet
{job=~".+"}Stream selector — tous les streams Loki
!~ "^\[EGRESS-"Drop les logs kernel iptables firewall (EGRESS-HOST/EGRESS-DOCKER) — bruit réseau, pas d'incident
!~ "martian source"Drop kernel routing asymétrique sur bridges Proxmox — comportement normal LXC
!~ "auth key pair too old"Drop pvestatd auth key rotation auto — comportement normal Proxmox
| detected_level=~"error|warn..."Filtre structured metadata pour level (post stream selector)
| job!~"fail2ban|monitor"Drop fail2ban INFO floods + monitor INFO logs (mais monitor-alerts passe ✓)

Note technique : les !~ line filters sont placés AVANT les | label filters dans la pipeline LogQL — c'est la syntaxe correcte (line filters bare, label filters préfixés |).

Ntfy delivery — pourquoi 2 topics​

Topic 1 — ae8fcbd80e6c5fa1b6c39f013da61d4e (homelab generic)​

Property : RESILIENT — bypass sucre entirely. Si sucre meurt, ces alertes arrivent quand même.

SourceComportement
homelab_monitor.shALERT [tag] ntfy
homelab_backup.shFAILED only (post-2026-05-04)
lynis-weekly.shéchec ou score < 70
vault/logs/dnsfailoverbackup FAILED
watchtowerECHEC + Skipped (level=warn)
ct-log-monitor.shnouveau sous-domaine
sucre-down canaryBYPASS sucre — survival critical

Topic 2 — sucre-homelab-c1e65af331c04569b97a (sucre proposals)​

Property : SMART — callback flow /approve/{proposal_id} POST back to sucre:8080. Demande sucre runtime alive.

SourceComportement
sucre.proposer.NtfyNotifierApprove/Deny callback flow
sucre.drafter.PatternDrafterdrafter PR ready notif

Pourquoi pas un seul topic​

Le callback handler de sucre (/approve/{id}) attend que les requests viennent UNIQUEMENT des proposals sucre. Si on mélange les topics :

  • Watchtower ntfy "Maj auto OK" arrive dans topic unique
  • Tu cliques sur la notif Watchtower (curieux/par erreur)
  • ntfy fire le callback URL configurée (qui pointe vers sucre)
  • Sucre reçoit un proposal_id qui n'existe pas → 404

Isolation namespace via 2 topics = bonne séparation de concerns.

Phone côté​

L'app ntfy iOS subscribe les 2 topics. Tu vois un seul inbox unifié. La séparation est invisible côté UX, présente côté code/résilience.

Centralisation = OBSERVATION, pas DELIVERY​

Une question naturelle : "sucre ne devrait-il pas être central, point unique de tout ?"

AxeRéponse
Observation (sucre voit tout)✅ Oui, c'est le but. Step B (2026-05-04) ferme le dernier gap (monitor→Loki). Sucre a maintenant ~5x plus de signal.
Delivery (sucre envoie tout)❌ Non, fragile. La sucre-DOWN canary doit bypass sucre (sinon sucre mort = silence indistinguable). Loki down ne doit pas casser les alertes critiques (qui restent en ntfy direct topic 1).

Le centralisme intelligent est sur l'observation. La delivery reste distribuée pour la résilience. C'est un design conscient, pas un accident.

Healthchecks.io — le canary deadman​

Voir notif-hygiene pour le setup. C'est complémentaire de sucre-observability :

  • Sucre observé via Loki → détecte les pannes des SERVICES qu'il watch
  • Healthchecks.io ping → détecte la panne du HOST penny qui run sucre + monitor

Sans healthchecks, "silence côté ntfy" = "tout va bien" OU "penny est mort", indistinguable.

Fichier de config​

Tout est dans /mnt/ssd/config/sucre/src/sucre/config.py :

VariableDefaultEffet
loki_querystring LogQLStream + filtres décrits ci-dessus
classifier_enabledTrueActiver/désactiver le LLM classifier
classifier_skip_sources{prometheus}Sources à pas classifier (noise)
classifier_rate_limit_window_s300Rate limit par (host, service)
classifier_rate_limit_max_calls1Max calls par window
drafter_enabledTrue (en prod)Activer drafter W5
drafter_dedup_window_h168Window dedup drafter (7j)
budget_hard_stop_eur20Hard stop mensuel Claude API
budget_soft_warn_eur10Soft warn ntfy mensuel Claude API