Хороший показатель — тот, источник которого вы можете указать в базе данных. В этом руководстве показано, какие KPI службы поддержки (Service Desk) действительно стоит отслеживать в GLPI, из какой таблицы и столбца берётся каждое число, какие диапазоны мы используем как ориентир и какие ловушки уже искажали решения в средах, которые мы сопровождаем для клиентов.
Прежде KPI — модель данных
Ошибка, которую мы чаще всего видим, принимая существующий GLPI, — измерять «поверх»: сравнивать сырые даты вместо того, чтобы использовать поля, которые GLPI уже вычисляет сам. Каждая заявка в таблице glpi_tickets содержит готовые статистические столбцы — те же, что использует модуль Статистики:
takeintoaccount_delay_stat— секунды до первого принятия в работу (основа времени реакции / TTO).solve_delay_stat— секунды до решения, уже за вычетом времени в статусе «В ожидании» и с учётом рабочего календаря организации (основа среднего времени решения / TTR).waiting_duration— общее число секунд, которые заявка провела в ожидании.time_to_resolveиtime_to_own— сроки (deadlines) SLA на решение и на принятие в работу.status— состояние заявки, определяющее, входит ли она в бэклог.
Это меняет всё: среднее время решения, вычисленное как solvedate - date, отличается от значения из solve_delay_stat (и всегда больше), потому что простое вычитание учитывает ночи, выходные и паузы. Выбрать правильный столбец — уже половина работы.
Важные KPI и где хранится каждый
Дело не в том, чтобы иметь десять показателей на панели, а в том, чтобы иметь те, что ведут к действию. Матрица ниже связывает каждый KPI с его техническим источником в GLPI и честным ориентиром. Ориентиром, а не универсальной целью: справедливое значение зависит от договора и типа работы.
| KPI | Источник в GLPI | Ориентир |
|---|---|---|
| Объём заявок | COUNT(*) в glpi_tickets (фильтр по date) | определяет размер команды; без фиксированной цели |
| Время реакции (TTO) | takeintoaccount_delay_stat | чем меньше, тем лучше; следует SLA |
| Среднее время решения | solve_delay_stat | сравнивать с собственной историей |
| Соблюдение SLA (TTR) | solvedate <= time_to_resolve | выше 90–95% |
| Доля повторных открытий | glpi_logs (статус 5 в 1/2/3) | ниже 5% |
| Удовлетворённость (CSAT) | glpi_ticketsatisfactions.satisfaction | выше 4,0/5,0 |
| Бэклог | status NOT IN (5,6) | стабильный или снижающийся |
| Средний возраст бэклога | AVG(DATEDIFF(NOW(), date)) по открытым | низкий; высокий = забытые заявки |
| Решение на первой линии (L1) | назначенная группа, без эскалации | 70–80% |
Извлечение чисел прямо из базы
Модуль Статистики (в разделе Поддержка) хорошо подходит для разовых запросов и анализа по категории, группе, специалисту и SLA. Но он не хранит историю по месяцам и не сводит несколько показателей в одну сопоставимую строку. Когда нам нужна сводная картина для ежемесячного отчёта клиентам, мы обращаемся к базе через пользователя только для чтения:
-- Current-month KPIs in a single row (use a read-only user)
-- Source: glpi_tickets, the same fields the Statistics module reads
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');У повторного открытия нет собственного столбца: оно живёт в истории смены статусов. В glpi_logs повторное открытие — это заявка, которая вышла из статуса Решена (статус 5) и вернулась в работу. Лог хранит значение как «5 Решена», поэтому мы фильтруем по числовому префиксу, чтобы не зависеть от языка инсталляции:
-- Reopenings this month: tickets that left Solved (5) and went back
-- to work. In glpi_logs, id_search_option 12 = the status field
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');Автоматизация ежемесячного сбора
Запускать запрос вручную каждое 1-е число не масштабируется. Мы планируем выгрузку системным cron, указывая файл учётных данных .cnf (chmod 600), чтобы никогда не оставлять пароль в командной строке, и храним CSV вне GLPI. Так появляется временной ряд, который штатная панель не хранит:
# /etc/cron.d/glpi-kpi -> day 1 at 06:00, as www-data
# Credentials in the .cnf file (chmod 600), never on the command line
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>&1Цели: честные диапазоны, а не магические числа
- Соблюдение SLA (TTR): выше 90–95% — здоровый уровень для большинства договоров. Постоянные 100% обычно говорят о слишком мягком SLA, а не о превосходстве.
- Повторные открытия: ниже 5%. Выше — ищите неполные решения или поспешное закрытие ради «попадания» в срок.
- Решение на первой линии (L1): 70–80%. Ниже 60% — не хватает обучения или категоризация плохая; намного выше 90% — подозревайте неправильно классифицированные сложные заявки.
- Удовлетворённость (CSAT): выше 4,0/5,0, но всегда в связке с долей ответов на опрос.
Ловушки, из-за которых уже приходилось дежурить
При сопровождении клиентских сред первое, что мы делаем, принимая уже работающий GLPI, — не доверяем штатной панели, пока не проверим базу. У одного клиента с большим ежемесячным объёмом заявок «официальное» среднее время решения выглядело отлично, пока мы не заметили, что у значительной части заявок один и тот же пользователь был автором и специалистом уже при создании: самоназначение обнуляет takeintoaccount_delay_stat и маскирует реальное время реакции. Мы стандартизировали выгрузку через запланированный SQL именно потому, что модуль Статистики не хранит историю по месяцам; без временного ряда вы сравниваете с памятью, а не с данными.
Практические ловушки, которые больше всего мешают интерпретации:
- Измерять время решения разницей дат.
solvedate - dateзавышает число: в него попадают ночи, выходные и время в статусе «В ожидании». Используйтеsolve_delay_stat, который GLPI уже корректирует по календарю. - Путать Решена и Закрыта. Если есть автоматическое закрытие через X дней, измерение только
status = 6скрывает решённые заявки, ожидающие подтверждения. Бэклог должен исключать 5 и 6. - Радоваться низкому TTO от самоназначения. Заявка, созданная уже назначенной, обнуляет время реакции; число падает, хотя работа ничуть не улучшилась.
- Читать удовлетворённость без доли ответов. Когда отвечают только недовольные, среднее вводит в заблуждение. Сопоставляйте
satisfactionс тем, сколько опросов было фактически заполнено.
Если ваш GLPI показывает числа, которым никто не доверяет, проблема редко в GLPI: дело в базе и способе выгрузки. Сопровождение GLPI от NexTool включает моделирование этих показателей и сводный ежемесячный отчёт, который руководство читает без всяких таблиц.
Проверено командой NexTool Solutions.