Основы языка запросов PromQL, селекторы, агрегации и базовые функции
«Данные без запросов — как библиотека без каталога»
PromQL (Prometheus Query Language) — это язык запросов к данным Prometheus.
Если Prometheus — это база данных временных рядов, то PromQL — это SQL для этой базы. Но с важными отличиями:
Зачем учить PromQL:
PromQL поддерживает два типа запросов:
Возвращает последнее значение каждой метрики.
# Последнее значение использования памяти
node_memory_MemAvailable_bytesРезультат: набор пар (лейблы, значение) на текущий момент времени.
Используется для:
Возвращает все значения за период времени.
# Все значения за последние 5 минут
node_memory_MemAvailable_bytes[5m]Результат: для каждой метрики — массив значений с временными метками.
Используется:
Важно: сам по себе range vector нельзя отобразить на графике. Его используют внутри функций.
Выбирает все временные ряды с данным именем:
http_requests_totalВернёт все ряды с метрикой http_requests_total, независимо от лейблов.
Фильтрует по значениям лейблов:
# Точное совпадение
http_requests_total{method="GET", status="200"}
# Неравенство
http_requests_total{status!="500"}
# Регулярное выражение (совпадение)
http_requests_total{path=~"/api/.*"}
# Регулярное выражение (несовпадение)
http_requests_total{path!~"/health.*"}Операторы:
= — точное совпадение!= — не равно=~ — совпадение с regex!~ — не совпадает с regexКомбинирование: несколько лейблов разделяются запятой (логическое И):
# method=GET И status=200
http_requests_total{method="GET", status="200"}# Сложение
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes # Использованная память
# Деление (процент использования)
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
# Умножение
rate(http_requests_total[5m]) * 60 # Запросов в минуту вместо секундВажно: операции применяются поэлементно. Prometheus сопоставляет ряды по лейблам.
Возвращают вектор с отфильтрованными элементами:
# Только где CPU > 80%
node_cpu_usage_percent > 80
# Равно (возвращает ряды где значение = 1)
up == 1
# Фильтрация с модификатором bool (возвращает 1/0 вместо фильтрации)
node_cpu_usage_percent > bool 80Модификатор bool:
bool: фильтрует ряды (возвращает только где условие истинно)bool: возвращает все ряды, но значение = 1 если истинно, 0 если ложноrate() — самая важная функция для работы с counter.
rate(http_requests_total[5m])Что делает:
Зачем: counter растёт бесконечно. rate() превращает его в полезную метрику — запросы в секунду.
Важные детали:
irate() — как rate(), но использует только последние две точки.
irate(http_requests_total[5m])Когда использовать:
Когда НЕ использовать:
Рекомендация: в 95% случаев используйте rate(). irate() — для специфичных кейсов.
increase() — показывает абсолютный прирост counter за период.
increase(http_requests_total[1h])Что делает: возвращает, насколько вырос counter за последний час.
Зачем: для отчётов («сколько запросов обработано за час/день»).
Агрегируют значения за период:
# Средняя температура за час
avg_over_time(node_cpu_temperature[1h])
# Максимальная память за день
max_over_time(node_memory_Used_bytes[24h])
# Минимальное свободное место за неделю
min_over_time(node_disk_Free_bytes[7d])deriv() — вычисляет производную (тренд).
# Тренд использования диска (байт в секунду)
deriv(node_disk_Used_bytes[1h])Зачем: понять, растёт метрика или убывает, и с какой скоростью.
Пример: если deriv() для свободного места на диске = -1000 байт/сек, диск заполняется со скоростью 1 КБ/сек.
predict_linear() — предсказывает значение через N секунд.
# Предсказание свободного места через 4 часа
predict_linear(node_disk_Free_bytes[24h], 4*3600)Зачем: для проактивного алертинга («через 4 часа закончится место»).
Агрегации объединяют несколько рядов в один.
# Сумма запросов по всем методам
sum(http_requests_total)
# Сумма с группировкой (by)
sum by (path) (http_requests_total)
# Сумма без группировки (without)
sum without (instance) (http_requests_total)by — группируем по указанным лейблам. without — агрегируем по всем лейблам, кроме указанных.
# Средняя загрузка CPU по всем ядрам
avg(node_cpu_usage_percent)
# Максимальная память среди всех серверов
max(node_memory_Used_bytes)
# Минимальное свободное место
min(node_disk_Free_bytes)# Количество работающих инстансов
count(up == 1)
# Количество метрик с errors > 0
count(http_errors_total > 0)# Топ-5 самых загруженных серверов
topk(5, node_cpu_usage_percent)
# 3 сервера с наименьшим использованием памяти
bottomk(3, node_memory_Used_percent)Для работы с histogram используется histogram_quantile().
# 95-й перцентиль времени ответа
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))Как работает:
rate(..._bucket[5m]) — скорость попадания в каждый бакетhistogram_quantile(0.95, ...) — вычисляет 95-й перцентильВажно: первый аргумент — квантиль от 0 до 1 (0.95 = 95-й перцентиль).
# Среднее время ответа
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])Логика: сумма всех времён / количество запросов = среднее время.
# Для одного ядра
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Для всех ядер (усреднённо)
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)Объяснение:
node_cpu_seconds_total{mode="idle"} — время в idle режиме (counter)rate()[5m] — превращаем в доли секунды в секунду100 - ... * 100 — конвертируем в процент загрузкиnode_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100# Процент ошибок (5xx)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
* 100# Процент времени доступности (up = 1 когда доступен)
avg_over_time(up[5m]) * 100Объяснение: up принимает значения 1 (доступен) или 0 (недоступен). Среднее за 5 минут = процент времени доступности.
# Секунд до заполнения (отрицательное значение = время до полного заполнения)
(node_disk_size_bytes - node_disk_free_bytes)
/
-deriv(node_disk_free_bytes[24h])# Покажет все ряды с этой метрикой
http_requests_totalВ Prometheus UI кликните на метрику — увидите все комбинации лейблов.
Если сложный запрос не работает, упростите:
В Grafana переключитесь с графика на таблицу (Table) — увидите сырые значения.
# НЕПРАВИЛЬНО
rate(http_requests_total)
# ПРАВИЛЬНО
rate(http_requests_total[5m])rate() требует range vector — укажите окно в квадратных скобках.
# ПЛОХО: окно меньше интервала скрапинга
rate(http_requests_total[10s]) # Если scrape_interval = 15s
# ХОРОШО
rate(http_requests_total[1m])Окно должно быть минимум в 2-3 раза больше scrape_interval.
# НЕПРАВИЛЬНО: суммируем уже агрегированные данные
sum(rate(http_requests_total[5m])) / count(http_requests_total)
# ПРАВИЛЬНО: сначала суммируем, потом делим
sum(rate(http_requests_total[5m])) / sum(rate(http_requests_total_count[5m]))=, !=, =~, !~.sum, avg, max, min, count, topk с by и without.Теперь вы умеете писать запросы. В следующей теме вы научитесь добавлять метрики в свои приложения — чтобы мониторить не только инфраструктуру, но и бизнес-логику.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.