Мониторинг производительности

Инструменты ответа на вопросы «система тормозит — где?», «какие страницы самые тяжелые?», «что упало по таймауту?» и алертинг «прямо сейчас плохо».

Подход: приложение не собирает метрики постоянно — оно журналирует только аномалии (запрос дольше порога, ошибка 5xx). Пустые журналы = система не тормозит; наблюдение за такими журналами тривиально: «файл растёт» = «системе плохо». Аналитика по всем запросам строится не онлайн, а отчётом по access-логу Apache, в котором каждая строка несёт время обработки.

Составные части

Что Откуда берётся Зачем
Время обработки каждого запроса access-лог Apache, формат combined_time (число микросекунд ...us в конце строки) сырьё для отчёта и разбора инцидентов задним числом
Журнал медленных запросов приложение, runtime/logs/perf.log каждая строка — запрос дольше порога, с маршрутом и логином; сигнал для алертинга
Отчёт yii perf/report консольная команда по access-логу ежедневная аналитика: тяжелые маршруты, перцентили, таймауты, 5xx
Шаблон Zabbix zabbix/arms-perf-template.yaml алертинг: триггеры «N медленных запросов за 5 минут» и «N ошибок 5xx за 5 минут»

Включение

1. Время обработки в access-логе Apache

В docker-инсталляции формат уже задан в конфигурации образа (docker/apache/site.conf) — достаточно обновиться.

При ручной установке допишите в VirtualHost:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %Dus" combined_time
CustomLog "/var/log/apache2/inventory.http_access.log" combined_time

Проверка: в конце строк access-лога появляется длительность вида 1234567us. Строки старого формата не мешают — отчёт учтёт их без таймингов.

2. Параметры приложения

В config/params-local.php (значения по умолчанию — в params.php):

//порог журнала медленных запросов, сек; 0 = выключить журнал
'perf.slow_request_seconds'=>3,
//маски access-логов для отчёта; ротированные куски и .gz читаются прозрачно
'perf.access_log'=>'/var/log/apache2/inventory.http_access.log*',

Порог подбирается так, чтобы в спокойное время perf.log оставался (почти) пустым: лог, в котором каждая строка — аномалия, можно мониторить триггером «появились строки». Если штатно всё отдаётся за секунду — порог 3 сек хорош; если есть легально тяжелые страницы — поднимите порог или живите с фоновым уровнем срабатываний ниже порога чувствительности триггера.

3. Ежедневный отчёт (cron)

10 0 * * * cd /var/www/arms && php yii perf/report --email=1 >/dev/null

--email=1 шлёт отчёт на adminEmail (нужен настроенный mailer); --email=адрес — на указанный адрес; без --email отчёт просто печатается (можно смотреть руками за любой день: php yii perf/report 2026-08-16).

Полезные опции: --top=20 — размер топов, --slow=29 — порог «подозрения на таймаут» (сек), --file= — явные маски логов вместо параметра.

4. Алертинг в Zabbix

Импортируйте шаблон ARMS perf monitoring (zabbix/arms-perf-template.yaml): Data collection → Templates → Import, затем прицепите шаблон к хосту инсталляции.

На хосте потребуется:

  • zabbix-agent с активными проверками: лог-итемы работают только активным агентом (ServerActive= указывает на сервер, Hostname= совпадает с именем хоста в Zabbix);
  • право чтения логов: apache-логи обычно root:adm — добавьте пользователя zabbix в группу adm (usermod -aG adm zabbix); runtime/logs/perf.log должен быть доступен агенту на чтение. В docker-инсталляции логи смонтированы наружу — агенту на хосте достаточно прав на смонтированные каталоги;
  • при нестандартных путях — переопределите макросы {$ARMS.ACCESS_LOG} / {$ARMS.PERF_LOG} на хосте (это regexp-маски logrt, точки экранируются).

Триггеры срабатывают не на единичное событие, а на плотность — по умолчанию 5 событий за 5 минут (макросы {$ARMS.SLOW.MAXCOUNT} / {$ARMS.5XX.MAXCOUNT}): одиночная медленная страница — шум, серия — инцидент.

Как пользоваться

Ежедневный отчёт

  • «Топ по суммарному времени» — создатели нагрузки: маршруты, на которые сервер потратил больше всего секунд за день (частые×небыстрые). Кандидаты на оптимизацию «для системы».
  • «Топ по p95» — медленные для человека страницы, даже редкие. p95 = 95% запросов маршрута быстрее этого времени. Кандидаты на оптимизацию «для пользователя».
  • «Подозрения на таймаут» — запросы дольше 29 сек. Длительности, кучкующиеся у круглых границ (30 сек, 60 сек), — почти наверняка упёрлись в чей-то таймаут (php max_execution_time, прокси, внешняя система).
  • Разрез ui/api — чей вклад в нагрузку больше: людей или внешних синхронизаций (инвентаризационные агенты, AD-синк и т.п. ходят через /api).

Разбор инцидента («в 14:32 не открывалась страница»)

  1. Время берём из алерта Zabbix или жалобы.
  2. Смотрим окно ±5 минут в access-логе: bash grep "17/Aug/2026:14:3" /var/log/apache2/inventory.http_access.log | sort -t' ' -k4
  3. Сопоставляем с perf.log за то же время — там маршруты и логины: кто именно и на чём ждал.
  4. Типовые картины:
    • залп /api/-запросов вокруг проблемного времени, у остальных запросов выросли длительности → нагрузка от синхронизации; смотрим какая (по URL и IP источника) и разносим по времени/оптимизируем её;
    • один маршрут долгий, остальные в норме → тяжелая страница; ждём её в топах отчёта и оптимизируем;
    • длительность = граница таймаута (ровно 30/60 сек), в БД при этом тихо → ждали внешнюю систему (LDAP, интеграции); смотрим доступность этой системы в то время;
    • всё подряд стало медленным, включая лёгкие страницы → общая просадка (диск, память, соседи по гипервизору, блокировки БД) — смотрим метрики хоста и БД за это окно.

Если лог-триггеры «слепы»

Запланированное продолжение (пока сознательно не реализовано): расчёт p95 времени ответа скользящим окном и отправка в Zabbix через zabbix_sender, триггер на резкий рост. Понадобится, если возникнут инциденты, при которых пользователи жалуются, а триггеры молчат (деградация ниже порога slow-лога). Реализация описана в docs/dev/perf-monitoring.md (раздел «Дальнейшее развитие»).