13 KiB
Orchai - Design Graylog Auto-Resolve (V1)
Date: 2026-04-17 Statut: Validé en session de brainstorming
1. Objectif
Ajouter un module projet Graylog qui:
- Interroge Graylog à intervalle régulier.
- Détecte des sujets d'erreur récurrents à partir des logs récents.
- Attribue un score déterministe à chaque sujet (
sévérité + fréquence + récence). - Déclenche automatiquement le pipeline agent existant
analyst -> developerpour les sujets au-dessus d'un seuil. - Crée une branche/worktree locale de correction via le flux actuel Orchai.
Le module doit rester isolé par projet avec des credentials Graylog propres à chaque projet.
2. Décisions validées
- Exécution automatique au-dessus du seuil: oui.
- Pipeline de traitement: réutilisation stricte du pipeline existant
analyst -> developer. - Scoring: formule déterministe uniquement.
- Définition d'un sujet:
source/service + message normalisé. - Déduplication: stricte, une seule branche active par sujet.
- Portée de la configuration Graylog: par projet.
- Approche d'architecture: extension ciblée sans refonte complète du modèle Tuleap.
3. Architecture cible
3.1 Module projet
Nouveau module dans project_modules:
module_key:graylog_polling_auto_resolvename:Polling Graylog + auto-resolvedescription: surveillance Graylog, scoring, déclenchement automatique du pipeline agent.
3.2 Composants backend
graylog_client- Appelle l'API Graylog (requêtes de recherche, filtres, stream éventuel).
- Transforme les réponses en événements de logs exploitables.
graylog_scoring- Normalise les messages.
- Regroupe par sujet.
- Calcule le score déterministe.
graylog_poller- Boucle périodique (comme les services de fond existants).
- Charge la configuration de chaque projet.
- Applique dédup et seuil.
graylog_to_queue_bridge- Insère un item de traitement dans la file existante pour réutiliser l'orchestrateur.
3.3 Réutilisation du pipeline actuel
Le traitement des sujets Graylog utilise:
processed_ticketscomme file de traitement commune.services/orchestrator.rspour exécuteranalyst -> developer.services/worktree_manager.rspour créer la branche/worktree locale.
Le poller Graylog détecte et pousse en file; il ne lance pas directement de correction.
4. Modèle de données
4.1 Nouvelles tables
-
graylog_credentials(unique par projet)id TEXT PRIMARY KEYproject_id TEXT NOT NULL UNIQUE REFERENCES projects(id) ON DELETE CASCADEbase_url TEXT NOT NULLapi_token_encrypted TEXT NOT NULLanalyst_agent_id TEXT NOT NULL REFERENCES agents(id)developer_agent_id TEXT NOT NULL REFERENCES agents(id)stream_id TEXT(optionnel)query_filter TEXT NOT NULL DEFAULT ''polling_interval_minutes INTEGER NOT NULL DEFAULT 10lookback_minutes INTEGER NOT NULL DEFAULT 30score_threshold INTEGER NOT NULL DEFAULT 70created_at TEXT NOT NULLupdated_at TEXT NOT NULL
-
graylog_subjects(état courant d'un sujet)id TEXT PRIMARY KEYproject_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADEsubject_key TEXT NOT NULLsource TEXT NOT NULLnormalized_message TEXT NOT NULLfirst_seen_at TEXT NOT NULLlast_seen_at TEXT NOT NULLlast_score INTEGER NOT NULL DEFAULT 0active_ticket_id TEXT REFERENCES processed_tickets(id)status TEXT NOT NULL DEFAULT 'idle'(idle|queued|processing|done|error|cancelled)created_at TEXT NOT NULLupdated_at TEXT NOT NULL
-
graylog_detections(historique des cycles)id TEXT PRIMARY KEYsubject_id TEXT NOT NULL REFERENCES graylog_subjects(id) ON DELETE CASCADEwindow_start TEXT NOT NULLwindow_end TEXT NOT NULLcritical_count INTEGER NOT NULL DEFAULT 0error_count INTEGER NOT NULL DEFAULT 0warning_count INTEGER NOT NULL DEFAULT 0total_count INTEGER NOT NULL DEFAULT 0last_seen_at TEXT NOT NULLscore INTEGER NOT NULLtriggered INTEGER NOT NULL DEFAULT 0triggered_ticket_id TEXT REFERENCES processed_tickets(id)created_at TEXT NOT NULL
4.2 Évolution de processed_tickets
Ajouts:
project_id TEXT REFERENCES projects(id)(renseigné pour tous les tickets)source TEXT NOT NULL DEFAULT 'tuleap'source_ref TEXT(référence externe, icigraylog_subjects.id)
Évolutions:
tracker_iddevient nullable pour supporter les sources non-Tuleap.- Le code de lecture par projet ne dépend plus d'un
JOINobligatoire verswatched_trackers. - Les tickets Tuleap continuent de renseigner
tracker_id. - Les tickets Graylog renseignent
project_idet laissenttracker_idnul.
Rôle:
- Distinguer les items Tuleap et Graylog.
- Réutiliser l'orchestrateur sans dupliquer la mécanique de queue/worktree.
4.3 Index recommandés
UNIQUE(project_id, subject_key)surgraylog_subjects.INDEX(subject_id, created_at DESC)surgraylog_detections.INDEX(source, source_ref)surprocessed_tickets.INDEX(project_id, detected_at DESC)surprocessed_tickets.- Index unique Tuleap conservé en version partielle:
UNIQUE(tracker_id, artifact_id) WHERE tracker_id IS NOT NULL.
4.4 Migration des données existantes
Ordre de migration recommandé:
- Ajouter
project_id,source,source_refsurprocessed_tickets. - Backfill
project_idpour les lignes existantes viaJOIN watched_trackers. - Rendre
tracker_idnullable. - Remplacer l'index unique historique
(tracker_id, artifact_id)par l'index partiel Tuleap. - Ajouter les nouvelles tables Graylog.
5. Définition d'un sujet et normalisation
5.1 Clé de regroupement
subject_key = source + '|' + normalized_message
source correspond au champ service applicatif si présent, sinon au champ source Graylog.
5.2 Normalisation V1
Transformation déterministe:
- Passage en minuscules.
- Remplacement des UUID par
<uuid>. - Remplacement des nombres longs/identifiants numériques par
<num>. - Remplacement des timestamps ISO par
<ts>. - Remplacement des adresses IP par
<ip>. - Remplacement des hash hexadécimaux longs par
<hash>. - Réduction des espaces multiples.
Objectif: regrouper des occurrences logiquement identiques malgré des valeurs dynamiques.
6. Scoring déterministe
Score total entre 0 et 100:
score_total = severity_score + frequency_score + recency_score
6.1 Sévérité (0..50)
- Si au moins un
critical:50 - Sinon si au moins un
error:35 - Sinon si au moins un
warning:20 - Sinon:
0
6.2 Fréquence (0..35)
Barème sur total_count dans la fenêtre du cycle:
1->52-3->124-7->228-15->30>=16->35
6.3 Récence (0..15)
Barème sur l'âge du dernier événement du sujet:
<=2 min->15<=10 min->12<=30 min->8<=120 min->4>120 min->0
6.4 Seuil
score_threshold est porté par projet dans graylog_credentials.
Valeur par défaut V1: 70.
7. Flux d'exécution
7.1 Cycle planifié
- Le scheduler Graylog se déclenche toutes les 60 secondes.
- Pour chaque projet:
- vérifier module
graylog_polling_auto_resolveactivé; - charger credentials + config;
- vérifier si
polling_interval_minutesest atteint; - interroger Graylog sur la fenêtre
lookback_minutes.
- vérifier module
- Regrouper les logs en sujets.
- Calculer score par sujet.
- Persister détections et état des sujets.
- Décider du déclenchement.
7.2 Règle de déclenchement
- Si
score < threshold:triggered = 0dansgraylog_detections.- aucun item queue créé.
- Si
score >= threshold:- si sujet sans traitement actif: créer un item
processed_ticketsde sourcegraylog. - sinon: ne rien créer (dédup stricte), garder la trace en détection.
- si sujet sans traitement actif: créer un item
7.3 Dédup stricte
Un sujet est considéré actif si:
graylog_subjects.active_ticket_idnon nul, et- le ticket lié est dans
Pending|Analyzing|Developing.
Conséquence:
- une seule branche active par sujet.
- pas de duplication de branche tant que le ticket actif n'est pas terminé.
7.4 Nommage de branche
Format recommandé:
orchai/graylog/<subject_hash>
subject_hash est dérivé de subject_key pour conserver un nom stable et compact.
8. Intégration orchestrateur/worktree
8.1 Représentation queue Graylog
Lors du trigger:
- créer un
processed_ticketsavec:project_id = <project_id>tracker_id = NULLsource = 'graylog'source_ref = graylog_subjects.idartifact_id: identifiant synthétique négatif (dérivé de hash de sujet, avec fallback anti-collision) pour compatibilité UI.artifact_title: résumé court ([Graylog] <source> - <message normalisé>).artifact_data: JSON détaillant métriques et exemples de logs.
- mettre
graylog_subjects.status = 'queued'etactive_ticket_id = <ticket_id>.
8.2 Transition de statut sujet
Synchroniser graylog_subjects.status avec le ticket lié:
Pending->queuedAnalyzing->processingDeveloping->processingDone->donepuisidleau cycle suivant si pas de nouveau dépassementError->errorCancelled->cancelled
8.3 Sélection des agents Graylog
Pour un ticket source='graylog', l'orchestrateur charge les agents depuis graylog_credentials du projet:
analyst_agent_idpour l'étape d'analyse.developer_agent_idpour l'étape de correction.
Comportement en cas de configuration invalide:
- le ticket passe en erreur explicite;
- l'événement d'erreur est émis;
- aucun worktree n'est créé.
9. Contrats Tauri (backend)
9.1 Credentials/config
set_graylog_credentials(project_id, base_url, api_token, analyst_agent_id, developer_agent_id, stream_id, query_filter, polling_interval_minutes, lookback_minutes, score_threshold)get_graylog_credentials(project_id)test_graylog_connection(project_id)delete_graylog_credentials(project_id)- Les commandes de configuration incluent
analyst_agent_idetdeveloper_agent_id.
9.2 Pilotage et visibilité
manual_graylog_poll(project_id)list_graylog_subjects(project_id)list_graylog_detections(project_id, subject_id?)
10. Événements frontend
Événements Tauri ajoutés:
graylog-polling-startedgraylog-subject-triggeredgraylog-polling-finishedgraylog-polling-error
Ces événements sont complémentaires des événements existants du pipeline ticket.
11. UI
11.1 Modules projet
Dans ProjectModules, afficher le module Graylog avec activation/désactivation.
11.2 Vue Graylog projet
Nouvelle page projet dédiée:
- Formulaire de configuration (
URL,token,stream,query, intervalle, lookback, seuil). - Bouton
Tester la connexion. - Liste des sujets:
- source
- message normalisé
- score actuel
- dernière occurrence
- statut
- ticket/branche liés s'ils existent
- Historique des détections par sujet.
11.3 Dashboard
Le dashboard projet affiche les événements Graylog récents au même titre que les événements de polling et d'orchestration actuels.
12. Gestion d'erreurs et robustesse
- Erreur API Graylog:
- journaliser côté backend,
- émettre
graylog-polling-error, - reprendre au cycle suivant sans bloquer le reste.
- Credentials absents/invalides:
- projet ignoré pour le cycle,
- statut explicite côté UI.
- Aucune erreur Graylog ne doit arrêter:
- le poller Tuleap,
- l'orchestrateur,
- le task runner.
13. Tests
13.1 Unit tests
- Normalisation de message.
- Calcul de score (cas limites inclus).
- Dédup stricte (pas de second ticket si sujet actif).
13.2 Intégration DB
- Migration vers le nouveau schéma.
- Création d'un ticket
source='graylog'. - Cohérence de
active_ticket_idet des transitions de statut sujet.
13.3 Services
- Poll sous seuil -> pas de trigger.
- Poll au-dessus seuil -> trigger unique.
- Poll répété au-dessus seuil avec sujet actif -> pas de nouveau trigger.
13.4 UI
- Toggle module Graylog.
- Sauvegarde config + test connexion.
- Affichage des sujets et statut lié au ticket.
14. Critères d'acceptation
- Un sujet Graylog au-dessus du seuil crée automatiquement un traitement complet
analyst -> developer. - Les sujets sont regroupés par
source + message normalisé. - Tant qu'un sujet est actif, aucune branche supplémentaire n'est créée pour ce sujet.
- Les décisions (trigger/dédup) sont auditables via l'historique des détections.
- Désactiver le module Graylog coupe les nouveaux déclenchements sans perdre l'historique.
15. Plan de rollout
- Livrer backend (migrations, services, commandes).
- Livrer UI (module + écran Graylog + événements).
- Activer sur un projet pilote.
- Ajuster seuil et barèmes de scoring si nécessaire.
- Généraliser projet par projet.