Prometheus метрики и функции

Prometheus метрики и функции

Что такое Prometheus

Prometheus — это система мониторинга, сбора и хранения метрик с открытым исходным кодом, разработанная для обработки и хранения временных рядов данных. Она была создана в 2012 году в компании SoundCloud. Основная особенность Prometheus — сбор метрик через HTTP-запросы к целевым объектам (так называемый pull-метод), которые возвращают данные в формате, удобном для анализа.

Prometheus хранит данные как временные ряды, что позволяет анализировать изменения состояния системы или приложения во времени. Например, можно отслеживать загрузку CPU, использование памяти, количество запросов и другие параметры. В системе используется язык запросов PromQL, который позволяет создавать сложные запросы для анализа и визуализации метрик.

Состоит из 4 ключевых компонентов:

  1. TSDB – база данных временных рядов, которая используется для хранения метрик в виде временных рядов. Каждый временной ряд представлен как набор пар (timestamp, value), где timestamp — это временная метка, а value — значение метрики на данный момент времени.
  2. Retrieval worker, который отвечает за сбор метрик. Prometheus использует механизм pull для получения данных, при котором через определенные интервалы времени Prometheus отправляет запросы к конечным точкам (target) метрик для получения актуальных значений. Retrieval worker выполняет эти запросы и получает метрики от целевых target.
  3. HTTP server, который предоставляет API для выполнения запросов к метрикам, сохранённым в TSDB. Через HTTP сервер можно запрашивать метрики за определённый период, а также применять функции агрегации, фильтрации и преобразования данных.
  4. Конфигурационные файлы, которые содержат настройки, такие как интервалы сбора метрик, статические и динамические источники данных, параметры алертов и другие аспекты работы системы

Виды метрик в Prometheus

В Prometheus существует четыре базовых типа метрик, каждый из которых решает свою задачу и критичен для корректного мониторинга.
Prometheus пример метрики

Пример метрики:

http_requests_total{method="POST",code="200"} 1027 1395066363000

Разбор:

  • Название метрики: http_requests_total — это имя самой метрики, которое указывает, что измеряется (здесь — общее количество HTTP-запросов).
  • Лейблы (labels): {method=“POST”,code=“200”} — набор пар ключ-значение, которые добавляют контекст к метрике (например, метод запроса и код ответа).
  • Значение (value): 1027 — текущее числовое значение метрики.
  • Временная метка (timestamp): 1395066363000 — время измерения в Unix timestamp (необязательно, часто отсутствует).

Counter / Счетчик

Монотонно возрастающее число. Может только увеличиваться или сбрасываться в ноль при перезапуске. Подходит для учета событий, которые могут только увеличиваться: количество обработанных запросов, ошибок, сбоев.

Примеры:

http_requests_total — общее количество HTTP-запросов  
errors_total — общее количество ошибок

Как использовать:

Почти никогда не смотрят на абсолютное значение. Используют с функциями, чтобы посмотреть скорость роста за период:

  • rate() — вычисляет среднюю скорость изменения счетчика в секунду за указанный промежуток времени
  • increase() — вычисляет прирост или уменьшение значения метрики за заданный временной интервал

Запрос:

rate(http_requests_total[5m]) — "сколько запросов в секунду в среднем было за последние 5 минут".

Gauge / Измеритель

Подходит для отслеживания мгновенных значений величин, которые могут возрастать и уменьшаться: загрузка CPU, температура, количество активных соединений, длина очереди сообщений.

Примеры:

memory_usage_bytes — текущее потребление памяти  
cpu_usage_percent — текущая загрузка CPU  
disk_free_bytes — свободное место на диске  
active_connections — текущее количество активных соединений

Как использовать:

Cмотрят на абсолютное значение, строят графики. Часто используют функции max(), min(), avg(). Поскольку эта метрика не монотонная, для нее не сработают некоторые математические функции, то есть она чуть больше ограничена в использовании.

Histogram / Гистограмма

Собирает значения по диапазонам (“бакетам”), позволяя увидеть распределение (например, сколько запросов было обслужено за 10 мс, 50 мс, 1 сек). Используется для анализа распределения задержек и размеров.

Примеры:

