Документация FlightPHP APM
Добро пожаловать в FlightPHP APM — ваш личный тренер по производительности приложения! Это руководство — ваша дорожная карта по настройке, использованию и освоению мониторинга производительности приложений (APM) с FlightPHP. Будь вы охотником за медленными запросами или просто хотите погрузиться в графики задержек, мы вас прикроем. Давайте сделаем ваше приложение быстрее, ваших пользователей счастливее, а сессии отладки — легкими как ветер!
Посмотрите демо панели управления для сайта Flight Docs.
Почему APM важен
Представьте: ваше приложение — это оживленный ресторан. Без способа отслеживать, сколько времени занимают заказы или где кухня тормозит, вы угадываете, почему клиенты уходят недовольными. APM — ваш су-шеф: он следит за каждым шагом, от входящих запросов до запросов к базе данных, и отмечает всё, что вас замедляет. Медленные страницы отпугивают пользователей (исследования говорят, что 53% уходят, если сайт загружается дольше 3 секунд!), а APM помогает поймать эти проблемы до того, как они укусят. Это проактивное спокойствие — меньше моментов «почему это сломано?», больше побед «смотрите, как круто это работает!».
Установка
Начните с Composer:
composer require flightphp/apm
Вам понадобится:
- PHP 7.4+: Обеспечивает совместимость с LTS-дистрибутивами Linux, поддерживая современный PHP.
- FlightPHP Core v3.15+: Легковесный фреймворк, который мы усиливаем.
Поддерживаемые базы данных
FlightPHP APM в настоящее время поддерживает следующие базы данных для хранения метрик:
- SQLite3: Простая, на основе файлов, идеальна для локальной разработки или небольших приложений. Вариант по умолчанию в большинстве настроек.
- MySQL/MariaDB: Идеально для крупных проектов или производственных сред, где нужна надежная, масштабируемая хранилище.
Вы можете выбрать тип базы данных на шаге конфигурации (см. ниже). Убедитесь, что в вашей среде PHP установлены необходимые расширения (например, pdo_sqlite
или pdo_mysql
).
Начало работы
Вот ваш пошаговый путь к крутости APM:
1. Регистрация APM
Вставьте это в ваш index.php
или файл services.php
, чтобы начать отслеживание:
use flight\apm\logger\LoggerFactory;
use flight\Apm;
$ApmLogger = LoggerFactory::create(__DIR__ . '/../../.runway-config.json');
$Apm = new Apm($ApmLogger);
$Apm->bindEventsToFlightInstance($app);
// Если вы добавляете подключение к базе данных
// Должно быть PdoWrapper или PdoQueryCapture из расширений Tracy
$pdo = new PdoWrapper('mysql:host=localhost;dbname=example', 'user', 'pass', null, true); // <-- True обязательно для включения отслеживания в APM.
$Apm->addPdoConnection($pdo);
Что здесь происходит?
LoggerFactory::create()
берет вашу конфигурацию (подробнее об этом скоро) и настраивает логгер — по умолчанию SQLite.Apm
— звезда: он слушает события Flight (запросы, маршруты, ошибки и т.д.) и собирает метрики.bindEventsToFlightInstance($app)
связывает всё с вашим приложением Flight.
Про-совет: Сэмплинг Если ваше приложение загружено, логирование каждого запроса может перегрузить систему. Используйте коэффициент сэмплинга (от 0.0 до 1.0):
$Apm = new Apm($ApmLogger, 0.1); // Логирует 10% запросов
Это сохраняет производительность высокой, при этом давая надежные данные.
2. Настройка
Запустите это, чтобы создать .runway-config.json
:
php vendor/bin/runway apm:init
Что это делает?
- Запускает мастер, спрашивающий, откуда берутся сырые метрики (источник) и куда идут обработанные данные (назначение).
- По умолчанию SQLite — например,
sqlite:/tmp/apm_metrics.sqlite
для источника, другой для назначения. - В итоге вы получите конфигурацию вроде:
{ "apm": { "source_type": "sqlite", "source_db_dsn": "sqlite:/tmp/apm_metrics.sqlite", "storage_type": "sqlite", "dest_db_dsn": "sqlite:/tmp/apm_metrics_processed.sqlite" } }
Этот процесс также спросит, хотите ли вы запустить миграции для этой настройки. Если вы настраиваете это впервые, ответ — да.
Почему два места? Сырые метрики накапливаются быстро (представьте нефильтрованные логи). Воркер обрабатывает их в структурированное назначение для панели. Держит всё в порядке!
3. Обработка метрик с помощью воркера
Воркер превращает сырые метрики в данные, готовые для панели. Запустите его один раз:
php vendor/bin/runway apm:worker
Что он делает?
- Читает из вашего источника (например,
apm_metrics.sqlite
). - Обрабатывает до 100 метрик (размер пакета по умолчанию) в ваше назначение.
- Останавливается, когда закончит или если метрик больше нет.
Держите его запущенным Для живых приложений вам понадобится непрерывная обработка. Вот ваши варианты:
-
Режим демона:
php vendor/bin/runway apm:worker --daemon
Работает вечно, обрабатывая метрики по мере поступления. Отлично для разработки или небольших настроек.
-
Crontab: Добавьте это в ваш crontab (
crontab -e
):* * * * * php /path/to/project/vendor/bin/runway apm:worker
Запускается каждую минуту — идеально для производства.
-
Tmux/Screen: Начните отсоединяемую сессию:
tmux new -s apm-worker php vendor/bin/runway apm:worker --daemon # Ctrl+B, затем D для отсоединения; `tmux attach -t apm-worker` для переподключения
Держит его запущенным даже при выходе из системы.
-
Пользовательские настройки:
php vendor/bin/runway apm:worker --batch_size 50 --max_messages 1000 --timeout 300
--batch_size 50
: Обрабатывает 50 метрик за раз.--max_messages 1000
: Останавливается после 1000 метрик.--timeout 300
: Выходит через 5 минут.
Зачем это нужно? Без воркера ваша панель пуста. Это мост между сырыми логами и полезными инсайтами.
4. Запуск панели
Посмотрите жизненные показатели вашего приложения:
php vendor/bin/runway apm:dashboard
Что это?
- Запускает PHP-сервер на
http://localhost:8001/apm/dashboard
. - Показывает логи запросов, медленные маршруты, уровень ошибок и многое другое.
Настройте это:
php vendor/bin/runway apm:dashboard --host 0.0.0.0 --port 8080 --php-path=/usr/local/bin/php
--host 0.0.0.0
: Доступно с любого IP (удобно для удаленного просмотра).--port 8080
: Используйте другой порт, если 8001 занят.--php-path
: Укажите путь к PHP, если он не в PATH.
Откройте URL в браузере и исследуйте!
Режим производства
Для производства вам может потребоваться несколько техник, чтобы запустить панель, поскольку, вероятно, есть файрволы и другие меры безопасности. Вот несколько вариантов:
- Используйте обратный прокси: Настройте Nginx или Apache для перенаправления запросов на панель.
- SSH-туннель: Если вы можете SSH на сервер, используйте
ssh -L 8080:localhost:8001 youruser@yourserver
, чтобы туннелировать панель на вашу локальную машину. - VPN: Если ваш сервер за VPN, подключитесь к нему и получите доступ к панели напрямую.
- Настройте файрвол: Откройте порт 8001 для вашего IP или сети сервера (или любого порта, который вы установили).
- Настройте Apache/Nginx: Если у вас есть веб-сервер перед приложением, вы можете настроить его на домен или поддомен. Если вы это сделаете, установите корень документов в
/path/to/your/project/vendor/flightphp/apm/dashboard
.
Хотите другую панель?
Вы можете построить свою собственную панель, если хотите! Посмотрите директорию vendor/flightphp/apm/src/apm/presenter для идей, как представить данные для вашей собственной панели!
Возможности панели
Панель — ваш штаб APM: вот что вы увидите:
- Журнал запросов: Каждый запрос с временной меткой, URL, кодом ответа и общим временем. Нажмите «Детали» для middleware, запросов и ошибок.
- Самые медленные запросы: Топ-5 запросов, поглощающих время (например, «/api/heavy» за 2.5с).
- Самые медленные маршруты: Топ-5 маршрутов по среднему времени — отлично для выявления паттернов.
- Уровень ошибок: Процент неудачных запросов (например, 2.3% 500-х).
- Перцентили задержек: 95-й (p95) и 99-й (p99) времена ответа — знайте худшие сценарии.
- График кодов ответа: Визуализируйте 200-е, 404-е, 500-е со временем.
- Длинные запросы/Middleware: Топ-5 медленных вызовов базы данных и слоев middleware.
- Попадания/промахи кэша: Как часто кэш спасает день.
Дополнительно:
- Фильтруйте по «Последний час», «Последний день» или «Последняя неделя».
- Переключайте темный режим для поздних ночных сессий.
Пример:
Запрос к /users
может показать:
- Общее время: 150мс
- Middleware:
AuthMiddleware->handle
(50мс) - Запрос:
SELECT * FROM users
(80мс) - Кэш: Попадание в
user_list
(5мс)
Добавление пользовательских событий
Отслеживайте что угодно — например, вызов API или процесс оплаты:
use flight\apm\CustomEvent;
$app->eventDispatcher()->trigger('apm.custom', new CustomEvent('api_call', [
'endpoint' => 'https://api.example.com/users',
'response_time' => 0.25,
'status' => 200
]));
Где это появится? В деталях запроса панели под «Пользовательские события» — расширяемо с красивым форматированием JSON.
Пример использования:
$start = microtime(true);
$apiResponse = file_get_contents('https://api.example.com/data');
$app->eventDispatcher()->trigger('apm.custom', new CustomEvent('external_api', [
'url' => 'https://api.example.com/data',
'time' => microtime(true) - $start,
'success' => $apiResponse !== false
]));
Теперь вы увидите, тянет ли этот API ваше приложение вниз!
Мониторинг базы данных
Отслеживайте PDO-запросы так:
use flight\database\PdoWrapper;
$pdo = new PdoWrapper('sqlite:/path/to/db.sqlite', null, null, null, true); // <-- True обязательно для включения отслеживания в APM.
$Apm->addPdoConnection($pdo);
Что вы получаете:
- Текст запроса (например,
SELECT * FROM users WHERE id = ?
) - Время выполнения (например, 0.015с)
- Количество строк (например, 42)
Внимание:
- Опционально: Пропустите это, если не нужно отслеживание БД.
- Только PdoWrapper: Основной PDO еще не подключен — следите за обновлениями!
- Предупреждение о производительности: Логирование каждого запроса на сайте с тяжелой БД может замедлить вещи. Используйте сэмплинг (
$Apm = new Apm($ApmLogger, 0.1)
), чтобы облегчить нагрузку.
Пример вывода:
- Запрос:
SELECT name FROM products WHERE price > 100
- Время: 0.023с
- Строки: 15
Опции воркера
Настройте воркер по вкусу:
--timeout 300
: Останавливается через 5 минут — хорошо для тестирования.--max_messages 500
: Ограничивает 500 метриками — держит конечным.--batch_size 200
: Обрабатывает 200 за раз — балансирует скорость и память.--daemon
: Работает без остановки — идеально для живого мониторинга.
Пример:
php vendor/bin/runway apm:worker --daemon --batch_size 100 --timeout 3600
Работает час, обрабатывая 100 метрик за раз.
ID запроса в приложении
Каждый запрос имеет уникальный ID запроса для отслеживания. Вы можете использовать этот ID в вашем приложении для корреляции логов и метрик. Например, вы можете добавить ID запроса на страницу ошибок:
Flight::map('error', function($message) {
// Получите ID запроса из заголовка ответа X-Flight-Request-Id
$requestId = Flight::response()->getHeader('X-Flight-Request-Id');
// Кроме того, вы могли бы получить его из переменной Flight
// Этот метод не будет работать хорошо в swoole или других асинхронных платформах.
// $requestId = Flight::get('apm.request_id');
echo "Error: $message (Request ID: $requestId)";
});
Обновление
Если вы обновляетесь до новой версии APM, возможно, потребуется запустить миграции базы данных. Вы можете сделать это, запустив следующую команду:
php vendor/bin/runway apm:migrate
Это запустит любые необходимые миграции для обновления схемы базы данных до последней версии.
Примечание: Если ваша база данных APM большая по размеру, эти миграции могут занять некоторое время. Вы можете захотеть запустить эту команду в непиковые часы.
Очистка старых данных
Чтобы держать базу данных в порядке, вы можете очистить старые данные. Это особенно полезно, если вы запускаете загруженное приложение и хотите держать размер базы управляемым. Вы можете сделать это, запустив следующую команду:
php vendor/bin/runway apm:purge
Это удалит все данные старше 30 дней из базы данных. Вы можете скорректировать количество дней, передав другое значение опции --days
:
php vendor/bin/runway apm:purge --days 7
Это удалит все данные старше 7 дней из базы данных.
Устранение неисправностей
Застряли? Попробуйте эти:
-
Нет данных в панели?
- Запущен ли воркер? Проверьте
ps aux | grep apm:worker
. - Пути конфигурации совпадают? Проверьте, что DSN в
.runway-config.json
указывают на реальные файлы. - Запустите
php vendor/bin/runway apm:worker
вручную для обработки ожидающих метрик.
- Запущен ли воркер? Проверьте
-
Ошибки воркера?
- Загляните в ваши файлы SQLite (например,
sqlite3 /tmp/apm_metrics.sqlite "SELECT * FROM apm_metrics_log LIMIT 5"
). - Проверьте логи PHP на наличие стек-трейсов.
- Загляните в ваши файлы SQLite (например,
-
Панель не запускается?
- Порт 8001 занят? Используйте
--port 8080
. - PHP не найден? Используйте
--php-path /usr/bin/php
. - Файрвол блокирует? Откройте порт или используйте
--host localhost
.
- Порт 8001 занят? Используйте
-
Слишком медленно?
- Уменьшите коэффициент сэмплинга:
$Apm = new Apm($ApmLogger, 0.05)
(5%). - Уменьшите размер пакета:
--batch_size 20
.
- Уменьшите коэффициент сэмплинга:
-
Не отслеживает исключения/ошибки?
- Если у вас включен Tracy для проекта, он переопределит обработку ошибок Flight. Вам нужно отключить Tracy и убедиться, что
Flight::set('flight.handle_errors', true);
установлено.
- Если у вас включен Tracy для проекта, он переопределит обработку ошибок Flight. Вам нужно отключить Tracy и убедиться, что
-
Не отслеживает запросы к базе данных?
- Убедитесь, что вы используете
PdoWrapper
для подключений к базе данных. - Убедитесь, что последний аргумент в конструкторе
true
.
- Убедитесь, что вы используете