Un bon indicateur est celui dont vous pouvez désigner l'origine dans la base. Ce guide montre quels KPI de Service Desk valent vraiment la peine d'être suivis dans GLPI, de quelle table et colonne sort chaque chiffre, quelles fourchettes nous utilisons comme référence et les pièges qui ont déjà faussé des décisions dans les environnements que nous maintenons pour des clients.
Avant le KPI, le modèle de données
L'erreur que nous voyons le plus en reprenant un GLPI existant est de mesurer "en surface" : comparer des dates brutes au lieu d'utiliser les champs que GLPI calcule déjà. Chaque ticket dans la table glpi_tickets porte des colonnes statistiques prêtes à l'emploi, les mêmes que consomme le module Statistiques :
takeintoaccount_delay_stat- secondes jusqu'à la première prise en compte (base du temps de réponse / TTO).solve_delay_stat- secondes jusqu'à la résolution, déjà déduites du temps en "En attente" et ajustées par le calendrier de travail de l'entité (base du TMR / TTR).waiting_duration- total des secondes passées en attente.time_to_resolveettime_to_own- les échéances (deadlines) du SLA de résolution et de prise en compte.status- l'état du ticket, qui décide de ce qui entre ou non dans le backlog.
Cela change tout : le TMR calculé comme solvedate - date diffère (et est toujours plus élevé) de ce que renvoie solve_delay_stat, car la soustraction brute additionne les nuits, les week-ends et les pauses. Choisir la bonne colonne, c'est déjà la moitié du travail.
Les KPI qui comptent et où chacun réside
Il ne s'agit pas d'avoir dix indicateurs sur le tableau de bord ; il s'agit d'avoir ceux qui déclenchent l'action. La matrice ci-dessous relie chaque KPI à sa source technique dans GLPI et à une fourchette de référence honnête. Une fourchette, pas une cible universelle : le bon chiffre dépend du contrat et du type d'exploitation.
| KPI | Source dans GLPI | Fourchette de référence |
|---|---|---|
| Volume de tickets | COUNT(*) sur glpi_tickets (filtre par date) | dimensionne l'équipe ; pas de cible fixe |
| Temps de réponse (TTO) | takeintoaccount_delay_stat | plus c'est bas, mieux c'est ; suit le SLA |
| Temps moyen de résolution (TMR) | solve_delay_stat | comparer à son propre historique |
| Respect du SLA (TTR) | solvedate <= time_to_resolve | au-dessus de 90-95% |
| Taux de réouverture | glpi_logs (statut 5 vers 1/2/3) | en dessous de 5% |
| Satisfaction (CSAT) | glpi_ticketsatisfactions.satisfaction | au-dessus de 4,0/5,0 |
| Backlog | status NOT IN (5,6) | stable ou décroissant |
| Âge moyen du backlog | AVG(DATEDIFF(NOW(), date)) sur les ouverts | faible ; élevé = tickets oubliés |
| Résolution en N1 | groupe attribué, sans escalade | 70-80% |
Extraire les chiffres directement de la base
Le module Statistiques (dans Assistance) répond bien pour une requête ponctuelle et pour explorer par catégorie, groupe, technicien et SLA. Mais il ne versionne pas l'historique mois par mois et ne croise pas plusieurs indicateurs sur une seule ligne comparable. Quand nous avons besoin de l'instantané consolidé qui entre dans le rapport mensuel des clients, nous allons à la base avec un utilisateur en lecture seule :
-- KPI du mois en cours sur une seule ligne (utiliser un utilisateur en lecture seule)
-- Source : glpi_tickets, les mêmes champs que lit le module Statistiques
SELECT
COUNT(*) AS volume,
SUM(status NOT IN (5,6)) AS backlog,
ROUND(AVG(NULLIF(takeintoaccount_delay_stat,0))/60, 1) AS tto_min,
ROUND(AVG(NULLIF(solve_delay_stat,0))/3600, 1) AS tmr_horas,
ROUND(
100 * SUM(solvedate IS NOT NULL AND solvedate <= time_to_resolve)
/ NULLIF(SUM(time_to_resolve IS NOT NULL AND solvedate IS NOT NULL), 0)
, 1) AS sla_ttr_pct
FROM glpi_tickets
WHERE is_deleted = 0
AND date >= DATE_FORMAT(CURDATE(), '%Y-%m-01');La réouverture n'a pas de colonne propre : elle vit dans l'historique des changements d'état. Dans glpi_logs, une réouverture est le ticket qui a quitté Résolu (statut 5) et est revenu en traitement. Le journal enregistre la valeur comme "5 Résolu", nous filtrons donc par le préfixe numérique pour ne pas dépendre de la langue de l'installation :
-- Réouvertures du mois : tickets sortis de Résolu (5) et revenus
-- en traitement. Dans glpi_logs, id_search_option 12 = le champ statut
SELECT COUNT(DISTINCT items_id) AS reabertos
FROM glpi_logs
WHERE itemtype = 'Ticket'
AND id_search_option = 12
AND old_value LIKE '5 %'
AND new_value REGEXP '^[123] '
AND date_mod >= DATE_FORMAT(CURDATE(), '%Y-%m-01');Automatiser la collecte mensuelle
Lancer la requête à la main chaque 1er du mois ne passe pas à l'échelle. Nous planifions l'extraction avec le cron du système, en pointant vers un fichier d'identifiants .cnf (chmod 600) pour ne jamais laisser de mot de passe en ligne de commande, et nous stockons le CSV hors de GLPI. C'est ainsi que naît la série temporelle que le tableau de bord natif ne conserve pas :
# /etc/cron.d/glpi-kpi -> le 1er à 06:00, en tant que www-data
# Identifiants dans le fichier .cnf (chmod 600), jamais en ligne de commande
0 6 1 * * www-data /usr/bin/mysql --defaults-file=/etc/glpi/kpi-ro.cnf glpi \
< /opt/glpi-kpi/kpi_mensal.sql >> /var/log/glpi-kpi/kpi-$(date +\%Y-\%m).csv 2>&1Cibles : des fourchettes honnêtes, pas des chiffres magiques
- Respect du SLA (TTR) : au-dessus de 90-95% est sain pour la plupart des contrats. Un 100% constant indique souvent un SLA trop large, pas l'excellence.
- Réouvertures : en dessous de 5%. Au-delà, enquêtez sur une résolution incomplète ou une clôture précipitée pour "tenir" le délai.
- Résolution en N1 : 70-80%. En dessous de 60%, cela pointe un manque de formation ou une mauvaise catégorisation ; bien au-dessus de 90%, suspectez des tickets complexes mal classés.
- Satisfaction (CSAT) : au-dessus de 4,0/5,0, mais toujours lue avec le taux de réponse à l'enquête.
Des pièges qui ont déjà provoqué des astreintes
Dans la maintenance d'environnements clients, la première chose que nous faisons en reprenant un GLPI déjà en service est de ne pas faire confiance au tableau de bord natif tant que la base n'est pas validée. Chez un client à fort volume mensuel de tickets, le TMR "officiel" semblait excellent jusqu'à ce que nous remarquions qu'une grande part des tickets avait le même utilisateur comme demandeur et technicien dès l'ouverture : une auto-attribution qui met à zéro takeintoaccount_delay_stat et masque le temps de réponse réel. Nous avons standardisé l'extraction via SQL planifié précisément parce que le module Statistiques ne conserve pas d'historique mois par mois ; sans série temporelle, vous comparez à la mémoire, pas à la donnée.
Les pièges de terrain qui faussent le plus la lecture :
- Mesurer le TMR par différence de dates.
solvedate - dategonfle le chiffre : nuits, week-ends et temps en "En attente" s'y glissent. Utilisezsolve_delay_stat, que GLPI ajuste déjà par le calendrier. - Confondre Résolu et Clos. S'il y a une clôture automatique après X jours, ne mesurer que
status = 6cache les résolus en attente de confirmation. Le backlog doit exclure 5 et 6. - Célébrer un TTO bas dû à l'auto-attribution. Un ticket ouvert déjà attribué met à zéro le temps de réponse ; le chiffre baisse sans que l'exploitation se soit améliorée.
- Lire la satisfaction sans le taux de réponse. Quand seuls les insatisfaits répondent, la moyenne trompe. Croisez
satisfactionavec le nombre d'enquêtes réellement répondues.
Si votre GLPI affiche des chiffres auxquels personne ne se fie, le problème est rarement GLPI : c'est la base et la façon d'extraire. La maintenance GLPI de NexTool inclut la modélisation de ces indicateurs et le rapport mensuel consolidé que la direction lit sans tableur.
Ce contenu a été produit avec l'aide de l'intelligence artificielle et révisé par l'équipe Nextool Solutions.