Ancienneté moyenne des tickets : l'indicateur que personne ne mesure dans GLPI

L'ancienneté moyenne des tickets révèle le backlog oublié que le temps moyen de résolution ne voit pas. Découvrez d'où vient le chiffre dans GLPI, pourquoi la moyenne induit en erreur, comment séparer ancienneté et stagnation en SQL et comment automatiser la revue hebdomadaire du backlog.

Le temps moyen de résolution mesure qui a déjà quitté la file. L'ancienneté moyenne des tickets mesure qui y est encore - et c'est là que se cache le backlog oublié. Ce guide montre d'où vient le chiffre dans GLPI, pourquoi la moyenne seule induit en erreur, comment séparer ancienneté et stagnation, et comment en faire une revue de backlog hebdomadaire dans les environnements que nous maintenons.

Ce que mesure l'ancienneté moyenne - et ce qu'elle cache

L'ancienneté moyenne des tickets est la moyenne de jours entre l'ouverture et aujourd'hui, en ne comptant que les tickets encore ouverts. Contrairement au TMR, qui ne voit que ce qui est déjà résolu, elle photographie l'état actuel de la file. Le hic, c'est que la moyenne, seule, résume mal une vraie file : un backlog typique est bimodal - des dizaines de tickets tout neufs de quelques heures côtoient une traîne de tickets bloqués depuis des semaines. La masse de tickets neufs tire la moyenne vers le bas et cache justement les anciens, ceux que vous devez trouver. C'est pourquoi la moyenne ne voyage jamais seule : elle vient avec une distribution et une médiane.

D'où vient le chiffre dans GLPI

Tout vit dans la table glpi_tickets. L'ancienneté utilise la colonne date (date d'ouverture) ; le filtre "ouvert" utilise status. Les états qui comptent :

  • 1 - Nouveau (pas encore trié)
  • 2 - En cours (attribué)
  • 3 - En cours (planifié)
  • 4 - En attente (dépend d'un tiers)
  • 5 - Résolu et 6 - Clos (hors backlog)

L'erreur la plus fréquente ici est de mettre tout ce qui n'est ni 5 ni 6 dans le même panier. Les tickets en En attente (statut 4) sont légitimement arrêtés en attendant un fournisseur, le client ou une pièce - ils gonflent l'ancienneté moyenne sans que personne n'ait rien oublié. Segmenter par statut est le premier filtre honnête :

-- Ancienneté moyenne par statut (segmenter : "En attente" gonfle la moyenne)
SELECT
  status,
  ROUND(AVG(DATEDIFF(NOW(), date)), 1) AS jours_anciennete_moy,
  COUNT(*)                             AS total
FROM glpi_tickets
WHERE status NOT IN (5, 6)   -- hors Résolu et Clos
  AND is_deleted = 0
GROUP BY status
ORDER BY jours_anciennete_moy DESC;
-- statut : 1 Nouveau, 2 attribué, 3 planifié, 4 En attente

L'ancienneté n'est pas la stagnation

Un ticket ouvert il y a 40 jours mais avec une tâche saisie hier est très différent d'un ticket ouvert il y a 40 jours que personne n'a touché. L'ancienneté (depuis l'ouverture) mesure l'âge ; la stagnation (depuis la dernière action humaine) mesure l'abandon - et c'est la stagnation qui désigne le ticket oublié.

En maintenance, l'erreur que nous avons vue coûter cher est d'utiliser date_mod comme "dernière action". La colonne date_mod du ticket est mise à jour par n'importe quoi : une notification envoyée, un observateur ajouté, le cron de SLA recalculant une échéance, une règle métier qui se déclenche. Autrement dit, elle donne l'illusion du mouvement sur des tickets que personne n'a réellement traités. La vraie dernière action humaine vit dans le suivi et la tâche - glpi_itilfollowups et glpi_tickettasks. Quand nous avons remplacé date_mod par la date maximale de ces deux tables, la liste des tickets en stagnation d'un client est passée de 3 à 17 : les 14 autres semblaient vivants uniquement parce qu'une automatisation les effleurait chaque jour.

