Мы у себя давно используем SLI/SLO и считаем их по метрикам VictoriaMetrics. Запросы для формулы пишутся на PromQL/MetricsQL.
Все было прекрасно пока мы использовали простые SLI вида
SLI=sum(increase(good_events))/sum(increase(total_events))Потому появились более сложные составные, где пришлось учитывать, что один компонент может и не вернуть данных. А в PromQL/MetricsQL
ничего + число = ничего. Чтобы такое обходить приходиться добавлять в выражение часть с or on() vector(0) - вернуть ноль вместо "ничего". И вот мы так и делали:SLI=(
sum(increase(a_good_events) or on() vector(0)) + sum(increase(b_good_events) or on() vector(0))
)
/ (
sum(increase(a_total_events) or on() vector(0)) + sum(increase(b_total_events) or on() vector(0))
)Но вот при создании очередного SLI, что то пошло не так, видимо копипаста напакастила, и выражение стало чуть другим:
SLI=(
sum(increase(a_good_events)) or on() vector(0) + sum(increase(b_good_events)) or on() vector(0)
)
/ (
sum(increase(a_total_events)) or on() vector(0) + sum(increase(b_total_events)) or on() vector(0)
)Кажется это тоже самое, но это не так. Приоритет операций тут не такой, как привык видеть мозг.
Обманываешься. Ожидаешь, что
sum(increase(a_good_events)) or on() vector(0) + sum(increase(b_good_events)) or on() vector(0) равносильно
(
sum(increase(a_good_events)) or on() vector(0) ) + ( sum(increase(b_good_events)) or on() vector(0) ), но на самом деле это вычисляется иначе, если расставить скобки (все что в них точно вычисляется в первую очередь), то аналог будет такой:(
sum( increase(a_good_events) ) + sum( increase(b_good_events) ) ) or on() vector(0)Как это проявляется в поведении? Да просто вы получаете неправильные данные SLI. В сырых данных может оказаться, что у вас good событий больше, чем total! Это происходит, потому что, если один из
sum(increase(...)) пуст, то весь запрос вернёт 0, даже если другой sum(increase(...)) содержит данные. 🫴🏻 Вот такие грабельки.
🔎 А какие грабли грабли запомнились вам при работе с метриками?
#грабли #promql #slo