Метрики Prometheus
OxPHP отдаёт Prometheus-совместимые метрики в текстовом формате экспозиции (text exposition format) на GET /metrics внутреннего сервера. Они охватывают пропускную способность по запросам, время ответа, состояние соединений, состояние пула воркеров, кеширование статических файлов, эффективность сжатия и производительность режима воркеров.
Включение метрик
Задайте INTERNAL_ADDR, чтобы запустить внутренний сервер:
INTERNAL_ADDR=127.0.0.1:9090Затем собирайте метрики из Prometheus или любого совместимого коллектора:
curl http://localhost:9090/metricsМетрики сервера
| Метрика | Тип | Описание |
|---|---|---|
oxphp_uptime_seconds |
gauge | Секунд с момента запуска процесса сервера |
oxphp_requests_total |
counter | Всего HTTP-запросов, принятых на основном порту |
Метрики запросов
| Метрика | Тип | Описание |
|---|---|---|
oxphp_requests_by_method_total |
counter | Запросы по HTTP-методу. Метка: method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, QUERY, OTHER) |
oxphp_responses_by_status_total |
counter | Ответы по классу статуса. Метка: status (1xx, 2xx, 3xx, 4xx, 5xx) |
oxphp_request_bytes_total |
counter | Всего принятых байт тела запроса |
oxphp_response_bytes_total |
counter | Всего отправленных байт тела ответа |
oxphp_request_cancelled_total |
counter | Отменённые запросы по причине. Метка: reason (client_abort, timeout, shutdown). Экспортируется всегда |
Экспортируются только методы и классы статусов, по которым зафиксировано хотя бы одно событие. Метки с нулевым значением опускаются.
Гистограмма длительности запросов
| Метрика | Тип | Описание |
|---|---|---|
oxphp_request_duration_us |
histogram | Полная длительность запроса в микросекундах для всех запросов (статические файлы и PHP) |
Границы бакетов (микросекунды): 100, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, +Inf.
Используйте эту гистограмму, чтобы отслеживать общую задержку, выявлять медленные эндпоинты и измерять перцентили хвостовой задержки (tail latency).
Метрики соединений
| Метрика | Тип | Описание |
|---|---|---|
oxphp_active_connections |
gauge | Открытые в данный момент TCP-соединения на основном порту |
oxphp_pending_requests |
gauge | Запросы, направленные в данный момент PHP-воркерам (в очереди и в обработке) |
oxphp_dropped_requests_total |
counter | Запросы, при которых PHP-воркер завершился с ошибкой уже после приёма запроса |
Метрики пула воркеров
| Метрика | Тип | Описание |
|---|---|---|
oxphp_workers_current |
gauge | Текущее число потоков PHP-воркеров |
oxphp_workers_min |
gauge | Минимальное число воркеров (в статическом режиме равно текущему) |
oxphp_workers_max |
gauge | Максимальное число воркеров (в статическом режиме равно текущему) |
oxphp_workers_idle |
gauge | Воркеры, не обрабатывающие запрос в данный момент |
oxphp_busy_workers |
gauge | Воркеры, обрабатывающие запрос в данный момент |
oxphp_workers_spawned_total |
counter | Всего воркеров, порождённых с момента запуска (включая начальные воркеры) |
oxphp_workers_retired_total |
counter | Всего воркеров, выведенных из работы по таймауту простоя (только в динамическом режиме) |
Метрики супервизора воркеров
Наблюдаемость на уровне отдельных воркеров, экспортируемая супервизором воркеров. Каждый ряд снабжён меткой worker_id (индекс слота). Эти метрики появляются, как только супервизор начинает отслеживать состояние отдельных воркеров.
| Метрика | Тип | Описание |
|---|---|---|
oxphp_worker_request_age_seconds |
gauge | Возраст обрабатываемого запроса на каждом воркере, в секундах. Метка: worker_id |
oxphp_worker_long_running_total |
counter | Сканирования супервизора, при которых обнаружен запрос старше порога зависания. Метка: worker_id |
oxphp_worker_stuck_total |
counter | Счётчик классификации зависаний по каждому воркеру. Метки: worker_id, kind (io, c_call, cpu) |
Гистограмма ожидания в очереди
| Метрика | Тип | Описание |
|---|---|---|
oxphp_queue_wait_us |
histogram | Время ожидания запроса в очереди до того, как воркер возьмёт его в работу, в микросекундах |
Границы бакетов (микросекунды): 50, 100, 250, 500, 1000, 2500, 5000, 10000, 50000, +Inf.
Большое время ожидания в очереди указывает на то, что все воркеры заняты и вам следует увеличить PHP_WORKERS или QUEUE_CAPACITY.
Метрики ограничения частоты запросов
| Метрика | Тип | Описание |
|---|---|---|
oxphp_rate_limited_total |
counter | Запросы, отклонённые ограничителем частоты (возвращён 429) |
oxphp_php_deny_total |
counter | Запросы, заблокированные PHP_DENY_PATHS (запрещено выполнение .php). См. Дени-лист выполнения PHP |
Метрики кеша статических файлов
| Метрика | Тип | Описание |
|---|---|---|
oxphp_static_cache_hits_total |
counter | Запросы статических файлов, обслуженные из кеша в памяти |
oxphp_static_cache_misses_total |
counter | Запросы статических файлов, потребовавшие чтения с диска |
Метрики сжатия
| Метрика | Тип | Описание |
|---|---|---|
oxphp_compressed_responses_total |
counter | Ответы, сжатые с помощью Brotli |
oxphp_compression_bytes_saved_total |
counter | Всего байт, сэкономленных сжатием (исходный размер минус сжатый) |
Метрики режима воркеров
Эти метрики экспортируются только при активном режиме воркеров (WORKER_MODE_ENABLED=true).
Глобальные счётчики
| Метрика | Тип | Описание |
|---|---|---|
oxphp_worker_mode_enabled |
gauge | Всегда 1, когда режим воркеров активен |
oxphp_worker_requests_handled_total |
counter | Всего запросов, обработанных постоянными воркерами |
oxphp_worker_recycles_total |
counter | Всего перезапусков воркеров (воркер завершился и был порождён заново) |
oxphp_worker_recycles_by_reason_total |
counter | Перезапуски по причине. Метка: reason (scheduled, max_memory, error) |
oxphp_worker_soft_resets_total |
counter | Всего мягких сбросов, выполненных между запросами |
Датчики по отдельным воркерам
| Метрика | Тип | Описание |
|---|---|---|
oxphp_worker_memory_bytes |
gauge | Текущее использование кучи PHP каждым воркером. Метка: worker (индекс слота, например "0", "1") |
oxphp_worker_uptime_seconds |
gauge | Секунд с момента порождения каждого воркера. Метка: worker |
oxphp_worker_requests_count |
gauge | Запросы, обработанные каждым экземпляром воркера. Метка: worker |
Гистограмма длительности запросов воркера
| Метрика | Тип | Описание |
|---|---|---|
oxphp_worker_request_duration_us |
histogram | Время выполнения PHP-обработчика на один запрос в микросекундах (только в режиме воркеров) |
Границы бакетов (микросекунды): 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, +Inf.
Эта гистограмма измеряет время, проведённое внутри колбэка PHP-обработчика, не учитывая время ожидания в очереди. Используйте её, чтобы выявлять медленные обработчики и отслеживать хвостовую задержку в режиме воркеров.
Метрики асинхронного пула
Для этих метрик необходимо задать ASYNC_WORKERS ненулевое значение, и у каждой есть собственное условие экспорта: счётчики появляются только после того, как хотя бы одна задача была направлена в пул или отклонена, датчики _in_flight / _in_flight_limit появляются, как только пул подключит свой счётчик задач в обработке, а oxphp_async_output_discarded_bytes_total появляется только после того, как какой-то вывод был отброшен.
| Метрика | Тип | Описание |
|---|---|---|
oxphp_async_tasks_dispatched_total |
counter | Всего асинхронных задач, направленных в фоновый пул |
oxphp_async_tasks_completed_total |
counter | Асинхронные задачи, успешно завершившиеся |
oxphp_async_tasks_failed_total |
counter | Асинхронные задачи, выбросившие исключение |
oxphp_async_tasks_cancelled_total |
counter | Асинхронные задачи, которые были отменены |
oxphp_async_tasks_rejected_total |
counter | Асинхронные задачи, отклонённые при отправке — потому что очередь пула была заполнена или достигнут предел числа задач в обработке (ASYNC_MAX_FIBERS × ASYNC_WORKERS) |
oxphp_async_tasks_stranded_total |
counter | Воркеры, продолжившие работу после таймаута await_race / await_any. Каждая такая зависшая задача может продлить RSHUTDOWN до 5 секунд. |
oxphp_async_tasks_in_flight |
gauge | Асинхронные задачи, находящиеся в очереди или выполняющиеся в данный момент (экспортируется, как только пул подключит свой счётчик задач в обработке) |
oxphp_async_tasks_in_flight_limit |
gauge | Максимальное число одновременно выполняющихся асинхронных задач (ASYNC_MAX_FIBERS × ASYNC_WORKERS) |
oxphp_async_output_discarded_bytes_total |
counter | Байты вывода асинхронной задачи, отброшенные при простое воркера (у echo в асинхронной задаче нет клиента, который бы его получил) |
Советы по дашбордам Grafana
Следующие PromQL-запросы полезны при построении дашбордов:
Частота запросов (запросов в секунду):
rate(oxphp_requests_total[5m])Среднее время ответа (миллисекунды):
rate(oxphp_request_duration_us_sum[5m])
/ rate(oxphp_requests_total[5m]) / 1000p99 длительности запроса (миллисекунды):
histogram_quantile(0.99, rate(oxphp_request_duration_us_bucket[5m])) / 1000Доля ошибок (ответы 5xx в процентах):
rate(oxphp_responses_by_status_total{status="5xx"}[5m])
/ rate(oxphp_requests_total[5m]) * 100Загрузка пула воркеров:
oxphp_busy_workers / oxphp_workers_currentНасыщение очереди (частота отбрасывания в секунду):
rate(oxphp_dropped_requests_total[5m])p99 ожидания в очереди (микросекунды):
histogram_quantile(0.99, rate(oxphp_queue_wait_us_bucket[5m]))Доля попаданий в кеш статических файлов:
rate(oxphp_static_cache_hits_total[5m])
/ (rate(oxphp_static_cache_hits_total[5m]) + rate(oxphp_static_cache_misses_total[5m]))Байты, сэкономленные сжатием, в секунду:
rate(oxphp_compression_bytes_saved_total[5m])p99 задержки в режиме воркеров (микросекунды):
histogram_quantile(0.99, rate(oxphp_worker_request_duration_us_bucket[5m]))Частота перезапусков воркеров (в минуту):
rate(oxphp_worker_recycles_total[5m]) * 60Среднее использование памяти воркером:
avg(oxphp_worker_memory_bytes)Конфигурация сбора для Prometheus
Добавьте задание сбора (scrape job) в ваш prometheus.yml:
scrape_configs:
- job_name: "oxphp"
scrape_interval: 15s
static_configs:
- targets: ["oxphp:9090"]Для service discovery в Kubernetes:
scrape_configs:
- job_name: "oxphp"
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: oxphp
action: keep
- source_labels: [__meta_kubernetes_pod_ip]
target_label: __address__
replacement: "$1:9090"Смотрите также
- Проверки работоспособности — эндпоинты
/healthи/configна внутреннем сервере - Справочник по конфигурации — все переменные окружения, включая
INTERNAL_ADDR - Корректное завершение работы — как дренирование соединений влияет на
oxphp_active_connections - Режим воркеров — постоянные воркеры и метрики, которые они экспортируют