http_request_duration_seconds_bucket{le="0.1"} — количество запросов, выполненных быстрее 0.1 секунды  
http_request_duration_seconds_bucket{le="0.5"} — быстрее 0.5 секунды  
... и т.д., пока последняя корзина le="+Inf" не будет равна общему количеству запросов (_count).

Как использовать:

Позволяет отвечать на вопросы: “Какой процент запросов обслуживается дольше 500мс?” или “Какое 95-й перцентиль времени ответа?”. Используется функция histogram_quantile().

Запрос:

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) — "95% запросов были выполнены быстрее, чем X секунд".

Summary / Сводка

Похож на Histogram, но вычисляет процентили на стороне приложения (клиента), а не в Prometheus.

Когда использовать:

Редко. Histogram обычно предпочтительнее, так как процентили можно агрегировать на стороне Prometheus, а в Summary — нет.

Популярные подходы

  • RED (Rate, Errors, Duration): частота запросов, количество ошибок, продолжительность операций — для API и сервисов, доступных снаружи.
  • USE (Utilization, Saturation, Errors): для инфраструктуры и оборудования, фокус на загрузку, насыщение очередей и количество ошибок.
  • 4 Golden Signals: latency, traffic, errors, saturation — универсальная абстракция для большинства сервисов.

Как не наделать ошибок?

  1. Не собирайте все подряд.
    Каждая метрика занимает место на диске, не пытайтесь визуализировать всё подряд.
  2. Неправильный выбор типа метрики
    1. Использование Counter вместо Gauge (или наоборот): приводит к ложным данным при сбросах, неправильно аггрегируется среднее.
    2. Использование Summary, когда нужен Histogram (или наоборот): summary неагрегируем по нескольким инстансам, histogram — да.
    3. Используйте правильные функции:
      1. Для Counter: rate(), increase().
      2. Для Histogram: histogram_quantile().
      3. Не используйте rate() для Gauge.
  3. Используйте лейблы с умом.
    1. Логически группируйте иерархию метрик: один namespace для всего сервиса; request_, queue_, db_, memory_ — для каждого обработчика/ресурса.
    2. Слишком много label-ов (особенно с уникальными значениями: user_id, uri, session и пр.) ведут к «взрыву» числа временных рядов, что тормозит Prometheus и увеличивает потребление ресурсов.
      • Плохо: http_requests_total{user_id=“12345”} (тысячи уникальных значений)
      • Хорошо: http_requests_total{endpoint="/api/v1/users", status=“500”} (ограниченное количество значений).
  4. Отсутствие явных unit и семантики
    1. Имя метрики и единица измерения должны быть ясны: request_duration_seconds, queue_size, и пр.
    2. Лейблы units — антипаттерн, нужно единообразие в наименовании метрик.
  5. Неоптимальная частота сбора
    Слишком частый опрос экспортёра: лишняя нагрузка на сервер и сеть, возможная потеря значения.
  6. Настройте алерты осмысленно. Не алармьте на все подряд. Алерты должны срабатывать, когда требуется человеческое вмешательство. Используйте for в алертах
    1. Плохое правило: cpu_usage > 80% (CPU может кратковременно подскакивать — это норма).
    2. Хорошее правило: avg_over_time(cpu_usage[5m]) > 80% — высокая загрузка в течение 5 минут.
    3. Пример для For: expr: up == 0, for: 2m — алерт сработает, только если сервис не будет доступен 2 минуты.

Функции в PromQL

Prometheus использует свой язык запросов PromQL (Prometheus Query Language) для анализа и агрегации метрик. Функции делятся на две категории в зависимости от типа вектора, с которым они работают.

  1. Instant Vector — значение метрики в конкретный момент времени. Используется для точечных снимков данных.​
  2. Range Vector — набор значений метрики за диапазон времени. Используется для анализа тренда. Синтаксис: metric_name[5m] (последние 5 минут).

Наиболее часто используемые функции

Prometheus функции в PromQL

