supervision : ce que l'ETL transforme, pas seulement qu'il tourne (#244) #245
No reviewers
Labels
No labels
Compat/Breaking
EC01
EC02
EC03
EC04
EC05
EC06
Kind/BDD
Kind/Back
Kind/Bug
Kind/CICD
Kind/Cloud
Kind/Contenu
Kind/Data
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Front
Kind/IA
Kind/Infra
Kind/Monitoring
Kind/Security
Kind/Testing
Portée/Post-jury
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
ops/alerte
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
g2/enervision!245
Loading…
Reference in a new issue
No description provided.
Delete branch "gabriel/244-supervision-etl"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ferme le #244.
Le trou
Depuis le #228, les trois passes de l'ETL publient leur état : code de retour, durée, dernière réussite. Elles ne publient pas ce qu'elles ont fait. Une passe argent qui rend 0 sans rien écrire ressemble, en supervision, trait pour trait à une passe qui a traité 5 040 lignes. Et quand la chaîne décroche,
chaine-donneemontre la zone or vieillir sans dire lequel des trois maillons a lâché : le diagnostic se faisait entailsursilver.log.Grafana ne peut pas aller chercher ces volumes lui-même — l'argent et l'or vivent dans DuckDB et MinIO, que Grafana ne lit jamais (§ 7 des exigences collectives). Ils sont donc publiés par les passes, par le mécanisme textfile déjà en place.
Ce que ça ajoute
Trois métriques étiquetées par zone du médaillon (
argent,or,base) :ev_etl_lignes_ecrites{zone}ev_etl_jour_traite_timestamp_seconds{zone}ev_etl_dernier_refus_timestamp_seconds{zone}La deuxième attrape le mode de panne le plus sournois de la chaîne :
load-postgrespeut réussir tous les quarts d'heure en rechargeant indéfiniment la même journée d'hier, parce que la zone argent ne lui en propose plus de nouvelle. Code 0, dernière réussite fraîche, alerte muette, et la base gèle en silence.Plus le tableau de bord
etl.json, dix panneaux, dont « Où la donnée s'est arrêtée » : si l'argent est à jour et que l'or et la base traînent d'une journée, le maillon cassé est l'or, et c'estgold.logqu'on ouvre — pas les trois.Le retard par zone ne demande aucune métrique nouvelle :
ev_ops_tache_derniere_reussite_timestamp_secondsdu #228 le porte déjà pour les trois tâches. Ce qui manquait, c'était de les mettre côte à côte.Les deux points à regarder en revue
1. Le répertoire textfile garde UN SEUL écrivain. Le job Python dépose un résumé avec
--resume, le lanceur le publie. node-exporter concatène tout le répertoire : une seule ligne mal formée y fait échouer la collecte entière, donc emporterait aussi les métriques des six autres tâches. D'où trois précautions cumulées — le résumé ne porte que des entiers (une journée y est un horodatage epoch, jamais une date ISO), le lanceur les refiltre sur[0-9]+, et l'étiquettezonevient du littéral du lanceur, jamais du fichier. Le banc fait passer un résumé hostile au mécanisme et vérifie qu'il ne publie rien.2. Le refus de journée de la zone argent passe du code 1 au code 4. C'est le seul changement de comportement public de ce lot. Le 4 est celui que le contrat des codes de sortie réserve déjà à « journée refusée » et que la zone or rendait seule ; l'écart était connu, et
docs/runbooks/etl.mddevait en faire un avertissement (« Attention au refus de la zone argent : il vaut 1, pas 4 »), tandis queservices/etl/README.mddemandait explicitement de l'aligner « dans un lot qui touchera les deux ». Un refus se corrige en regardant la source, une panne en regardant le job : le code doit permettre de trancher sans ouvrir le journal, ce qu'il ne permettait pas tant qu'il se confondait avec le 1 générique d'une trace Python. Aucun test ne fixait l'ancien code ; les deux documents sont corrigés.Vérifications jouées
pytest tests/unit/etl tests/unit/silver tests/unit/gold→ 325 passent.bash tests/ci/test-supervision.sh→ tout passe, dont trois cas qui exécutent le mécanisme au lieu de le lire pargrep: un résumé bien formé devient une métrique, un résumé aux valeurs non entières n'est pas publié, un répertoire absent ne demande rien au job./var/log/enervision(code inchangé, rien d'écrit, aucune plainte). La brancheflock, celle qui tourne en production, éprouvée avec unflockde substitution : macOS n'en a pas.ruff check+format --checketmypy --strictsuretl: propres.Preuve à joindre après déploiement
et une capture du tableau de bord
etlpendant que la zone or est volontairement en retard d'un quart d'heure.