supervision : combler les angles morts — sondes, tâches planifiées, sorties produit (#228) #231

Merged
lenaic merged 1 commit from gabriel/228-angles-morts-supervision into develop 2026-09-09 08:46:48 +00:00
Member

Ferme #228.

Ce que la supervision ne voyait pas

Relevé sur la production ce matin. Toutes les cibles étaient vertes — elles
l'étaient sur ce qu'elles regardaient.

Trou Conséquence
Six des sept tâches cron ne publiaient aucune métrique l'arrêt de l'ETL, de la prévision ou des recommandations ne se voyait nulle part
Treize métriques probe_* collectées, affichées dans aucun panneau disponibilité et latence de l'API, de la forge et de Grafana invisibles
Le front n'était sondé nulle part un Caddy arrêté ou un /srv/www/app vide laissait toutes les sondes vertes
prevision, recommandation, alerte, qualite_jour sans aucun panneau les sorties du produit n'étaient pas monitorées
Notre API sans alerte, alors que l'API source en avait une

Ce que la PR change

Les sept tâches publient leur état. Le mécanisme sort de
collecte-current.sh vers bin/_metriques-ops.sh, sourcé par les sept
lanceurs. Chacun publie tentative, réussite, code, durée et cadence.

Les six lanceurs non instrumentés lançaient leur travail par exec : le shell
était remplacé, rien ne pouvait s'exécuter après. Ils gardent maintenant la
main, capturent le code, publient, ressortent avec le même code. Le banc
refuse désormais un exec en dernière ligne
— c'est ce qui empêchera le trou
de se rouvrir.

La cadence publiée permet une seule règle pour les sept tâches, au lieu de
sept seuils recopiés :

(time() - ev_ops_tache_derniere_reussite_timestamp_seconds)
    > 3 * ev_ops_tache_cadence_secondes

Deux tableaux de bord. disponibilite (frise par service, latences,
décomposition HTTP, table des sondes, table des tâches, âge des sauvegardes,
alertes en cours) et sorties-produit (prévisions, recommandations, alertes,
qualité — là où chaine-donnee s'arrête).

Le chemin du jury est sondé. Nouveau job blackbox-vhost qui traverse
Caddy en 443. app.g2.enervision ne se résolvant pas depuis le serveur, le nom
part en paramètre hostname, que blackbox pose en en-tête Host et en
SNI. MLflow et MinIO, eux non plus sondés, rejoignent le job blackbox.

Cinq alertes de plus, dans un second groupe « Disponibilité » — celui du
#42 reste intact, sans renumérotation ni relecture à refaire.

Ce que ça a déjà trouvé

En écrivant le tableau de bord des sorties, la requête a montré que cinq des
sept sites n'ont plus de prévision depuis hier 14 h
— seuls Toulouse et
Marseille sont servis. Le journal d'inférence le confirme (prévision périmée : elle vise 2026-09-08T14:00). Ce n'est pas corrigé ici — ce n'est pas le
périmètre du ticket — mais c'est exactement le genre de chose que la
supervision ne pouvait pas dire hier, et qu'elle dira demain. À regarder
avant la démonstration.

Vérifications

Contre la production, en lecture seule :

  • les quatre nouvelles sondes répondent 200 — conteneur blackbox jetable sur un
    port séparé, arrêté depuis ;
  • promtool check config accepte la configuration Prometheus ;
  • promtool check metrics accepte chacun des fichiers de métriques produits ;
  • les treize requêtes SQL du nouveau tableau de bord rendent le résultat
    attendu.

Sur un banc à faux interpréteur, les sept lanceurs : code de sortie
préservé
, métrique juste, fichier de réussite écrit seulement sur un succès,
et une passe de préproduction ne rafraîchit pas la fraîcheur de la production.

tests/ci/test-supervision.sh passe, enrichi de dix-huit cas d'essai. Les
douze autres bancs tests/ci/ passent aussi.

Risque et retour arrière

Le rechargement de Prometheus et le redémarrage de blackbox n'ont aucun effet
sur les services supervisés. Un tableau de bord invalide est refusé au
chargement sans toucher aux autres.

Le point sensible est la publication de métriques dans les six lanceurs. Trois
garde-fous : la publication est faite après la capture du code de retour et
n'en change pas la valeur ; toute écriture est gardée et ops_publier_resultat
rend toujours 0, donc une tâche ne peut pas échouer à cause de sa supervision ;
et l'écriture est atomique, node-exporter ne peut pas lire un fichier à moitié
écrit.

Retour arrière : git revert puis redéploiement --tags app,proxy.

Ce qui reste ouvert, volontairement

Trois trous, nommés dans le runbook (§ 9) et dans le ticket, à reprendre en
Portée/Post-jury : l'API n'expose aucune métrique applicative (/metrics),
donc ni taux d'erreur 5xx ni latence par route — l'ENF-04 n'est mesuré en
continu nulle part ; les journaux ne sont pas agrégés ; les métriques HTTP par
vhost de Caddy ne sont pas activées.

Leur correctif touche l'API (dépendance de plus, donc réinstallation du venv au
déploiement, et une règle Caddy pour ne pas exposer /api/metrics
publiquement) ou le Caddy de la forge, dont le fichier porte l'avertissement
« une erreur ici coupe la forge ». Pas dans une fenêtre de deux jours.

Ferme #228. ## Ce que la supervision ne voyait pas Relevé sur la production ce matin. Toutes les cibles étaient vertes — elles l'étaient sur ce qu'elles regardaient. | Trou | Conséquence | |---|---| | Six des sept tâches cron ne publiaient aucune métrique | l'arrêt de l'ETL, de la prévision ou des recommandations ne se voyait nulle part | | Treize métriques `probe_*` collectées, affichées dans aucun panneau | disponibilité et latence de l'API, de la forge et de Grafana invisibles | | Le front n'était sondé nulle part | un Caddy arrêté ou un `/srv/www/app` vide laissait **toutes** les sondes vertes | | `prevision`, `recommandation`, `alerte`, `qualite_jour` sans aucun panneau | les sorties du produit n'étaient pas monitorées | | Notre API sans alerte, alors que l'API source en avait une | — | ## Ce que la PR change **Les sept tâches publient leur état.** Le mécanisme sort de `collecte-current.sh` vers `bin/_metriques-ops.sh`, sourcé par les sept lanceurs. Chacun publie tentative, réussite, code, durée et **cadence**. Les six lanceurs non instrumentés lançaient leur travail par `exec` : le shell était remplacé, rien ne pouvait s'exécuter après. Ils gardent maintenant la main, capturent le code, publient, ressortent avec le même code. **Le banc refuse désormais un `exec` en dernière ligne** — c'est ce qui empêchera le trou de se rouvrir. La cadence publiée permet **une seule règle** pour les sept tâches, au lieu de sept seuils recopiés : ```promql (time() - ev_ops_tache_derniere_reussite_timestamp_seconds) > 3 * ev_ops_tache_cadence_secondes ``` **Deux tableaux de bord.** `disponibilite` (frise par service, latences, décomposition HTTP, table des sondes, table des tâches, âge des sauvegardes, alertes en cours) et `sorties-produit` (prévisions, recommandations, alertes, qualité — là où `chaine-donnee` s'arrête). **Le chemin du jury est sondé.** Nouveau job `blackbox-vhost` qui traverse Caddy en 443. `app.g2.enervision` ne se résolvant pas depuis le serveur, le nom part en paramètre `hostname`, que blackbox pose en en-tête `Host` **et** en SNI. MLflow et MinIO, eux non plus sondés, rejoignent le job `blackbox`. **Cinq alertes de plus**, dans un second groupe « Disponibilité » — celui du #42 reste intact, sans renumérotation ni relecture à refaire. ## Ce que ça a déjà trouvé En écrivant le tableau de bord des sorties, la requête a montré que **cinq des sept sites n'ont plus de prévision depuis hier 14 h** — seuls Toulouse et Marseille sont servis. Le journal d'inférence le confirme (`prévision périmée : elle vise 2026-09-08T14:00`). Ce n'est pas corrigé ici — ce n'est pas le périmètre du ticket — mais c'est exactement le genre de chose que la supervision ne pouvait pas dire hier, et qu'elle dira demain. **À regarder avant la démonstration.** ## Vérifications Contre la production, **en lecture seule** : - les quatre nouvelles sondes répondent 200 — conteneur blackbox jetable sur un port séparé, arrêté depuis ; - `promtool check config` accepte la configuration Prometheus ; - `promtool check metrics` accepte chacun des fichiers de métriques produits ; - les treize requêtes SQL du nouveau tableau de bord rendent le résultat attendu. Sur un banc à faux interpréteur, les sept lanceurs : **code de sortie préservé**, métrique juste, fichier de réussite écrit seulement sur un succès, et une passe de préproduction ne rafraîchit pas la fraîcheur de la production. `tests/ci/test-supervision.sh` passe, enrichi de dix-huit cas d'essai. Les douze autres bancs `tests/ci/` passent aussi. ## Risque et retour arrière Le rechargement de Prometheus et le redémarrage de blackbox n'ont aucun effet sur les services supervisés. Un tableau de bord invalide est refusé au chargement sans toucher aux autres. Le point sensible est la publication de métriques dans les six lanceurs. Trois garde-fous : la publication est faite **après** la capture du code de retour et n'en change pas la valeur ; toute écriture est gardée et `ops_publier_resultat` rend toujours 0, donc une tâche ne peut pas échouer à cause de sa supervision ; et l'écriture est atomique, node-exporter ne peut pas lire un fichier à moitié écrit. Retour arrière : `git revert` puis redéploiement `--tags app,proxy`. ## Ce qui reste ouvert, volontairement Trois trous, nommés dans le runbook (§ 9) et dans le ticket, à reprendre en `Portée/Post-jury` : l'API n'expose aucune métrique applicative (`/metrics`), donc ni taux d'erreur 5xx ni latence par route — l'ENF-04 n'est mesuré en continu nulle part ; les journaux ne sont pas agrégés ; les métriques HTTP par vhost de Caddy ne sont pas activées. Leur correctif touche l'API (dépendance de plus, donc réinstallation du venv au déploiement, **et** une règle Caddy pour ne pas exposer `/api/metrics` publiquement) ou le Caddy de la forge, dont le fichier porte l'avertissement « une erreur ici coupe la forge ». Pas dans une fenêtre de deux jours.
supervision: combler les angles morts — sondes, tâches, sorties produit (#228)
All checks were successful
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 46s
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 7s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 18s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m51s
ac70d4a054
Relevé sur la production le 09/09 : la supervision était verte sur ce qu'elle
regardait, pas sur ce qui pouvait casser. Cinq trous, comblés ici.

1. SIX TÂCHES PLANIFIÉES SUR SEPT NE PUBLIAIENT AUCUNE MÉTRIQUE. Seul
   `collecte-current.sh` déposait un `.prom`. L'arrêt de l'ETL argent, de
   l'ETL or, du chargement PostgreSQL, de la prévision ou des recommandations
   ne se voyait nulle part. Le mécanisme sort de `collecte-current.sh` vers
   `bin/_metriques-ops.sh`, que les sept lanceurs sourcent. Chacun publie
   tentative, réussite, code, durée et CADENCE — cette dernière permet une
   règle d'alerte unique pour les sept au lieu de sept seuils recopiés.

   Les six lanceurs lançaient leur travail par `exec` : le shell était
   remplacé, rien ne pouvait s'exécuter après. Ils gardent la main, capturent
   le code, publient, et ressortent avec le même code. Le banc de supervision
   refuse désormais un `exec` en dernière ligne.

2. TREIZE MÉTRIQUES `probe_*` COLLECTÉES, AFFICHÉES NULLE PART. Nouveau
   tableau de bord `disponibilite` : frise de disponibilité par service,
   latences, décomposition HTTP, table des sondes, table des tâches, âge des
   sauvegardes, et l'état des alertes sur le même écran.

3. LE FRONT N'ÉTAIT SONDÉ NULLE PART. Les sondes visaient chaque service sur
   son écoute directe : elles seraient restées vertes avec un Caddy arrêté, un
   vhost mal routé ou un `/srv/www/app` vide — les trois cas où plus personne
   ne peut ouvrir l'application. Nouveau job `blackbox-vhost` qui traverse
   Caddy en 443. `app.g2.enervision` ne se résolvant pas depuis le serveur, le
   nom part en paramètre `hostname`, que blackbox pose en Host et en SNI.
   MLflow et MinIO, eux non plus sondés, rejoignent le job `blackbox`.

4. LES SORTIES DU PRODUIT N'ÉTAIENT PAS MONITORÉES. `prevision`,
   `recommandation`, `alerte` et `qualite_jour` n'avaient aucun panneau : le
   tableau de bord « chaîne de donnée » s'arrête à la zone or. Nouveau
   tableau de bord `sorties-produit`, qui reprend là où il finit.

5. CINQ ALERTES MANQUAIENT. Notre API n'en avait aucune alors que l'API source
   en avait une ; s'y ajoutent l'application injoignable, PostgreSQL
   injoignable, une tâche planifiée en retard et la mémoire du serveur. Un
   second groupe « Disponibilité » les porte, celui du #42 reste intact. La
   règle « cible tombée » couvre en plus `noms-conteneurs` et le nouveau job.

Vérifié contre la production, en lecture seule : les quatre nouvelles sondes
répondent 200 (conteneur blackbox jetable, arrêté depuis), `promtool check
config` accepte la configuration, `promtool check metrics` accepte chaque
fichier de métriques, et les treize requêtes SQL du nouveau tableau de bord
rendent le résultat attendu. Les sept lanceurs sont joués sur un banc à faux
interpréteur : code de sortie préservé, métrique juste, fichier de réussite
écrit seulement sur un succès, et une passe de préproduction ne rafraîchit
pas la fraîcheur de la production.

Trois trous restent ouverts et sont nommés dans le runbook et le ticket :
l'API n'expose aucune métrique applicative, les journaux ne sont pas agrégés,
les métriques HTTP par vhost de Caddy ne sont pas activées. Leur correctif
touche l'API ou le Caddy de la forge — pas dans une fenêtre de deux jours.
lenaic approved these changes 2026-09-09 08:43:42 +00:00
lenaic left a comment

Relu en vérifiant, pas en croyant. Dix-sept fichiers dont les sept lanceurs cron : c'est l'endroit où une erreur arrête toute la chaîne en silence, donc c'est par là que j'ai commencé.

Ce que j'ai contrôlé

Point Résultat
RACINE défini avant le . du fichier commun, dans les sept oui, du 12/41 au 26/140 selon le lanceur
Code de sortie préservé sur les deux chemins de gold-daily oui, le 75 du verrou est publié tel quel et ne rafraîchit pas la réussite
Les sept cadences déclarées contre les vraies crontabs exactes toutes les sept : 60 / 60 / 900 / 900 / 900 / 3600 / 3600
Les deux tableaux de bord JSON valides, 16 et 13 panneaux
rules.yaml, prometheus.yml, blackbox.yml, docker-compose.yml tous valides à l'analyse
tests/ci/test-supervision.sh passe, garde de l'exec comprise

Le point qui m'inquiétait le plus, et qui est bien traité : collecte-current.sh continue de publier ev_ops_collecte_* à l'identique. Le supprimer aurait cassé l'alerte « collecte arrêtée » du #42, le panneau de fraîcheur du #197 et mon contrôle de production, sans que rien ne le dise. Tu as gardé les deux jeux côte à côte et écrit pourquoi. « Trois lignes de doublon valent mieux qu'une alerte réécrite à deux jours du jury » : c'est le bon arbitrage, et il est écrit là où quelqu'un le lira.

La cadence publiée avec la métrique est la vraie idée de cette PR. Une règle pour sept tâches au lieu de sept seuils recopiés, et le seuil suit automatiquement le jour où une crontab bouge — ce qui vient d'arriver au #205.

Un seul point, et il est hors de ta PR

On passe de cinq alertes à dix, et de cinq tableaux à sept. Le README de la pile est à jour, bien vu. Deux endroits ne le sont pas :

  • docs/EXIGENCES-collectives.md, ENF-08 : « Cinq alertes ayant seuil, destinataire et action ». Dix ne viole pas une exigence qui pose un plancher, mais un jury qui compare comptera ;
  • le pack de liens envoyé au formateur ce matin annonce « Grafana, cinq tableaux ».

Rien qui bloque cette PR. Je m'occupe des deux, le second est de mon fait.

Ce que je n'ai pas pu vérifier

Les dix règles ne sont valides qu'à l'analyse syntaxique. Leur comportement réel ne se verra qu'après déploiement, quand Grafana les aura chargées et évaluées. Si le provisioning refuse une règle, c'est Grafana entier qui ne démarre pas — donc premier contrôle à faire après la mise en prod, avant tout le reste.

Bon pour moi. Je fusionne.

Relu en vérifiant, pas en croyant. Dix-sept fichiers dont **les sept lanceurs cron** : c'est l'endroit où une erreur arrête toute la chaîne en silence, donc c'est par là que j'ai commencé. ### Ce que j'ai contrôlé | Point | Résultat | |---|---| | `RACINE` défini avant le `.` du fichier commun, dans les sept | oui, du 12/41 au 26/140 selon le lanceur | | Code de sortie préservé sur les deux chemins de `gold-daily` | oui, le 75 du verrou est publié tel quel et ne rafraîchit pas la réussite | | Les sept cadences déclarées contre les vraies crontabs | **exactes toutes les sept** : 60 / 60 / 900 / 900 / 900 / 3600 / 3600 | | Les deux tableaux de bord JSON | valides, 16 et 13 panneaux | | `rules.yaml`, `prometheus.yml`, `blackbox.yml`, `docker-compose.yml` | tous valides à l'analyse | | `tests/ci/test-supervision.sh` | passe, garde de l'`exec` comprise | **Le point qui m'inquiétait le plus, et qui est bien traité** : `collecte-current.sh` continue de publier `ev_ops_collecte_*` à l'identique. Le supprimer aurait cassé l'alerte « collecte arrêtée » du #42, le panneau de fraîcheur du #197 et mon contrôle de production, sans que rien ne le dise. Tu as gardé les deux jeux côte à côte et écrit pourquoi. « Trois lignes de doublon valent mieux qu'une alerte réécrite à deux jours du jury » : c'est le bon arbitrage, et il est écrit là où quelqu'un le lira. La cadence publiée avec la métrique est la vraie idée de cette PR. Une règle pour sept tâches au lieu de sept seuils recopiés, et le seuil suit automatiquement le jour où une crontab bouge — ce qui vient d'arriver au #205. ### Un seul point, et il est hors de ta PR **On passe de cinq alertes à dix, et de cinq tableaux à sept.** Le README de la pile est à jour, bien vu. Deux endroits ne le sont pas : - `docs/EXIGENCES-collectives.md`, ENF-08 : « **Cinq** alertes ayant seuil, destinataire et action ». Dix ne viole pas une exigence qui pose un plancher, mais un jury qui compare comptera ; - le pack de liens envoyé au formateur ce matin annonce « Grafana, **cinq** tableaux ». Rien qui bloque cette PR. Je m'occupe des deux, le second est de mon fait. ### Ce que je n'ai pas pu vérifier Les dix règles ne sont valides qu'à l'analyse syntaxique. Leur comportement réel ne se verra qu'après déploiement, quand Grafana les aura chargées et évaluées. Si le provisioning refuse une règle, c'est Grafana entier qui ne démarre pas — donc premier contrôle à faire après la mise en prod, avant tout le reste. Bon pour moi. Je fusionne.
lenaic merged commit e76f346f04 into develop 2026-09-09 08:46:48 +00:00
lenaic deleted branch gabriel/228-angles-morts-supervision 2026-09-09 08:46:48 +00:00
Sign in to join this conversation.
No reviewers
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision!231
No description provided.