InfraGuard

Résolution des problèmes (cas d’incident)

Un flux de travail de cas d’incident qui suit les pannes et les erreurs de l’enregistrement à la clôture — enregistrement -> en investigation -> cause identifiée -> résolu -> clos — en consignant la cause directe et la cause profonde, la remise en service et l’action préventive.

Vue d’ensemble — à quoi sert cet écran

Résolution des problèmes est le flux de travail de cas d’incident du domaine de rôle Service. Enregistrez toute panne, erreur ou dégradation sous la forme d’un cas unique et faites-le progresser le long de la chaîne d’états enregistrement → en investigation → cause identifiée → résolu → clos, en consignant l’investigation, la cause et l’action à chaque étape. L’écran fait aussi office de registre de post-mortems et d’actions préventives.

Toutes les données résident dans une seule table, infr_incident, et cet écran ne traite que les lignes portant area='service'. L’écran Résolution des problèmes de sécurité partage la même table avec area='security' — schéma identique, tableau distinct.

Chaque cas comporte quatre champs de cause/action calqués sur un rapport post-mortem formel :

Champ Signification Exemple
direct_cause Le déclencheur apparent de la panne limite de connexions mysql dépassée (Too many connections)
root_cause La raison sous-jacente qui a produit la cause apparente un script cron de 5 minutes ne rendait jamais les connexions → fuite → limite épuisée
resolution Action qui a rétabli le service pendant l’incident connexions purgées, processus redémarré, limite relevée pour une reprise immédiate
action_taken Correctif permanent pour éviter la récidive compte dédié isolé avec MAX_USER_CONNECTIONS, script corrigé, alerte de supervision ajoutée

Cet écran a été renommé à partir de l’ancien menu « SLA & Uptime » (espace de noms sla → resolution). L’indicateur d’objectif de disponibilité (uptime_target) est conservé.


Quand l’utiliser


Disposition

Bandeau d’indicateurs

Les indicateurs du haut sont calculés sur l’ensemble des cas area='service'.

Indicateur Mode de calcul
Total (total) Nombre de cas de service
Actifs (active) Somme de open + investigating + cause_identified
Résolus (resolved) Somme de resolved + closed
MTTR (mttr_min) Moyenne de (résolution − survenue) en minutes, uniquement pour les cas disposant À LA FOIS de occurred_at et de resolved_at
Indisponibilité cumulée (downtime_min) Simple somme du champ downtime_min de chaque cas (en minutes)
Objectif de disponibilité (uptime_target) sla_uptime_target de la Politique d’exploitation (99.9% par défaut)

Pour obtenir un MTTR exact, saisissez une heure de survenue (occurred_at) sur le cas et laissez la transition vers Résolu horodater resolved_at automatiquement. Un cas sans heure de survenue est exclu de la moyenne du MTTR.

Tableau des cas

Les cas sont listés sous forme de cartes/lignes, triés côté serveur (en PHP, afin d’éviter le SQL brut dans le contrôleur) selon cette priorité :

  1. Rang d’état : open → investigating → cause_identified → resolved → closed
  2. Rang de gravité : crit → warn → info
  3. Identifiant le plus récent en premier

Les cas actifs, graves et récents remontent donc en haut.

Chaque carte affiche le badge d’origine (manuel / Pulse / alerte / organisme / quarantaine / promu depuis une détection), la gravité, l’état, le nom du projet, l’heure de survenue, l’indisponibilité et le nombre d’événements.

Fenêtre de détail

L’ouverture d’un cas affiche le Rapport à gauche (résumé · cause directe · cause profonde · remise en service · action préventive) et la Chronologie à droite (changements d’état · notes), avec les boutons de transition de la chaîne en haut.


Mode d’emploi

1) Enregistrer un cas

[Register case] → formulaire modal. À la création, le cas est enregistré avec source='manual', area='service', status='open' ; detected_at est horodaté côté serveur (now()) et un événement created est ajouté à la chronologie.

Champs et limites de validation :

Champ Obligatoire Limite
title ✔ 200 caractères max.
severity info/warn/crit — vide, la valeur par défaut est warn (Politique d’exploitation incident_default_severity)
project_id doit exister dans infr_project
service_id doit exister dans infr_service
url 255 caractères max.
occurred_at date
summary 4000 caractères max.
direct_cause / root_cause / resolution / action_taken 4000 caractères max. chacun
downtime_min entier, ≥ 0
impact 191 caractères max.

2) Transition d’état (chaîne)

Dans la fenêtre de détail, cliquer sur un bouton d’étape suivante ouvre une boîte de dialogue de transition d’étape. Chaque étape explique « ce qu’il faut faire à cette étape » et vous laisse renseigner les champs du rapport pertinents pour cette étape. Seuls les champs que vous envoyez sont mis à jour, ce qui vous permet d’enrichir les causes sans changer d’état, ou d’étoffer uniquement le rapport.

Étape Code Ce qu’il faut faire à cette étape
Enregistrement open Renvoyer le cas en file d’admission (avant investigation)
En investigation investigating Confirmer les symptômes, délimiter l’impact, rédiger le résumé
Cause identifiée cause_identified Déterminer et consigner la cause directe et sa cause profonde (de fond)
Résolu resolved Consigner la méthode de reprise appliquée et l’action préventive
Clos closed Vérifier que le correctif et la prévention sont en place, puis clore le cas