-- Stagnation réelle : jours depuis la dernière interaction humaine
-- date_mod n'est pas fiable (notifications, observateurs et cron la modifient)
SELECT
  t.id,
  t.name,
  DATEDIFF(NOW(), t.date) AS jours_anciennete,
  DATEDIFF(NOW(), GREATEST(
      t.date,
      COALESCE(MAX(f.date), t.date),
      COALESCE(MAX(k.date), t.date)
  ))                       AS jours_inactif
FROM glpi_tickets t
LEFT JOIN glpi_itilfollowups f
       ON f.itemtype = 'Ticket' AND f.items_id = t.id
LEFT JOIN glpi_tickettasks k
       ON k.tickets_id = t.id
WHERE t.status NOT IN (4, 5, 6)   -- hors En attente, Résolu, Clos
  AND t.is_deleted = 0
GROUP BY t.id, t.name, t.date
HAVING jours_inactif >= 7
ORDER BY jours_inactif DESC;

La distribution, pas seulement la moyenne

Avant de réagir à une moyenne qui a grimpé, regardez la forme de la file. La requête ci-dessous découpe le backlog en tranches d'ancienneté et révèle la longue traîne que la moyenne aplatit :

-- Répartition du backlog par tranche d'ancienneté
SELECT
  CASE
    WHEN DATEDIFF(NOW(), date) <= 3  THEN '0-3 jours'
    WHEN DATEDIFF(NOW(), date) <= 7  THEN '3-7 jours'
    WHEN DATEDIFF(NOW(), date) <= 15 THEN '7-15 jours'
    WHEN DATEDIFF(NOW(), date) <= 30 THEN '15-30 jours'
    ELSE '30+ jours'
  END        AS tranche,
  COUNT(*)   AS tickets
FROM glpi_tickets
WHERE status NOT IN (4, 5, 6)
  AND is_deleted = 0
GROUP BY tranche
ORDER BY MIN(DATEDIFF(NOW(), date));

Comme plage de référence honnête (jours calendaires, pas jours ouvrés) : sous 3 jours c'est sain, de 3 à 7 jours c'est acceptable, de 7 à 15 jours cela lève une alerte et au-delà de 15 jours cela demande une revue ticket par ticket. Ce ne sont pas des objectifs universels - le bon chiffre dépend du contrat et du type d'exploitation.

Du chiffre à l'action : matrice de décision

Une ancienneté élevée n'est pas un problème ; c'est un symptôme aux causes multiples. Ce qui le règle, c'est lire le signal technique et classer avant d'agir :

Signal techniqueClassificationAction
statut 1 (Nouveau) et ancienneté > 3 joursNon triéAttribuer un responsable/groupe maintenant
jours_inactif élevé, sans observateur externeOubliéRéattribuer et relancer
statut 4 (En attente) avec retour échuBlocage expiréRelancer le tiers ou rouvrir
ancienneté élevée et jours_inactif faibleLégitime (complexe)Revoir SLA / périmètre
ancienneté élevée et catégorie récurrenteCandidat problèmeOuvrir un Problème / article de KB

Un cas silencieux à souligner : des tickets coincés en Nouveau parce que la règle métier d'attribution n'a pas correspondu à la catégorie et n'a jamais posé de groupe. Ils vieillissent invisibles - ils disparaissent des tableaux de bord par groupe et n'apparaissent que lorsque vous regardez l'ancienneté moyenne sans filtre de groupe.

Automatiser la revue hebdomadaire

Lancer la requête à la main ne passe pas à l'échelle. Nous enregistrons la requête de stagnation dans un fichier .sql et la planifions dans le cron du système, en lisant les identifiants depuis un fichier .cnf (chmod 600) pour ne jamais laisser de mot de passe en ligne de commande. Le résultat est un CSV hebdomadaire qui devient l'ordre du jour de la revue de backlog :

