Средняя доля ошибок врёт при разном трафике: считаем общий ratio

У приложения две реплики. Первая получила сто запросов и ответила ошибкой на десять. Вторая получила десять тысяч запросов и тоже дала десять ошибок. На панелях реплик видны 10% и 0,1%. Если усреднить проценты, получится 5,05%, хотя во всём сервисе было лишь двадцать ошибок на 10100 запросов.

Ошибка возникает из-за одинакового веса реплик в среднем. Для пользователя важна доля неудачных запросов, а не средний процент по машинам. Реплика с малым трафиком не должна влиять на итог так же, как реплика, которая обслужила почти всю нагрузку. Сначала нужно сложить одинаковые величины, затем поделить общий числитель на общий знаменатель.

Агрегировать счётчики до деления

Предположим, http_requests_total содержит service, instance и status. Для общего уровня сервиса выражение суммирует скорости запросов, сохраняя только service. Окно в пять минут выбрано для примера и должно подходить частоте scrape.

sum by (service) (
  rate(http_requests_total{status=~"5.."}[5m])
)
/
sum by (service) (
  rate(http_requests_total[5m])
)

Rate применяется к каждой исходной серии до суммирования. Так сброс счётчика одной реплики обрабатывается на её собственном ряду. Мы объединяем уже рассчитанные скорости, а не пытаемся интерпретировать сумму независимых накопительных счётчиков как единственный процесс.

Само понятие ошибки нужно выбрать заранее. Ответы 5xx могут быть удобным техническим индикатором, но не всегда совпадают с пользовательским неуспехом: таймаут на прокси может не попасть в счётчик приложения, а ожидаемый отказ по бизнес-правилу может иметь другой статус. Важно, чтобы числитель был подмножеством того же потока событий, который считает знаменатель.

Проверить числа без Prometheus

Для приведённого набора общая доля равна 20 / 10100, то есть примерно 0,198%. Этот простой расчёт должен совпасть с результатом запроса на сопоставимых данных. Затем поменяйте распределение трафика между репликами, сохранив общее число запросов и ошибок. Общая доля должна остаться прежней, а среднее процентов может измениться.

Для проверки реальной панели временно выведите рядом общий числитель, общий знаменатель и результат деления. Это позволяет заметить потерянный фильтр service, лишний status или разные labels после агрегации. Когда итог выглядит странно, читать одну длинную дробь сложнее, чем сравнить две исходные величины.

Отдельно решите поведение при отсутствии трафика и отсутствии серии ошибок. Они не определяются правилом взвешивания автоматически. Полезно сохранять рядом число запросов: рост доли на двух запросах требует другой реакции, чем тот же процент на большой нагрузке. После этого уже можно выбирать порог алерта и минимальный объём наблюдений, не маскируя неверную арифметику настройками уведомлений.

Продолжить практику

Одно выражение или правило становится полезным, когда связано с конкретным действием инженера. В программе курса «Prometheus и Grafana: мониторинг и observability» — метрики учебного сервиса, exporters, обзорный и диагностический дашборды, SLI/SLO и алерты с инструкциями. Практика включает воспроизведение отказа или роста задержек и расследование по сигналам системы. Это продолжение для тех, кто хочет собрать мониторинг, по которому можно принимать решения во время сбоя.

Посмотреть программу курса

Источник: официальная документация.

Другие задачи по теме: Метрики и уведомления без неверных выводов.

Продолжить на практике

  • Prometheus и Grafana: мониторинг и observability ↗

    Замечайте сбои до жалоб пользователей. Соберите мониторинг приложения: метрики Prometheus, запросы PromQL, дашборды Grafana и алерты, по которым понятно, что делать. Итог — наблюдаемый сервис и разбор учебного инцидента.