Règles de transition :

Les dates sont rendues via toLocaleString lié à la langue active de l’interface (window.__locale), de sorte que le mois et l’heure s’affichent correctement même en mode EN.

3) Notes de collaboration

Ajouter une note dans la fenêtre de détail ajoute un événement kind='note' à la chronologie (les notes sont regroupées dans infr_incident_event — il n’existe pas de table de notes distincte). Corps de 4000 caractères max.

4) Suppression

Supprimer un cas supprime l’incident et toutes ses lignes infr_incident_event associées d’un seul tenant. Cette opération est irréversible.

5) Admission automatique (Pulse / rapporteur d’exceptions)

Lorsqu’une application Laravel externe pousse ses exceptions vers l’API d’ingestion d’incidents (POST /api/v1/incidents), IncidentIngestService les traite et les inscrit automatiquement sur ce tableau :

Les clés et le code d’intégration se gèrent dans Administration ▸ Clés API.


Sources de données

Table Rôle
infr_incident Le cas lui-même. Cet écran n’interroge que area='service'. Migration 000719 (+ 000723 champs d’ingestion · 000731 area · 000732 extension de source)
infr_incident_event Chronologie (en ajout seul). kind = created/note/action/status_change/cause/resolution/alert_added. N’utilise que created_at (migration 000720)
infr_project Liste déroulante des projets · nom du projet sur la carte
infr_service Liste déroulante des services
infr_audit_log Piste d’audit pour la création/modification/transition/suppression

Colonnes clés de infr_incident : source, area, title, severity, status, project_id, service_id, url, occurred_at, detected_at, resolved_at, closed_at, summary, direct_cause, root_cause, resolution, action_taken, downtime_min, impact, fingerprint, occurrence_count, last_occurred_at, api_key_id, created_by, updated_by.

Les valeurs par défaut proviennent de la Politique d’exploitation OpsPolicy::slaDefaults() :

sla_uptime_target         = 99.9   # disponibilité cible du SLA (%)
incident_default_severity = warn   # gravité par défaut à l’enregistrement (info|warn|crit)

Routes :

GET  /service/resolution              index (tableau)
GET  /service/resolution/live         live  (rafraîchissement par sondage JSON)
POST /service/resolution/save         enregistrer / mettre à jour un cas
POST /service/resolution/transition   transition d’état (+ rapport par étape / closed_at)
POST /service/resolution/note         ajouter une note de collaboration
POST /service/resolution/delete       supprimer un cas

Accès

Action Niveau requis
Consulter le tableau (index/live) Utilisateur authentifié (infr.auth, niveau ≥ 1)
Enregistrer / modifier / faire transiter / annoter / supprimer niveau ≥ 2

Chaque écriture (enregistrement/modification/transition/suppression) est consignée dans infr_audit_log sous incident.create / incident.update / incident.transition / incident.delete, avec l’auteur et l’état avant/après. Voir Niveaux RBAC pour le modèle de niveaux.


Dépannage et FAQ

Q. Le MTTR est vide / sans valeur. Un cas doit posséder À LA FOIS une heure de survenue (occurred_at) et une heure de résolution (resolved_at) pour être inclus dans la moyenne du MTTR. Vérifiez que vous avez saisi l’heure de survenue et que la transition vers Résolu a bien horodaté resolved_at.

Q. L’indisponibilité cumulée affiche 0. L’indicateur d’indisponibilité est une simple somme du champ downtime_min de chaque cas. Vous devez saisir l’indisponibilité (en minutes) sur le cas ; elle n’est pas déduite automatiquement des heures de survenue et de résolution.

Q. Un cas Pulse n’apparaît pas. Les cas ingérés portent source='pulse' et laissent area non défini ; ils prennent donc la valeur par défaut service et apparaissent ici. S’il en manque toujours un, vérifiez (1) si la clé API est valide et (2) si la même empreinte a été dédupliquée dans un cas déjà ouvert (seul occurrence_count a été incrémenté). Les incidents de sécurité apparaissent dans Résolution des problèmes de sécurité (area='security'), et non sur ce tableau.

Q. Puis-je fixer l’heure de clôture dans le passé ? Oui. Saisissez l’heure souhaitée dans le champ d’heure de clôture (flatpickr) de la boîte de dialogue de transition closed : cette valeur sera enregistrée. Laissez-le vide pour utiliser l’heure courante du serveur (now()).

Q. Je veux enrichir les causes sans changer d’état. La boîte de dialogue de transition ne met à jour que les champs que vous envoyez. Effectuer une transition vers le même état tout en renseignant les champs du rapport met à jour le rapport sans événement de changement d’état (ou modifiez le cas directement).

Q. Un cas supprimé peut-il être restauré ? Non. La suppression retire le cas et tous ses événements de chronologie, et elle est irréversible. L’action de suppression elle-même est consignée dans le journal d’audit.


Voir aussi

문제 해결 — 인시던트 보드
문제 해결 — 인시던트 보드