cyrtolat/spiral-runtime-diagnostics

Runtime diagnostics for Spiral Framework: call logging without redeploying or restarting RoadRunner.

Installs: 2

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/cyrtolat/spiral-runtime-diagnostics

v0.1.1 2026-01-27 14:16 UTC

This package is auto-updated.

Last update: 2026-01-28 09:52:49 UTC


README

Описание

Библиотека runtime-диагностики для Spiral Framework: временно запускает логирование вызовов в рантайме, без деплоя и без перезапуска RoadRunner-воркеров.

Ключевая идея

Пакет даёт interceptor, совместимый с механизмом interception в Spiral: его можно встроить в ваш pipeline (который вы настраиваете сами в приложении), чтобы получать «первый срез» по последующим вызовам. Включив диагностику на живой системе, вы без деплоя и без перезапуска RoadRunner быстро соберёте поверхностные сигналы (что именно и как долго выполнялось, где чаще падает, где всплески по времени/памяти) и локализуете проблемные кейсы. На этом роль пакета заканчивается: он помогает найти направление, а детальную причину уже нужно разбирать внутри конкретного кода/обработчиков.

Как это работает

Управление диагностикой выполняется через консольные команды. Они не «общаются» с воркерами напрямую, а создают и удаляют специальный временный файл — runfile. В этом файле хранится состояние запущенной диагностики и её параметры (например, включено ли логирование и как долго оно должно работать). Поскольку runfile лежит на сервере в общей для приложения файловой системе, его видят все RoadRunner-воркеры: переключение режима применяется сразу ко всем процессам, а не к одному конкретному воркеру.

Установка и конфигурация

Пакет устанавливается через Composer:

composer require cyrtolat/spiral-runtime-diagnostics

Конфигурация

Пакет использует секцию конфигурации diagnostics. Рекомендуемый способ настройки — опубликовать файл конфигурации в приложение и отредактировать его под своё окружение:

php app.php diag:publish --write

Полезные флаги:

  • --path=... (по умолчанию @config/diagnostics.php)
  • --force / --overwrite — перезаписать существующий файл

Если конфиг не опубликован, пакет всё равно будет работать: bootloader подставит значения по умолчанию из stubs/diagnostics.php.

Команда php app.php diag:config выводит актуальные (эффективные) значения конфигурации diagnostics — с учётом опубликованного файла и переменных окружения.

Пример config/diagnostics.php:

return [
    // TTL по умолчанию для запуска диагностики (например: 30s, 5m, 1h, 2d, forever)
    'duration' => env('DIAGNOSTICS_DURATION', '1h'),

    // Путь к runfile (должен быть общим для CLI и воркеров: одна ФС/volume)
    // Рекомендуется делать путь уникальным для приложения/окружения.
    'runfile_path' => sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'diagnostics.json',

    // Канал логирования. Транспорт/handler настраивается в хост-приложении.
    'log_channel' => env('DIAGNOSTICS_LOG_CHANNEL', 'diagnostics'),

    // Ключ атрибута, по которому в контексте вызова хранится исходный callable.
    'callable_attribute' => 'callable',
];

Переменные окружения (если используешь stub как есть):

  • DIAGNOSTICS_DURATION — значение по умолчанию для diagnostics.duration
  • DIAGNOSTICS_LOG_CHANNEL — значение по умолчанию для diagnostics.log_channel

Параметр runfile_path — это общий «переключатель» для всех воркеров, поэтому путь должен быть уникальным для приложения/окружения и доступным одновременно и CLI, и воркерам (общая файловая система/volume).

Подключение к Spiral

Для работы пакета требуется три шага интеграции: подключение bootloader (регистрация команд и DI-зависимостей), добавление interceptor в pipeline приложения (желательно первым), и настройка канала логирования, куда будут попадать диагностические события.

1) Подключение Bootloader

Точка входа пакета в Spiral-приложение - это класс Cyrtolat\SpiralRuntimeDiagnostics\DiagnosticsBootloader::class. Его следует указать в Kernel (в список bootloaders): после этого появляются консольные команды php app.php diag:* и регистрируются DI-зависимости, необходимые для корректной работы пакета.

Важно: DiagnosticsBootloader не “включает” диагностику и не встраивает interceptor в pipeline. Он только регистрирует команды и биндинги.

2) Подключение Interceptor

Основное звено пакета — Cyrtolat\SpiralRuntimeDiagnostics\DiagnosticsInterceptor::class. Его необходимо добавить в общий pipeline interceptor-ов вашего приложения — где именно это настраивается, зависит от структуры проекта

Важно: DiagnosticsInterceptor должен применяться глобально, чтобы диагностика работала для всех перехватываемых вызовов.

Рекомендуемое размещение — первым в цепочке: так interceptor видит вызовы максимально “снаружи” и не теряет контекст из-за ранних выходов или обработки другими interceptor-ами.

3) Канал логирования

Пакет пишет диагностические события в лог через Psr\Log\LoggerInterface и использует канал из diagnostics.log_channel. При этом он не настраивает «куда именно» писать логи (handlers/transport/ротацию): это зона ответственности хост-приложения.

На практике это означает, что для выбранного канала в приложении должна быть настроена доставка логов в нужное место (отдельный файл, stdout, централизованный сборщик и т.п.). Иначе диагностика формально будет работать, но записи могут смешаться с общими логами, быть отфильтрованы уровнем или вообще не попасть никуда.

Использование

Диагностика управляется консольными командами diag:*: они включают режим на заданное время, показывают статус и позволяют остановить его вручную. Команды не требуют деплоя и не зависят от перезапуска воркеров — режим применяется ко всем процессам через общий runfile.

Команды

  • php app.php diag:config — текущие (эффективные) значения конфигурации
  • php app.php diag:info — краткая справка по режиму и применению
  • php app.php diag:publish — публикация шаблона конфигурации
  • php app.php diag:start — запуск диагностики
  • php app.php diag:status — текущий статус режима по runfile
  • php app.php diag:stop — остановка режима (удаление runfile, идемпотентно)

Команда diag:start принимает необязательный параметр --duration. Значение задаётся в человекочитаемом формате TTL, например 30s, 5m, 1h, 2d или forever. Если параметр не указан, используется значение по-умолчанию.

Формат лог-события

Пакет пишет одну запись на перехваченный вызов.

Message: diagnostics.action

Context (payload):

  • action (string) — идентификатор действия/вызова, который логируется
  • duration_ms (int) — длительность выполнения в миллисекундах
  • ok (bool) — признак успеха выполнения (true — успешно, false — ошибка/исключение)
  • memory_usage_bytes (int) — потребление памяти на момент завершения (в байтах)
  • memory_peak_bytes (int) — пиковое потребление памяти за время выполнения (в байтах)
  • memory_usage (string) — memory_usage_bytes в человекочитаемом виде
  • memory_peak (string) — memory_peak_bytes в человекочитаемом виде

Важно: пакет не настраивает транспорт логов (handlers/файлы/ротацию) и не решает, куда именно попадёт запись. Он лишь пишет событие в канал diagnostics.log_channel; настройка вывода — ответственность хост-приложения.

Практические заметки

  • Режим предназначен для кратковременного включения: объём логов может быть большим.
  • При использовании forever диагностика не завершится сама — её нужно остановить вручную командой diag:stop.
  • По истечении TTL логирование прекращается автоматически, даже если runfile остался на диске.
  • Доступ к запуску diag:* команд должен быть ограничен доверенными пользователями/ролями.