Pinba (PinbaManager) — Профилировщик
Внимание
Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!
Обзор
IO\Profile\PinbaManager — обёртка над gggeek/polyfill-pinba для профилирования PHP-приложений. Отправляет таймеры и метрики в Pinba-сервер через UDP для анализа производительности.
Требования
composer require gggeek/polyfill-pinba- Pinba-сервер (Pinba v1 или Pinba2)
- Включить в
php.ini:pinba.enabled=1 pinba.server=127.0.0.1:3002
Или через PinbaManager::init():
\IO\Profile\PinbaManager::init([
'enabled' => true,
'server' => '127.0.0.1:3002',
]);
Как это работает
gggeek/polyfill-pinba — чистая PHP-реализация API расширения pinba. Не требует компиляции C-расширения. Автоматически отправляет собранные данные в Pinba-сервер по UDP в конце выполнения скрипта (auto-flush).
Конфигурация
Через .env (рекомендуется)
Фреймворк автоматически инициализирует PinbaManager при старте, если переменные заданы в .env:
PINBA_ENABLE=1
PINBA_SERVER=127.0.0.1:3002
PINBA_HOSTNAME=web01
PINBA_SCRIPT_NAME=/api/users
| Переменная | Описание | Пример |
|---|---|---|
PINBA_ENABLE | Включить профилирование (1 = вкл) | 1 |
PINBA_SERVER | Адрес сервера host:port (приоритетнее PINBA_HOST/PINBA_PORT) | 127.0.0.1:3002 |
PINBA_HOST | Хост Pinba-сервера | 127.0.0.1 |
PINBA_PORT | Порт Pinba-сервера | 3002 |
PINBA_HOSTNAME | Имя хоста для отображения в Pinba | web01 |
PINBA_SCRIPT_NAME | Имя скрипта | /api/users |
Доступ через $app->pinba:
$timerId = $app->pinba->start('api_request', ['endpoint' => '/api/users']);
// ... обработка
$app->pinba->stop($timerId);
Через define()
define('PINBA_ENABLE', 1);
define('PINBA_SERVER', '127.0.0.1:3002');
define('PINBA_HOSTNAME', 'web01');
Через init() вручную
\IO\Profile\PinbaManager::init([
'enabled' => true,
'server' => '127.0.0.1:3002',
'hostname' => 'web01',
'server_name' => 'example.com',
'script_name' => '/api/users',
]);
Параметры init()
| Параметр | Тип | Описание |
|---|---|---|
enabled | bool | Включить профилирование |
server | string | Адрес Pinba-сервера (host:port) — приоритетнее host/port |
host | string | Хост (используется если server не задан) |
port | int | Порт (используется если server не задан) |
hostname | string | Имя хоста для отображения в Pinba |
server_name | string | Имя сервера (например, example.com) |
script_name | string | Имя скрипта |
start_time | float | Время начала (microtime) для точного замера |
Методы
init(array $config = []): static
Инициализация менеджера и настройка polyfill-pinba.
\IO\Profile\PinbaManager::init([
'enabled' => true,
'server' => '127.0.0.1:3002',
]);
start(string $name, array $tags = []): int|false
Начать замер времени. Возвращает ID таймера для передачи в stop().
| Параметр | Тип | Описание |
|---|---|---|
$name | string | Имя операции (становится тегом group) |
$tags | array | Дополнительные теги |
| Возврат | int|false | ID таймера или false если disabled |
$timerId = \IO\Profile\PinbaManager::start('db_query', ['table' => 'users', 'operation' => 'select']);
// ... выполнение запроса
\IO\Profile\PinbaManager::stop($timerId);
stop(int|false $timerId): void
Остановить таймер и зафиксировать время.
\IO\Profile\PinbaManager::stop($timerId);
addTimer(string $name, float $value, array $tags = []): void
Добавить завершённый таймер с известным временем.
\IO\Profile\PinbaManager::addTimer('db_query', 0.05, ['query' => 'SELECT * FROM users']);
addMetric(string $name, float $value, array $tags = []): void
Добавить метрику (по сути то же, что addTimer).
\IO\Profile\PinbaManager::addMetric('memory_usage', memory_get_usage() / 1024 / 1024);
\IO\Profile\PinbaManager::addMetric('users_count', count($users));
setTag(string $key, string $value): void
Установить тег уровня запроса.
\IO\Profile\PinbaManager::setTag('application', 'io7proj');
\IO\Profile\PinbaManager::setTag('environment', 'production');
setRequestTime(float $time): void
Установить время выполнения запроса вручную.
\IO\Profile\PinbaManager::setRequestTime(microtime(true) - $startTime);
flush(): void
Принудительная отправка данных в Pinba-сервер.
\IO\Profile\PinbaManager::flush();
reset(): void
Сбросить все таймеры и данные.
\IO\Profile\PinbaManager::reset();
getInfo(): array
Получить информацию о текущем запросе.
$info = \IO\Profile\PinbaManager::getInfo();
isAvailable(): bool
Проверка доступности Pinba.
if (\IO\Profile\PinbaManager::isAvailable()) {
// Pinba включён
}
Примеры
Замер времени запроса
\IO\Profile\PinbaManager::init([
'enabled' => true,
'server' => '127.0.0.1:3002',
]);
$timerId = \IO\Profile\PinbaManager::start('api_request', [
'endpoint' => '/api/users',
'method' => 'GET',
]);
// ... обработка запроса
$users = $db->search('users', []);
\IO\Profile\PinbaManager::stop($timerId);
// Данные автоматически отправятся в конце скрипта
Замер нескольких операций
$t1 = \IO\Profile\PinbaManager::start('page_render');
$t2 = \IO\Profile\PinbaManager::start('db_query', ['table' => 'users']);
$users = $db->search('users', []);
\IO\Profile\PinbaManager::stop($t2);
\IO\Profile\PinbaManager::addMetric('users_count', count($users));
// ... рендер шаблона
\IO\Profile\PinbaManager::stop($t1);
Ручное добавление таймеров
$start = microtime(true);
// ... сложная операция
$duration = microtime(true) - $start;
\IO\Profile\PinbaManager::addTimer('complex_operation', $duration, [
'type' => 'data_processing',
]);
Мониторинг памяти
\IO\Profile\PinbaManager::addMetric('memory_usage', memory_get_usage() / 1024 / 1024);
\IO\Profile\PinbaManager::addMetric('peak_memory', memory_get_peak_usage() / 1024 / 1024);
В cron задачах
class CleanUpCron extends \IO\CronTemplate
{
public function cron_do(): void
{
$timerId = \IO\Profile\PinbaManager::start('cleanup_job');
// ... очистка данных
\IO\Profile\PinbaManager::stop($timerId);
\IO\Profile\PinbaManager::addMetric('cleaned_items', $count);
}
}
Использование без PinbaManager
Можно использовать polyfill-pinba напрямую:
use PinbaPhp\Polyfill\PinbaFunctions as pinba;
pinba::init(microtime(true));
$timer = pinba_timer_start(['group' => 'db', 'operation' => 'select']);
// ... запрос
pinba_timer_stop($timer);
pinba_timer_add(['group' => 'cache', 'operation' => 'get'], 0.001);
pinba_flush();