Суть Читай реальные PromQL recording rules, MWMBR-выражения, latency-bucket SLI и Sloth YAML, предсказывай поведение и выбирай фикс с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min
Баги SLO прячутся в PromQL, а не в слайдах. Неверный bucket, захардкоженный budget rate, NaN-знаменатель — каждый тихо портит бюджет и алерт. Прочитай правило и выбери фикс, который senior сделает первым.
Цель
Потренируй чтение артефактов, из которых реально собран SLO: recording rules, burn-rate-выражения алертов, latency-bucket SLI и YAML, из которого платформа их генерирует — и находи дефект.
Сниппет 1 — page-правило по burn rate
# 99.9% SLO. Задумано: пейджить, когда burn за 1h И за 5m оба превышают 14.4x.alert: SLOAvailabilityBurnFastexpr: | (1 - job:slo_availability:ratio_rate1h) > (14.4 * 0.001) or (1 - job:slo_availability:ratio_rate5m) > (14.4 * 0.001)labels: severity: page
Викторина
Completed
Автор хотел MWMBR-поведение. В чём баг и что он вызывает в проде?
Heads-up 0.001 — это ровно budget rate для 99.9% SLO (1 − 0.999). Дефект — оператор OR: MWMBR требует AND, чтобы длинное окно подтверждало тяжесть, а короткое — что burn всё ещё идёт.
Heads-up В каноническом MWMBR короткое окно использует тот же порог burn, что и парное длинное — это гейт «всё ещё происходит?», а не другая severity. Настоящий баг — OR vs AND.
Heads-up MWMBR определяется через AND между длинным и коротким окном. OR — это провальный Approach 4 из SRE workbook именно потому, что совмещает шум короткого окна с медленным сбросом длинного.
Сниппет 2 — latency SLI
# SLO-цель по латентности: 99% запросов под 200ms.# Bucket-границы заданы как le: 0.1, 0.25, 0.5, 1, 2.5latency_sli = sum(rate(http_request_duration_seconds_bucket{le="0.25"}[1h])) / sum(rate(http_request_duration_seconds_count[1h]))
Викторина
Completed
Порог SLO — 200ms, но ближайший bucket — le=0.25. Что не так и какой фикс?
Heads-up Latency SLO — это отношение счётчиков (fast / total), а не оценка перцентиля. histogram_quantile интерполирует внутри bucket и вносит ошибку, портящую бюджет. Фикс — bucket-граница ровно на пороге, затем прямой подсчёт.
Heads-up Диапазон влияет на сглаживание, а не на корректность. Настоящий дефект — отсутствие bucket на 0.2s, что вынуждает SLI использовать границу 0.25 и классифицировать запросы 200-250ms как «быстрые».
Heads-up «Достаточно близко» тихо смещает бюджет: каждый запрос между 200ms и 250ms засчитывается как хороший, хотя должен жечь бюджет. Порог SLO и bucket-граница гистограммы должны совпадать точно.
Сниппет 3 — NaN-знаменатель
# Recording rule для низкотрафикового внутреннего сервиса.record: job:slo_availability:ratio_rate5mexpr: | sum(rate(http_requests_total{status!~"5..",job="reports"}[5m])) / sum(rate(http_requests_total{job="reports"}[5m]))# В тихое окно эта серия вычисляется в NaN.
Викторина
Completed
Отношение уходит в NaN в тихие периоды на этом низкотрафиковом сервисе. Что это значит для SLO и какой senior-фикс?
Heads-up NaN — это не 100%, а 0/0 из-за отсутствующего знаменателя. Алерт вычисляется против NaN и остаётся в неопределённом состоянии, что хуже ложного отрицания, потому что никто не замечает.
Heads-up Цель не связана с нулевым знаменателем. Структурный фикс для низкотрафикового NaN — synthetic probes (стабилизировать знаменатель), агрегация по родственным сервисам или более длинное окно оценки — плюс отдельный no-traffic алерт.
Heads-up increase() за окно без трафика всё равно даёт ноль, поэтому отношение всё ещё 0/0. Корневая причина — отсутствие трафика в знаменателе, а не выбор rate vs increase.
Коллега говорит, что это рискованно, ведь надо вручную держать шесть recording rules и три MWMBR-алерта на сервис. Почему здесь этот аргумент неверен?
Heads-up Пересчёт — это ровно то, что делает генератор: он выводит budget rate под цель (здесь 0.005) и эмитит корректные выражения алертов. Именно рукопись путает 0.005; Sloth — нет.
Heads-up Рукописный PromQL по многим сервисам — задокументированный источник тихих багов SLO (неверное окно, неверный budget rate). Декларативная генерация даёт аудируемость через YAML плюс консистентный, корректный вывод.
Heads-up Sloth эмитит Prometheus recording rules И MWMBR alert rules (плюс опционально Grafana-дашборды) из декларации. Генерируется весь стек алертинга, а не только дашборды.
Итог
Каждый дефект SLO читается в правилах: MWMBR нужен and между длинным и коротким окном (OR — это провальный Approach 4); latency SLI нужен bucket гистограммы ровно на пороге SLO, иначе он тихо просчитывается и смещает бюджет; нулевой знаменатель на низкотрафиковых сервисах даёт NaN, который не срабатывает и не сбрасывается, поэтому добавь synthetic probes плюс no-traffic алерт; а платформа вроде Sloth генерирует все шесть recording rules и три MWMBR-алерта — с budget rate, корректно пересчитанным под цель — из одного YAML, и именно поэтому рукописный PromQL — источник багов.