Про метрики, а именно - вычисление всяких SLA в Grafana + Prometheus
Бывает такая веселая задача, как посчитать SLA какого-нибудь сервиса. Это весьма легко для метрик, которые возвращают бинарное значение, 0 или 1, скажем какой-нибудь условный site_probe. Берем, суммируем за период, делим на количество записей и получаем наш SLA. Выглядеть это будет так:
sum_over_time(site_probe{site="example.local"}}[$__range]) / count_over_time(site_probe{site="example.local"}[$__range]) * 100
Один минус - при этом если по какой-то причине на какому-то отрезке времени метрики не было, то на SLA это никак не отобразиться. Упал экспортер? Все ок. Упал мониторинг? Все ок. Упало все, сервера сгорели, а админ повесился? Все ок (а на деле вообще же не ок). Это можно обойти костылем - зная частоту забора метрик, мы можем просто использовать не количество записей, а разделить период на интервал измерений, получив при этом эталонное число сколько должно быть записей. То есть при scrape_interval = 10s, оно будет выглядеть где-то вот так:
sum_over_time(site_probe{site="example.local"}[$__range]) * 10 / $__range_s * 100
На выходе мы получим, какой процент времени наша метрика site_probe для указанного сайта возвращала 1 (“все ок”) за выбранный нами период времени, и если метрик за какой-то кусок этого периода не было, то считаться это будет, что метрика возвращала 0.
Плюс - даже если легло все, то после восстановления это падение будет видно в статистике. Минус совершенно такой же, как и плюс - упал мониторинг или даже один экспортер, а для метрик выходит, что лежало все. В силу того, что я предпочитаю пессимистично смотреть на работу систем и этим мотивировать на лучшую их отладку - я выбираю этот путь. Можно еще дублировать графики, имея две метрики - на основе количества элементов и на основе эталонного их количества. И уже в голове делать поправки, зная о истории происшествий. И конечно для вычисления KPI и других важных вещей такое не подойдет, но просто для оценки молодцы ли мы и все ли у нас, технарей, хорошо - более чем.
Другой кейс, когда статус системы это не бинарная метрика “ок/не ок”, а анализ показателей. Скажем разница между какими-то двумя метриками не более определенной, или какая-то метрика прирастает быстрее другой. Здесь наш SLA вычислять напрямую нет возможности, так как Prometheus все же не космический корабль и работает с временными рядами, но не с вычислениями их на лету в каждый момент времени. То есть имея условное выражение metric1 / metric2 >= 1, вы будете иметь его значение здесь и сейчас, или в выбранный один момент времени, но вот анализировать в ряде моментов времени - уже нет. Но и здесь есть решение и оно даже не костыль - создаем правило записи (recording rules) на основе нашего выражения PromQL, возвращаем там бинарное значение, и из этого создаем новую метрику с тем же бинарным значением “ок/не ок”. И вот эту метрику Prometheus уже хранит как временной ряд и ее можно анализировать во времени. Для нас это будет выглядеть в конфиге приблизительно вот так:
groups:
- name: example
rules:
- record: sla_example_metric
expr: (metric1 / metric2) >= bool 1
Теперь у нас есть метрика sla_example_metric которая возвращает 1, если в этот момент времени выражение metric1 / metric2 было больше или равно 1. И 0 - если меньше. И это тот самый временной ряд, отображающий нужные нам данные и мы может уже его анализировать во времени
-— И да, не надо путать в Grafana переменные $_interval и $_range, не так давно с этим столкнулся, смотря на чужое решение. Первая берет временной отрезок, что вы выбрали, а еще разрешение экрана и строится на основе них ((from - to) / resolution), по сути это масштаб графика. А вот $__range - это как раз временной отрезок (to - from), что вы выбрали.