Функции для Counter метрик

  1. rate() — вычисляет среднюю скорость изменения счетчика в секунду за указанный промежуток времени.

    Формула:

    rate(counter[5m]) = (последнее_значение - первое_значение) / (время_в_секундах)
    

    Примеры:

    * rate(http_requests_total[5m]) — запросов в секунду за 5 минут  
    * rate(errors_total[1m]) — ошибок в секунду (за минуту)  
    * sum(rate(requests_total{job="api"}[5m])) — все запросы к API в RPS
    

    Важно:

    Диапазон должен быть больше интервала скрэпинга Prometheus. Если скрэпите каждые 15 сек, то минимум [1m].

  2. increase() — вычисляет прирост или уменьшение значения метрики за заданный временной интервал

    Примеры:

    * increase(errors_total[1h]) — сколько всего ошибок за час  
    * increase(disk_bytes_written[24h]) — сколько гигабайт записано за сутки
    

rate() vs increase():

* rate() → скорость изменения (per-second average)  
* increase() → сумма изменений (total change)

Функции агрегации (Aggregation Operators)

  1. sum() — группирует метрики и суммирует значения. Работает как GROUP BY в SQL.​

    Примеры:

    * sum by (job)(requests_total) — все запросы для каждого сервиса  
    * sum(rate(requests_total[5m])) — суммарный RPS  
    * sum without (instance)(memory_bytes) — память без разбивки по инстансам​
    
  2. avg() — вычисляет среднее арифметическое по label-ам.

    Примеры:

    * avg by (instance)(cpu_usage_percent) — средняя загрузка CPU на каждом сервере  
    * avg(response_time_ms) — среднее время ответа​  
    
  3. max()/min() — находит экстремальные значения.​

    Примеры:

    * max by (pod)(memory_usage_bytes) — самый «прожорливый» pod  
    * min by (region)(latency_ms) — регион с лучшей latency  
    * max(disk_usage_percent) — самый забитый диск
    
  4. count() — показывает сколько временных рядов соответствует условию.​

    Примеры:

    * count by (job)(up==1) — сколько здоровых инстансов в каждом сервисе  
    * count(node_exporter_build_info) — сколько узлов в кластере
    

Функции для Histogram метрик

  1. histogram_quantile() — вычисляет квантили (p50, p95, p99) из гистограммы. Критична для SLA мониторинга.​

    Синтаксис:

    * histogram_quantile(квантиль, rate(метрика_bucket[диапазон]))
    

    Примеры:

    * histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) — 95-й перцентиль time response за 5 минут  
    * histogram_quantile(0.99, rate(db_query_duration_seconds_bucket[1h])) — p99 для БД запросов  
    * По service: histogram_quantile(0.95, sum by (le, service)(rate(request_duration_bucket[5m]))) — p95 для каждого сервиса​
    

    Важно:

    Бакеты должны быть накопительными. Используйте только с метриками типа _bucket.​

Функции для Gauge метрик

  1. delta() — показывает полное изменение значения.​

    Примеры:

    * delta(temperature_celsius[1h]) — на сколько изменилась температура за час  
    * delta(queue_depth[10m]) — прирост очереди за 10 минут  
    
  2. predict_linear() — экстраполирует линейный тренд в будущее. Полезна для прогноза срока полноты диска.​

    Примеры:

    * predict_linear(disk_free_bytes[1h], 3600) — будет ли диск свободен через час (по тренду за последний час)  
    * predict_linear(memory_usage[4h], 86400) — спрогнозировать память на завтра
    

Best Practices при использовании функций

  1. Выбирайте правильный диапазон:
    • [5m] для текущей нагрузки
    • [1h] для трендов
    • [24h] для долгосрочных изменений.​
  2. Обработка счётчиков:
    • Всегда используйте rate() для counter метрик, никогда не выводите их «в лоб».
  3. Агрегация по label-ам:
    • Группируйте через by (label) или without (label), это эффективнее, чем обработка на уровне дашборда.​
  4. Для SLA алертов:
    • Используйте histogram_quantile() + пороги, например: если p99 > 1 сек → alert.​
  5. Комбинируйте функции:
    • sum(rate(…)) by (service) — суммируйте rate результаты по сервисам.​
  6. Помните про extrapolation (угадывание/добавление значений, которых нет в реальных данных):
    • Функции rate() и increase() при необходимости “добавляют” значения, это может дать неожиданные результаты на краях временного диапазона.

Полезные ссылки: