Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. PromQL для начинающих: запросы к метрикам
promql_basics

PromQL для начинающих: запросы к метрикам

Основы языка запросов PromQL, селекторы, агрегации и базовые функции

PromQL для начинающих: запросы к метрикам

«Данные без запросов — как библиотека без каталога»

#Что такое PromQL

PromQL (Prometheus Query Language) — это язык запросов к данным Prometheus.

Если Prometheus — это база данных временных рядов, то PromQL — это SQL для этой базы. Но с важными отличиями:

  • PromQL специализирован для временных рядов
  • Нет JOIN, нет группировок в традиционном понимании
  • Встроенные функции для работы со временем (rate, histogram_quantile, predict_linear)

Зачем учить PromQL:

  • Grafana использует PromQL для построения графиков
  • Алерты в Prometheus пишутся на PromQL
  • Без PromQL вы не сможете извлечь пользу из собранных метрик

#Типы запросов

PromQL поддерживает два типа запросов:

#Instant Vector (Мгновенный вектор)

Возвращает последнее значение каждой метрики.

# Последнее значение использования памяти node_memory_MemAvailable_bytes

Результат: набор пар (лейблы, значение) на текущий момент времени.

Используется для:

  • Текущих дашбордов (что происходит прямо сейчас)
  • Алертинга (срабатывает при текущем условии)

#Range Vector (Диапазонный вектор)

Возвращает все значения за период времени.

# Все значения за последние 5 минут node_memory_MemAvailable_bytes[5m]

Результат: для каждой метрики — массив значений с временными метками.

Используется:

  • Как аргумент для функций (rate, irate, avg_over_time)
  • Для анализа трендов

Важно: сам по себе 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 если ложно

#Функции работы с Counter

#rate()

rate() — самая важная функция для работы с counter.

rate(http_requests_total[5m])

Что делает:

  • Берёт range vector за 5 минут
  • Вычисляет скорость изменения (единиц в секунду)
  • Экстраполирует на полный интервал

Зачем: counter растёт бесконечно. rate() превращает его в полезную метрику — запросы в секунду.

Важные детали:

  • Всегда используйте положительное окно (1m, 5m, 15m)
  • Окно должно быть больше scrape_interval (минимум 2x)
  • rate() автоматически обрабатывает сброс counter в 0 (после перезапуска)

#irate()

irate() — как rate(), но использует только последние две точки.

irate(http_requests_total[5m])

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

  • Для быстро меняющихся метрик
  • Когда важна реакция на резкие скачки

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

  • Для алертинга (irate() слишком чувствительна к шуму)
  • Когда данные приходят с задержкой

Рекомендация: в 95% случаев используйте rate(). irate() — для специфичных кейсов.

#increase()

increase() — показывает абсолютный прирост counter за период.

increase(http_requests_total[1h])

Что делает: возвращает, насколько вырос counter за последний час.

Зачем: для отчётов («сколько запросов обработано за час/день»).


#Функции работы с Gauge

#avg_over_time(), max_over_time(), min_over_time()

Агрегируют значения за период:

# Средняя температура за час 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() — вычисляет производную (тренд).

# Тренд использования диска (байт в секунду) deriv(node_disk_Used_bytes[1h])

Зачем: понять, растёт метрика или убывает, и с какой скоростью.

Пример: если deriv() для свободного места на диске = -1000 байт/сек, диск заполняется со скоростью 1 КБ/сек.

#predict_linear()

predict_linear() — предсказывает значение через N секунд.

# Предсказание свободного места через 4 часа predict_linear(node_disk_Free_bytes[24h], 4*3600)

Зачем: для проактивного алертинга («через 4 часа закончится место»).


#Агрегации

Агрегации объединяют несколько рядов в один.

#sum()

# Сумма запросов по всем методам sum(http_requests_total) # Сумма с группировкой (by) sum by (path) (http_requests_total) # Сумма без группировки (without) sum without (instance) (http_requests_total)

by — группируем по указанным лейблам. without — агрегируем по всем лейблам, кроме указанных.

#avg(), min(), max()

# Средняя загрузка CPU по всем ядрам avg(node_cpu_usage_percent) # Максимальная память среди всех серверов max(node_memory_Used_bytes) # Минимальное свободное место min(node_disk_Free_bytes)

#count()

# Количество работающих инстансов count(up == 1) # Количество метрик с errors > 0 count(http_errors_total > 0)

#topk(), bottomk()

# Топ-5 самых загруженных серверов topk(5, node_cpu_usage_percent) # 3 сервера с наименьшим использованием памяти bottomk(3, node_memory_Used_percent)

#Histogram и перцентили

Для работы с histogram используется histogram_quantile().

#Расчёт перцентиля

# 95-й перцентиль времени ответа histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

Как работает:

  1. rate(..._bucket[5m]) — скорость попадания в каждый бакет
  2. histogram_quantile(0.95, ...) — вычисляет 95-й перцентиль

Важно: первый аргумент — квантиль от 0 до 1 (0.95 = 95-й перцентиль).

#Среднее время ответа

# Среднее время ответа rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

Логика: сумма всех времён / количество запросов = среднее время.


#Практические примеры

#Пример 1: Процент использования CPU

# Для одного ядра 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 — конвертируем в процент загрузки

#Пример 2: Процент доступной памяти

node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100

#Пример 3: Error rate в процентах

# Процент ошибок (5xx) sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100

#Пример 4: Uptime сервиса

# Процент времени доступности (up = 1 когда доступен) avg_over_time(up[5m]) * 100

Объяснение: up принимает значения 1 (доступен) или 0 (недоступен). Среднее за 5 минут = процент времени доступности.

#Пример 5: Время до заполнения диска

# Секунд до заполнения (отрицательное значение = время до полного заполнения) (node_disk_size_bytes - node_disk_free_bytes) / -deriv(node_disk_free_bytes[24h])

#Отладка запросов

#Шаг 1: Проверьте существование метрики

# Покажет все ряды с этой метрикой http_requests_total

#Шаг 2: Посмотрите лейблы

В Prometheus UI кликните на метрику — увидите все комбинации лейблов.

#Шаг 3: Упростите запрос

Если сложный запрос не работает, упростите:

  • Уберите агрегации
  • Уберите функции
  • Проверьте базовый селектор

#Шаг 4: Используйте табличный вид

В Grafana переключитесь с графика на таблицу (Table) — увидите сырые значения.


#Распространённые ошибки

#Ошибка 1: rate() без range vector

# НЕПРАВИЛЬНО rate(http_requests_total) # ПРАВИЛЬНО rate(http_requests_total[5m])

rate() требует range vector — укажите окно в квадратных скобках.

#Ошибка 2: Слишком маленькое окно

# ПЛОХО: окно меньше интервала скрапинга rate(http_requests_total[10s]) # Если scrape_interval = 15s # ХОРОШО rate(http_requests_total[1m])

Окно должно быть минимум в 2-3 раза больше scrape_interval.

#Ошибка 3: Неправильная агрегация

# НЕПРАВИЛЬНО: суммируем уже агрегированные данные sum(rate(http_requests_total[5m])) / count(http_requests_total) # ПРАВИЛЬНО: сначала суммируем, потом делим sum(rate(http_requests_total[5m])) / sum(rate(http_requests_total_count[5m]))

Далее: Инструментирование приложений: первые метрики