Journaliser les erreurs de service-tableau et du collecteur (STUD-1157) #1623

Merged
hermes-fusion merged 1 commit from hermes/stud-1157-rust-logs into main 2026-10-15 17:00:05 +02:00
Collaborator

Carte t_22cdd8c8. Aucun changement de champ d'API : /api/processus et /api/calendrier rendent exactement les mêmes corps ; le front n'a rien à faire.

Cause. Les journaux systemd des deux services Rust de _tableau/rust ne portaient que leurs lignes de démarrage. Relevé du 13/10 au soir (ticket STUD-1157) : un collecteur injoignable, un relevé trop vieux et une réponse 5xx ne laissaient rien dans journalctl -u service-tableau ni journalctl -u collecteur-processus.

Remède. Un module collecteur::erreurs — une ligne par erreur, journalctl -u <unité> | grep ERREUR- — et ses appels sur chaque chemin d'erreur :

  • ERREUR-COLLECTEUR source=collecteur url=… : le 130 injoignable ou sa réponse refusée (5xx, JSON illisible), une ligne par tentative ;
  • ERREUR-COLLECTEUR source=etat-studio url=… : la base des dates du 130 injoignable ou refusée ;
  • ERREUR-RELEVE-VIEUX age_s=… seuil_s=45 : une seule ligne par épisode de silence (le seuil du bandeau « Collecteur muet depuis N ») ; age_s=jamais si rien n'a jamais été reçu ;
  • ERREUR-5XX code=… chemin=… methode=… raison=… : 500 du service (état partagé empoisonné), 503 de GET /conso.json ;
  • ERREUR-TACHES machine=… : systemctl illisible (les deux services) ;
  • ERREUR-CONSO raison=… : journaux de Claude Code du conteneur introuvables, une ligne par épisode ;
  • ERREUR-ECOUTE adresse=… : écoute refusée au démarrage (remplace un eprintln! sans heure) ;
  • ERREUR-HISTORIQUE fichier=… : écriture de la tendance de la semaine refusée.

Format aligné sur le serveur Python du même ticket : <ISO 8601 UTC> ERREUR-<TAG> cle=valeur, aplati sur une ligne (un saut de ligne devient |), borné à 400 caractères, sans secret (jamais un corps de requête, jamais un en-tête).

Preuves.

  • cargo test --release --locked : 47 cas, 0 échec, 9 nouveaux — la forme des lignes (collecteur/tests/erreurs.rs) et les vrais binaires lancés avec l'environnement de la panne (service/tests/journal_erreurs.rs, collecteur/tests/journal_erreurs.rs : collecteur injoignable, réponse 500 en face, relevé qui vieillit jusqu'à 45 s, systemctl absent, écoute refusée, et le silence d'un relevé sain).
  • cargo build --release --locked : propre, aucun avertissement.
  • python3 _tableau/garde_fous.py : « rien à redire » ; python3 _tableau/test_deployer_rust.py : vert.

Ce que les bancs ne couvrent pas, dit franchement : la ligne d'une réponse 5xx servie (500 sur mutex empoisonné, 503 de la première passe de consommation) n'est pas rejouée de bout en bout — sa forme est tenue par collecteur/tests/erreurs.rs, et la fenêtre du 503 ne se force pas depuis un banc. Et l'apparition des lignes dans les journaux systemd du 132 et du 130 ne sera mesurée qu'après déploiement (cargo test ne déploie rien ; je ne déploie pas).

Doc. _tableau/LXC-132.md, section « Ce que le journal dit, et comment le lire » (motifs, seuils, comment lire).

À savoir pour la fusion. _tableau/rust/service/src/main.rs est aussi touché par la carte t_b9f385fb (branche locale hermes/stud-1157-backend-erreurs, POST /api/erreurs-page), non poussée : la seconde des deux à fusionner portera un conflit, sur main.rs seulement (mon diff y ajoute des appels erreurs::…, aucun déplacement).

