Модуль 2 · как работает prometheus · сбор метрик
Глава 2.7
Формат YAML
и ряд up
Короткая глава-справка о двух вещах, которые встречались во всём модуле. Первая — формат файла prometheus.yml: как он устроен и какие ошибки в нём делают чаще всего. Вторая — ряд up: откуда он берётся, что означает и как им пользоваться в запросах.
- Категория
- Справка
- Уровень
- Начальный
- Опирается на
- Главы 2.2 и 2.4
- Результат
- Читать и править prometheus.yml, проверять доступность по up
§1Что такое YAML
Настройки Prometheus записаны в файле prometheus.yml. Окончание .yml (или .yaml) означает формат YAML — текстовый способ записать вложенные настройки так, чтобы их читал и человек, и программа. В том же формате написаны compose.yaml для Docker Compose и настройки Grafana на стенде.
Устройство YAML похоже на оглавление книги. В оглавлении вложенность показана отступом: глава стоит у края, её разделы сдвинуты вправо, подразделы — ещё правее. Номера и рамки не нужны, всё видно по сдвигу. В YAML вложенность тоже задаётся только отступом, поэтому от отступа зависит смысл строки.
Ниже рабочий файл стенда, и каждый уровень в нём сдвинут на два пробела.
global: # уровень 1: раздел scrape_interval: 15s # уровень 2: настройка внутри раздела scrape_timeout: 10s scrape_configs: # уровень 1: список заданий - job_name: api # «-» начинает элемент списка: одно задание static_configs: # настройка этого задания - targets: ['api:8000'] # список адресов в одну строку
Если читать файл как оглавление, получается: есть раздел общих настроек с двумя значениями и раздел заданий. В разделе заданий одно задание с именем api, у него список статических целей, а в нём один адрес.
Чтобы так читать любой файл, достаточно пяти правил.
§2Пять правил записи
Пара «ключ: значение». Название настройки, двоеточие, пробел, значение: scrape_interval: 15s. Пробел после двоеточия обязателен.
Вложенность — отступом из пробелов. Всё, что сдвинуто правее ключа, принадлежит ему. Отступы делают только пробелами; символ табуляции YAML запрещает. В Prometheus принято сдвигать каждый уровень на два пробела, и сдвигать нужно одинаково: элементы одного уровня стоят строго друг под другом.
Список. Каждый элемент начинается с дефиса и пробела. Короткий список можно записать в одну строку в квадратных скобках. Две записи ниже означают одно и то же.
- targets: ['api:8000', 'api2:8000'] - targets: - 'api:8000' - 'api2:8000'
Строки можно не брать в кавычки. job_name: api и job_name: 'api' равноценны. Кавычки нужны, когда в значении есть символы, важные для YAML, например двоеточие с пробелом или # в начале.
Комментарий начинается с #. Всё правее этого знака до конца строки программа пропускает.
Длительности в Prometheus
Это правило относится к самому Prometheus. Время в его настройках записывают числом с единицей без пробела: 500ms, 15s, 1m, 2h, 1d. Число без единицы, например 15, Prometheus не принимает.
Ошибки в этих правилах встречаются часто. Следующий раздел показывает, как они выглядят в проверке.
§3Частые ошибки и что пишет promtool
Перед перезагрузкой настроек файл проверяют программой promtool, которая входит в образ Prometheus. Она останавливается на первой ошибке и называет номер строки. Каждый файл из таблицы проверен на стенде, Prometheus 3.5.0.
docker compose exec prometheus promtool check config /etc/prometheus/prometheus.yml
| Что написано в файле | Что ответил promtool | Что исправить |
|---|---|---|
| Отступ сделан табуляцией | line 2: found character that cannot start any token | Заменить табуляцию пробелами |
scrape_interval:15s — нет пробела после двоеточия | line 2: cannot unmarshal !!str `scrape_...` into config.plain | Поставить пробел после двоеточия |
scrape_intervall: 15s — опечатка в имени | line 2: field scrape_intervall not found in type config.plain | Сверить имя с документацией |
scrape_interval: 15 — нет единицы | not a valid duration string: "15" | Записать 15s |
targets: api:8000 — строка вместо списка | line 4: cannot unmarshal !!str `api:8000` into []string | Записать ['api:8000'] |
labels сдвинут на уровень задания вместо уровня target | line 5: field labels not found in type config.ScrapeConfig | Сдвинуть labels под targets |
Последняя строка таблицы показывает, что отступ меняет смысл. Блок labels из главы 2.2 принадлежит одной группе адресов и стоит на одном уровне с targets. Если сдвинуть его на два пробела левее, он попадает внутрь задания, где такой настройки нет.
static_configs: - targets: ['api:8000'] labels: # под targets: те же 8 пробелов, что и у слова targets env: dev
Сообщения not found in type читают целиком: в конце указан раздел, в котором Prometheus искал настройку. config.plain — раздел global, config.ScrapeConfig — одно задание.
Файл настроек задаёт, что опрашивать. Как прошёл каждый опрос, Prometheus записывает в ряд up.
§4Ряд up
Ряд up встречался почти в каждой главе модуля. Здесь сведения о нём собраны вместе.
Его можно сравнить с отметкой в журнале обхода. Контролёр записывает не только показания, но и то, удалось ли попасть в квартиру: «попал» или «не открыли». По этим отметкам видно, какие квартиры давно недоступны, даже если показаний нет.
upслужебный ряд · один на каждый target
Ряд, который Prometheus записывает сам после каждого scrape каждого target: 1 — scrape успешный, 0 — неуспешный. У ряда только метки target: job, instance и метки из labels.
У этого определения три следствия, и все они проверены на стенде модуля.
Приложение не может повлиять на up. Ряда up нет в ответе /metrics: его создаёт Prometheus по результату опроса. Поэтому up показывает доступность, даже когда приложение упало и не может ничего сообщить.
up записывается и во время сбоя. Ряды приложения при неуспешном scrape прерываются, а up продолжает писаться нулями. На стенде приложение остановили в 13:22:41, и картина была такой:
up = 1 не означает, что сервис работает правильно. Это значит только, что страница /metrics ответила без ошибок. Рабочий маршрут при этом может возвращать ошибку 500 в каждом запросе, и это видно уже по метрикам приложения. Ряд up отвечает на вопрос «получается ли собирать данные». Работает ли сервис правильно, по нему не узнать.
Для Pushgateway из главы 2.5 ряд up относится к самому Pushgateway. О задачах, которые в него отправляют данные, он ничего не говорит.
Ряд up — обычный временной ряд, и с ним работают обычные запросы.
§5Запросы с up
Четыре запроса покрывают почти все случаи. Их вводят на вкладке Query веб-интерфейса Prometheus.
| Запрос | Что возвращает | Когда нужен |
|---|---|---|
up | По одному ряду на каждый target со значением 1 или 0 | Проверить все цели сразу |
up{job="api"} | Только target задания api | Проверить один сервис |
up == 0 | Только недоступные target; если все доступны — пустой результат | Найти, что сломалось; основа правила оповещения |
avg_over_time(up{job="api"}[1h]) | Среднее значение up за час | Доля успешных опросов: 0,95 — 5% опросов за час не удались |
Запрос up == 0 отличается от остальных: он оставляет только ряды со значением 0. Поэтому пустой результат здесь означает, что все target доступны. На нём строят первое правило оповещения почти в любой системе: «если up == 0 дольше двух минут — сообщить дежурному». Без такого правила сломанный сбор выглядит так же, как сервис без запросов: графики пустеют.
Запрос с avg_over_time переводит ряд нулей и единиц в долю. За час при интервале 15 секунд набирается 240 отсчётов. Если 12 из них нули, среднее равно 228 / 240 = 0,95.