Мониторинг PHP приложений: продвинутые метрики и алерты

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему базового мониторинга недостаточно?

Базовый мониторинг PHP приложений (проверка "жив/мертв" и загрузка CPU) перестает работать на высоких нагрузках. Когда ваше приложение обрабатывает тысячи запросов в секунду, стандартные метрики не показывают узкие места: медленные запросы к БД, утечки памяти в долгих процессах или внезапные пики задержек (latency).

В этой статье мы рассмотрим продвинутый уровень мониторинга: сбор бизнес-метрик, профилирование в реальном времени, настройку алертов на основе перцентилей и интеграцию с современными стеками observability (Prometheus + Grafana). Вы научитесь внедрять инструментарий, который позволит не просто видеть, что приложение "упало", но и предсказывать проблемы до их возникновения.

1. Продвинутые метрики: от HTTP-кодов к бизнес-показателям

Стандартные счетчики (количество запросов, 200/500 статусы) — это минимум. Для глубокого анализа нужно собирать:

  • Latency (задержка): p50, p95, p99 время ответа. Аномалии в p99 указывают на "выбросы" в работе.
  • Потребление памяти: не только пиковое значение, но и скорость роста в рамках одного запроса.
  • Время выполнения внешних вызовов: Redis, MySQL, RabbitMQ — каждый сервис должен иметь свою метрику.
  • Бизнес-метрики: количество оформленных заказов, ошибок валидации, скорость очередей.

Пример сбора метрик с использованием promphp/prometheus_client_php:

use Prometheus\CollectorRegistry;
use Prometheus\RenderTextFormat;
use Prometheus\Storage\InMemory;

$registry = new CollectorRegistry(new InMemory());

// Гистограмма для времени выполнения запроса
$histogram = $registry->registerHistogram(
    'app', 'request_duration_seconds', 'HTTP request duration',
    ['method', 'endpoint'],
    [0.1, 0.5, 1.0, 2.0, 5.0]
);

// Счетчик бизнес-событий
$counter = $registry->registerCounter(
    'business', 'orders_total', 'Total orders created',
    ['status'] // success/failed
);

// В middleware замеряем время
$start = microtime(true);
// ... выполнение запроса ...
$duration = microtime(true) - $start;
$histogram->observe($duration, ['GET', '/api/orders']);

2. Health Checks и Deep Probing: проверка зависимостей

Простой ping-эндпоинт не проверяет доступность базы данных, кэша или очередей. Создайте комплексный health check, который имитирует реальные запросы:

// health.php
$checks = [
    'database' => function () {
        $db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
        $db->query('SELECT 1');
        return true;
    },
    'redis' => function () {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->ping();
        return true;
    },
    'queue' => function () {
        // Проверяем, что RabbitMQ не переполнен
        $channel = new AMQPChannel(new AMQPConnection());
        $queue = new AMQPQueue($channel);
        return $queue->declareQueue() !== false;
    }
];

$results = [];
$healthy = true;
foreach ($checks as $name => $check) {
    try {
        $check();
        $results[$name] = 'ok';
    } catch (\Throwable $e) {
        $results[$name] = 'failed: ' . $e->getMessage();
        $healthy = false;
    }
}

header('Content-Type: application/json');
http_response_code($healthy ? 200 : 503);
echo json_encode(['status' => $healthy ? 'healthy' : 'unhealthy', 'checks' => $results]);

Такой эндпоинт можно подключить к Kubernetes liveness/readiness probes или к внешнему мониторингу (например, UptimeRobot), который будет проверять не только доступность, но и работоспособность всех зависимостей.

3. Алерты на основе перцентилей и аномалий

Алерты на "среднее время ответа" часто пропускают проблемы. Если среднее = 200ms, но каждый 100-й запрос выполняется 10 секунд, среднее все еще будет низким. Используйте перцентили (p99) и базовые линии (baselines).

Пример правил для Prometheus Alertmanager:

groups:
  - name: php_app
    rules:
      - alert: HighLatencyP99
        expr: histogram_quantile(0.99, rate(app_request_duration_seconds_bucket[5m])) > 2
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "P99 latency over 2s for {{ $labels.endpoint }}"

      - alert: HighErrorRate
        expr: rate(app_http_requests_total{status=~"5.."}[5m]) / rate(app_http_requests_total[5m]) > 0.05
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Error rate above 5%"

      - alert: MemoryLeakDetected
        expr: process_resident_memory_bytes / 1024 / 1024 > 512
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Memory usage > 512MB on {{ $labels.instance }}"

Для бизнес-метрик настройте алерты на "внезапное падение" — например, если количество заказов упало на 50% за час (используйте predict_linear или пороговые значения).

4. Интеграция с Grafana: визуализация и дашборды

Данные бесполезны без визуализации. Создайте дашборд в Grafana, который покажет:

  • Тепловую карту (heatmap) задержек по эндпоинтам.
  • График перцентилей p50, p95, p99 на одном полотне.
  • Скорость ошибок в разрезе статусов (4xx, 5xx).
  • Топ медленных запросов — таблица с сортировкой по p99.

Пример запроса для получения p99 в Grafana (PromQL):

histogram_quantile(0.99,
  sum(rate(app_request_duration_seconds_bucket[                

Блоги

Рекомендаций по книгам