Hors périmètre, mesuré : _tableau/lancer-tests.py --sans-couverture sort en 1 sur _tableau/test_deploy_132.py (« 3 échec(s) ») — déjà rouge sur origin/main, à l'identique, sans rapport avec cette branche (rejoué sur un arbre détaché d'origin/main).

Fusion réservée à l'opérateur (relu puis fusion-auto) ; cette PR n'est pas fusionnée par son auteur.

Carte t_22cdd8c8. **Aucun changement de champ d'API** : `/api/processus` et `/api/calendrier` rendent exactement les mêmes corps ; le front n'a rien à faire. **Cause.** Les journaux systemd des deux services Rust de `_tableau/rust` ne portaient que leurs lignes de démarrage. Relevé du 13/10 au soir (ticket STUD-1157) : un collecteur injoignable, un relevé trop vieux et une réponse 5xx ne laissaient **rien** dans `journalctl -u service-tableau` ni `journalctl -u collecteur-processus`. **Remède.** Un module `collecteur::erreurs` — une ligne par erreur, `journalctl -u <unité> | grep ERREUR-` — et ses appels sur chaque chemin d'erreur : - `ERREUR-COLLECTEUR source=collecteur url=…` : le 130 injoignable ou sa réponse refusée (5xx, JSON illisible), **une ligne par tentative** ; - `ERREUR-COLLECTEUR source=etat-studio url=…` : la base des dates du 130 injoignable ou refusée ; - `ERREUR-RELEVE-VIEUX age_s=… seuil_s=45` : **une seule ligne par épisode** de silence (le seuil du bandeau « Collecteur muet depuis N ») ; `age_s=jamais` si rien n'a jamais été reçu ; - `ERREUR-5XX code=… chemin=… methode=… raison=…` : 500 du service (état partagé empoisonné), 503 de `GET /conso.json` ; - `ERREUR-TACHES machine=…` : `systemctl` illisible (les deux services) ; - `ERREUR-CONSO raison=…` : journaux de Claude Code du conteneur introuvables, une ligne par épisode ; - `ERREUR-ECOUTE adresse=…` : écoute refusée au démarrage (remplace un `eprintln!` sans heure) ; - `ERREUR-HISTORIQUE fichier=…` : écriture de la tendance de la semaine refusée. Format aligné sur le serveur Python du même ticket : `<ISO 8601 UTC> ERREUR-<TAG> cle=valeur`, aplati sur une ligne (un saut de ligne devient ` | `), borné à 400 caractères, **sans secret** (jamais un corps de requête, jamais un en-tête). **Preuves.** - `cargo test --release --locked` : **47 cas, 0 échec**, 9 nouveaux — la forme des lignes (`collecteur/tests/erreurs.rs`) et les **vrais binaires** lancés avec l'environnement de la panne (`service/tests/journal_erreurs.rs`, `collecteur/tests/journal_erreurs.rs` : collecteur injoignable, réponse 500 en face, relevé qui vieillit jusqu'à 45 s, `systemctl` absent, écoute refusée, et le silence d'un relevé sain). - `cargo build --release --locked` : propre, aucun avertissement. - `python3 _tableau/garde_fous.py` : « rien à redire » ; `python3 _tableau/test_deployer_rust.py` : vert. **Ce que les bancs ne couvrent pas**, dit franchement : la ligne d'une réponse 5xx **servie** (500 sur mutex empoisonné, 503 de la première passe de consommation) n'est pas rejouée de bout en bout — sa forme est tenue par `collecteur/tests/erreurs.rs`, et la fenêtre du 503 ne se force pas depuis un banc. Et l'apparition des lignes dans les journaux systemd **du 132 et du 130** ne sera mesurée qu'après déploiement (`cargo test` ne déploie rien ; je ne déploie pas). **Doc.** `_tableau/LXC-132.md`, section « Ce que le journal dit, et comment le lire » (motifs, seuils, comment lire). **À savoir pour la fusion.** `_tableau/rust/service/src/main.rs` est aussi touché par la carte t_b9f385fb (branche locale `hermes/stud-1157-backend-erreurs`, POST `/api/erreurs-page`), non poussée : la seconde des deux à fusionner portera un conflit, sur `main.rs` seulement (mon diff y ajoute des appels `erreurs::…`, aucun déplacement). **Hors périmètre, mesuré** : `_tableau/lancer-tests.py --sans-couverture` sort en 1 sur `_tableau/test_deploy_132.py` (« 3 échec(s) ») — **déjà rouge sur `origin/main`**, à l'identique, sans rapport avec cette branche (rejoué sur un arbre détaché d'`origin/main`). Fusion réservée à l'opérateur (`relu` puis `fusion-auto`) ; cette PR n'est pas fusionnée par son auteur.
Journalise les erreurs de service-tableau et du collecteur (STUD-1157)
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m14s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 12s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m8s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 11s
73ad68199e
Cause : les journaux systemd des deux services Rust (_tableau/rust) ne portaient
que leurs lignes de démarrage. Relevé le 13/10 au soir : un collecteur
injoignable, un relevé trop vieux et une réponse 5xx ne laissaient rien dans
`journalctl -u service-tableau` ni `journalctl -u collecteur-processus`, d'où la
question de l'opérateur : « il y a des logs derrière pour voir les problèmes ? ».

Remède : un module `collecteur::erreurs` (une ligne horodatée ISO 8601 UTC,
aplatie sur une seule ligne, bornée à 400 caractères, sans secret) et ses appels
sur chaque chemin d'erreur des deux binaires : collecteur injoignable ou réponse
refusée (une ligne par échec), relevé trop vieux (une ligne par épisode de
silence, `age_s=jamais` si rien n'a jamais été reçu), 5xx servi (500 du service,
503 de la consommation du collecteur), `systemctl` illisible, conteneur des
agents introuvable, écoute refusée au démarrage, historique de la semaine non
écrit. Format aligné sur le serveur Python du même ticket : `<ISO> ERREUR-<TAG> cle=valeur`.

Bancs : `cargo test --release --locked` (47 cas, 9 nouveaux — la forme des lignes,
et les deux vrais binaires lancés avec l'environnement de la panne) ;
`cargo build --release --locked` sans avertissement ; `python3 _tableau/garde_fous.py`
et `python3 _tableau/test_deployer_rust.py` verts. Doc : `_tableau/LXC-132.md`.
Collaborator

fusion-auto : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.

`fusion-auto` : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.
hermes-bot force-pushed hermes/stud-1157-rust-logs from 73ad68199e
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m14s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 12s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m8s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 11s
to 76deba8dc3
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m11s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 13s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m19s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 13s
2026-10-14 21:57:48 +02:00
Compare
hermes-bot force-pushed hermes/stud-1157-rust-logs from 76deba8dc3
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m11s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 13s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m19s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 13s
to b243cc75ef
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m11s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 13s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m12s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 14s
2026-10-14 22:14:17 +02:00
Compare
Collaborator

fusion-auto : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.

`fusion-auto` : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.
hermes-bot force-pushed hermes/stud-1157-rust-logs from b243cc75ef
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 1m11s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 13s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 1m12s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 14s
to 502a11ffe4
All checks were successful
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 2m3s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 7m31s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 1m42s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 7m26s
2026-10-15 16:46:57 +02:00
Compare
hermes-fusion deleted branch hermes/stud-1157-rust-logs 2026-10-15 17:00:05 +02:00
Collaborator

Fusionnée automatiquement par fusion-auto (forge) : CI verte, sans conflit.

Fusionnée automatiquement par `fusion-auto` (forge) : CI verte, sans conflit.
Sign in to join this conversation.
No reviewers
No milestone
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
foXaCe/studio!1623
No description provided.