# /etc/cron.d/glpi-idade  ->  chaque lundi 07:30, en www-data
# Génère la liste des tickets en stagnation (7+ jours) pour la revue du backlog
30 7 * * 1 www-data /usr/bin/mysql --defaults-file=/etc/glpi/kpi-ro.cnf glpi \
  < /opt/glpi-kpi/estagnados.sql \
  > /var/log/glpi-kpi/estagnados-$(date +\%Y-\%m-\%d).csv 2>&1

Erreurs de terrain courantes

  • Ne regarder que la moyenne : elle aplatit la traîne. Suivez toujours la distribution et, si possible, la médiane.
  • Mélanger En attente dans le panier : le statut 4 est une attente légitime ; à lui seul il relève la moyenne et crée une fausse alerte.
  • Utiliser date_mod comme dernière action : les automatisations la mettent à jour. Utilisez les dates de suivi et de tâche.
  • Comparer des entités aux calendriers différents : DATEDIFF compte les jours calendaires ; des entités aux horaires différents ne sont pas comparables une à une.
  • Oublier is_deleted = 0 : la corbeille de GLPI ne quitte pas la table et contamine toute moyenne.

Prochaine étape

Combinez l'ancienneté moyenne avec le reste de vos KPI de Service Desk et mettez le tout sur un tableau de bord dans Metabase ou Grafana avec des filtres par entité et par groupe. Ainsi l'ancienneté cesse d'être un chiffre en fin de mois et devient une alerte qui se déclenche tant qu'il est encore temps d'agir.

Chez NexTool, l'ancienneté et la stagnation du backlog entrent dans le rapport mensuel de maintenance que nous livrons aux clients, avec la liste des tickets à récupérer. Si vous voulez ce suivi sur votre GLPI, découvrez notre service de support et de maintien en conditions opérationnelles.


Ce contenu a été produit avec l'aide de l'intelligence artificielle et révisé par l'équipe Nextool Solutions.

Questions fréquentes

C'est la moyenne de jours entre la date d'ouverture (la colonne date) et aujourd'hui, en ne comptant que les tickets ouverts (statut autre que 5 Résolu et 6 Clos). Elle photographie l'état actuel de la file, contrairement au temps moyen de résolution qui ne mesure que les tickets déjà clos.

Parce que le backlog est souvent bimodal : beaucoup de tickets neufs côtoient une traîne d'anciens. La masse de neufs tire la moyenne vers le bas et cache les quelques-uns bloqués depuis des semaines. C'est pourquoi il lui faut la distribution par tranche et, si possible, la médiane.

L'ancienneté est le temps depuis l'ouverture ; la stagnation est le temps depuis la dernière action humaine (un suivi ou une tâche). Un ticket ancien travaillé hier n'est pas oublié ; un ancien sans interaction l'est. La stagnation est le signal qui désigne l'abandon.

Parce que date_mod est mis à jour par les notifications, l'ajout d'observateurs, le cron de SLA et les règles métier - des mouvements automatiques qui ne sont pas du travail humain. Utilisez la date maximale dans glpi_itilfollowups et glpi_tickettasks pour savoir quand le ticket a réellement été touché par quelqu'un.

Comme plage de référence en jours calendaires : sous 3 jours c'est sain, 3 à 7 acceptable, 7 à 15 lève une alerte et au-delà de 15 cela demande une revue ticket par ticket. Ce n'est pas un objectif universel - cela dépend du contrat, du calendrier de travail et du type d'exploitation.

Pas directement. Le module Statistiques aide pour des requêtes ponctuelles, mais il ne conserve pas la série historique et ne sépare pas ancienneté et stagnation. Pour cela on utilise du SQL avec un utilisateur en lecture seule ou un tableau de bord Metabase/Grafana alimenté par ces requêtes.

Besoin d'aide ?