Прогнозирующие функции триггеров
Обзор
Иногда появляются признаки надвигающейся проблемы. Эти признаки можно обнаружить, чтобы заранее принять меры для предотвращения проблемы или хотя бы минимизации ее последствий.
В Zabbix есть инструменты для прогнозирования будущего поведения контролируемой системы на основе исторических данных. Эти инструменты реализованы с помощью прогностических функций триггеров.
Функции
Перед настройкой триггера необходимо определить, что считается проблемным состоянием и сколько времени требуется для принятия мер. Затем есть два способа настроить триггер, сигнализирующий о потенциальной нежелательной ситуации. Первый: триггер должен сработать, когда ожидается, что система будет в проблемном состоянии через «время на реагирование». Второй: триггер должен сработать, когда система достигнет проблемного состояния менее чем через «время на реагирование». Соответствующие функции триггера для использования — forecast и timeleft. Обратите внимание, что лежащий в основе статистический анализ по сути идентичен для обеих функций. Вы можете настроить триггер любым удобным для вас способом и получить схожие результаты.
Параметры
Обе функции используют почти одинаковый набор параметров. Для справки используйте список поддерживаемых функций.
Интервал времени
Прежде всего, следует указать исторический период, который Zabbix должен
проанализировать, чтобы построить прогноз. Это делается привычным способом
с помощью параметра time period и необязательного сдвига по времени, так же,
как и в функциях avg, count, delta, max, min и sum.
Горизонт прогнозирования
(только для forecast)
Параметр time задаёт, насколько далеко в будущее Zabbix должен
экстраполировать зависимости, обнаруженные в исторических данных. Независимо от того,
используете ли вы time_shift или нет, time всегда отсчитывается от текущего
момента.
Порог для достижения
(только для timeleft)
Параметр threshold задаёт значение, которого анализируемый элемент данных должен достичь,
независимо от того, сверху или снизу. После того как мы определили f(t)
(см. ниже), следует решить уравнение f(t) = threshold и вернуть
корень, который ближе к текущему моменту и расположен справа от него, либо
1.7976931348623158E+308, если такого корня нет.
Когда значения элемента данных приближаются к порогу, а затем пересекают
его, timeleft предполагает, что это пересечение уже произошло в прошлом, и
поэтому переключается на следующее пересечение с уровнем threshold, если
оно есть. Рекомендуется использовать прогнозы как дополнение к
обычной диагностике проблем, а не как её замену.1
Функции аппроксимации
По умолчанию fit — это линейная функция. Но если ваша отслеживаемая система
более сложная, у вас есть больше вариантов на выбор.
fit |
x = f(t) |
|---|---|
| linear | x = a + b*t |
| polynomialN2 | x = a~0~ + a~1~*t + a~2~*t2 + ... + a~n~*tn |
| exponential | x = a*exp(b*t) |
| logarithmic | x = a + b*log(t) |
| power | x = a*tb |
Режимы
(только для forecast)
Каждый раз, когда вычисляется функция триггера, она получает данные из
указанного периода истории и подбирает к данным указанную функцию. Таким
образом, если данные немного отличаются, подобранная функция также будет
немного отличаться. Если просто вычислить значение подобранной функции в
указанный момент времени в будущем, вы ничего не узнаете о том, как
ожидается поведение анализируемого элемента данных между текущим
моментом и этим моментом в будущем. Для некоторых вариантов fit
(например, polynomial) простое значение из будущего может вводить в
заблуждение.
mode |
Результат forecast |
|---|---|
| value | f(now + time) |
| max | max~now\ <=\ t\ <=\ now\ +\ time~ f(t) |
| min | min~now\ <=\ t\ <=\ now\ +\ time~ f(t) |
| delta | max - min |
| avg | среднее значение f(t) (now <= t <= now + time) согласно определению |
Подробности
Чтобы избежать вычислений с огромными числами, мы рассматриваем временную метку первого значения в указанном периоде плюс 1 нс как новое нулевое время (текущее время эпохи имеет порядок 109, квадрат эпохи — 1018, двойная точность составляет около 10-16). 1 нс добавляется, чтобы обеспечить все положительные значения времени для логарифмической и степенной аппроксимации, которые включают вычисление log(t). Сдвиг времени не влияет на линейную, полиномиальную, экспоненциальную аппроксимацию (кроме более простых и точных вычислений), но изменяет форму логарифмической и степенной функций.
Возможные ошибки
Функции возвращают -1 в следующих случаях:
- указанный период оценки не содержит данных;
- результат математической операции не определён3;
- численные осложнения (к сожалению, для некоторых наборов входных данных диапазон и точность формата чисел с плавающей точкой двойной точности оказываются недостаточными)4.
Предупреждения или ошибки не выдаются, если выбранная аппроксимация плохо описывает предоставленные данные или если данных просто слишком мало для точного прогнозирования.
Примеры и обработка ошибок
Чтобы получить предупреждение, когда на вашем узле сети вот-вот закончится свободное место на диске, вы можете использовать такое выражение триггера:
timeleft(/host/vfs.fs.size[/,free],1h,0)<1h
Однако в дело может вмешаться код ошибки -1 и перевести ваш триггер в проблемное состояние. В целом это хорошо, потому что вы получаете предупреждение о том, что ваши прогнозы работают некорректно, и вам следует изучить их более тщательно, чтобы выяснить причину. Но иногда это плохо, потому что -1 может просто означать, что за последний час не было получено данных о свободном месте на диске узла сети. Если вы получаете слишком много ложноположительных оповещений, рассмотрите возможность использования более сложного выражения триггера 5:
timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1
С forecast ситуация немного сложнее. Прежде всего, -1 может как перевести триггер в проблемное состояние, так и не сделать этого, в зависимости от того, есть ли у вас выражение вида forecast(/host/item,(...))<... или вида forecast(/host/item,(...))>...
Кроме того, -1 может быть допустимым прогнозом, если для элемента данных нормально иметь отрицательное значение. Но вероятность такой ситуации в реальных условиях пренебрежимо мала (см.
как работает оператор =). Поэтому добавьте ... or forecast(/host/item,(...))=-1 или
... and forecast(/host/item,(...))<>-1, если вы соответственно хотите или не хотите рассматривать -1 как проблему.
Сноски
1 Например, простой триггер вида
timeleft(/host/item,1h,X) < 1h может перейти в проблемное состояние, когда значение элемента данных приближается к X, а затем внезапно восстановиться, как только значение X будет достигнуто. Если проблема заключается в том, что значение элемента данных ниже X, используйте:
last(/host/item) < X or timeleft(/host/item,1h,X) < 1h Если проблема заключается в том, что значение элемента данных выше X, используйте:
last(/host/item) > X or timeleft(/host/item,1h,X) < 1h
2 Степень полинома может быть от 1 до 6, polynomial1 эквивалентен linear. Однако используйте полиномы более высокой степени с осторожностью. Если период оценки содержит меньше точек, чем требуется для определения коэффициентов полинома, степень полинома будет понижена (например, запрошен polynomial5, но есть только 4 точки, поэтому будет аппроксимирован polynomial3).
3 Например, аппроксимация функциями exponential или power включает вычисление log() от значений элемента данных. Если данные содержат нули или отрицательные числа, вы получите ошибку, поскольку log() определён только для положительных значений.
4 Для аппроксимаций linear, exponential, logarithmic и power все необходимые вычисления можно записать явно. Для polynomial без дополнительных шагов можно вычислить только value. Вычисление avg включает нахождение первообразной полинома (аналитически). Вычисление max, min и delta включает нахождение производной полинома (аналитически) и поиск её корней (численно). Решение f(t) = 0 включает поиск корней полинома (численно).
5 Но в этом случае -1 может привести к восстановлению вашего триггера из проблемного состояния. Чтобы полностью защититься, используйте:
timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and ({TRIGGER.VALUE}=0 and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1 or {TRIGGER.VALUE}=1)