2 Выражение триггера

Overview

The expressions used in triggers are very flexible. You can use them to create complex logical tests regarding monitored statistics.

A simple expression uses a function that is applied to the item with some parameters. The function returns a result that is compared to the threshold, using an operator and a constant.

The syntax of a simple useful expression is function(/host/key,parameter)<operator><constant>.

For example:

  min(/Zabbix server/net.if.in[eth0,bytes],5m)>100K

will trigger if the number of received bytes during the last five minutes was always over 100 kilobytes.

While the syntax is exactly the same, from the functional point of view there are two types of trigger expressions:

  • problem expression - defines the conditions of the problem
  • recovery expression (optional) - defines additional conditions of the problem resolution

When defining a problem expression alone, this expression will be used both as the problem threshold and the problem recovery threshold. As soon as the problem expression evaluates to TRUE, there is a problem. As soon as the problem expression evaluates to FALSE, the problem is resolved.

When defining both problem expression and the supplemental recovery expression, problem resolution becomes more complex: not only the problem expression has to be FALSE, but also the recovery expression has to be TRUE. This is useful to create hysteresis and avoid trigger flapping.

Функции

Функции триггеров позволяют ссылаться на собранные значения, текущее время и другие факторы.

Имеется полный список поддерживаемых функций.

Параметры функций

Большинство числовых функций принимают количество секунд в качестве параметра.

Вы можете использовать префикс #, чтобы указать что этот параметр должен иметь другой смысл:

ВЫЗОВ ФУНКЦИИ СМЫСЛ
sum(600) Сумма всех значений за 600 секунд
sum(#5) Сумма последних 5 значений

Функция last использует другой смысл для значений, когда начинается с решетки - она дает выбрать n-ое предыдущее значение, так что с учетом значений 3, 7, 2, 6, 5 (от наиболее нового до наиболее старого), при last(#2) вернется 7 и при last(#5) вернется 5.

Несколько функций поддерживают дополнительный, второй параметр сдвиг_времени. Этот параметр позволят ссылаться на данные из периода времени в прошлом. Например, для avg(1h,1d) будет возвращено среднее значение за час днем ранее.

Вы можете использовать поддерживаемые суффиксы преобразований в выражениях триггеров, например, '5m' (минут) вместо '300' секунд или '1d' (день) вместо '86400' секунд. '1K' будет состоять из '1024' байт.

Операторы

Следующие операторы поддерживаются для триггеров (представлены по убыванию приоритета выполнения):

ПРИОРИТЕТ ОПЕРАТОР ОПРЕДЕЛЕНИЕ Заметки по неизвестным значениям
1 - Унарный минус -Неизвестно → Неизвестно
2 not Логическое НЕ not Неизвестно → Неизвестно
3 * Умножение 0 * Неизвестно → Неизвестно
(да, Неизвестно, не 0 - чтобы не потерять
Неизвестно в арифметических операциях)
1.2 * Неизвестно → Неизвестно
/ Деление Неизвестно / 0 → ошибка
Неизвестно / 1.2 → Неизвестно
0.0 / Неизвестно → Неизвестно
4 + Арифметический плюс 1.2 + Неизвестно → Неизвестно
- Арифметический минус 1.2 - Неизвестно → Неизвестно
5 < Менее чем. Этот оператор может быть представлен в виде:

A<B ⇔ (A<B-0.000001)
1.2 < Неизвестно → Неизвестно
<= Менее чем или равно.Этот оператор может быть представлен в виде:

A<=B ⇔ (A≤B+0.000001)
Неизвестно <= Неизвестно → Неизвестно
> Более чем. Этот оператор может быть представлен в виде:

A>B ⇔ (A>B+0.000001)
>= Более чем или равно. Этот оператор может быть представлен в виде:

A>=B ⇔ (A≥B-0.000001)
6 = Равенство. Этот оператор может быть представлен в виде:

A=B ⇔ (A≥B-0.000001) и (A≤B+0.000001)
<> Не равно. Этот оператор может быть представлен в виде:

A<>B ⇔ (A<B-0.000001) или (A>B+0.000001)
7 and Логическое И 0 and Неизвестно → 0
1 and Неизвестно → Неизвестно
Неизвестно and Неизвестно → Неизвестно
8 or Логическое ИЛИ 1 or Неизвестно → 1
0 or Неизвестно → Неизвестно
Неизвестно or Неизвестно → Неизвестно

Операторы not, and and or регистрозависимы и должны быть в нижнем регистре. Они также должны быть окружены символами пробелов или круглыми скобками.

Все операторы, кроме унарных - и not, имеют ассоциативность слева на право. Унарные - и not не ассоциативны (имеется в виду необходимо использовать -(-1) и not (not 1) вместо --1 и not not 1).

Результат вычисления:

  • Операторы <, <=, >, >=, =, <> должны давать '1' в выражении триггера, если указанное соотношение правдиво и '0', если оно ложно. Если по крайней мере один операнд Неизвестен, то и результат будет Неизвестно;
  • and по известным операндам должно давать '1', если оба из этих операндов сравнения не равны '0'; в противном случае, будет давать '0'; для неизвестных операндов and даст '0' только, если один из операндов сравнения равен '0'; в противном случае, он даст 'Неизвестно';
  • or по известным операндам должно давать '1', если какой-либо из этих операндов сравнения не равен '0'; в противном случае, будет давать '0'; для неизвестных операндов or даст '1' только, если один из операндов сравнения не равен '0'; в противном случае, он даст 'Неизвестно';
  • Результат логического операнда отрицания not для известного операнда равен '0', если значение этого операнда сравнения не равно '0'; '1', если значение его операнда сравнения равно '0'. Для неизвестных операндов not даст 'Неизвестно'.

Кэширование значений

Значения, которые требуются для вычисления триггеров, кэшируются Zabbix сервером. По этой причине такое вычисление триггеров на некоторое время приводит к более высокой загрузке базы данных после перезапуска сервера. Кэш значений не очищается, когда значения истории элементов данных удаляются (либо вручную, либо при помощи автоматической очистки истории), поэтому сервер будет использовать кэшированные значения пока они не станут старше, чем периоды времени, которые заданы в функциях триггеров, либо пока сервер не будет перезапущен.

Примеры триггеров

Operators

The following operators are supported for triggers (in descending priority of execution):

Priority Operator Definition Notes for unknown values Force cast operand to float 1
1 - Unary minus -Unknown → Unknown Yes
2 not Logical NOT not Unknown → Unknown Yes
3 * Multiplication 0 * Unknown → Unknown
(yes, Unknown, not 0 - to not lose
Unknown in arithmetic operations)
1.2 * Unknown → Unknown
Yes
/ Division Unknown / 0 → error
Unknown / 1.2 → Unknown
0.0 / Unknown → Unknown
Yes
4 + Arithmetical plus 1.2 + Unknown → Unknown Yes
- Arithmetical minus 1.2 - Unknown → Unknown Yes
5 < Less than. The operator is defined as:

A<B ⇔ (A<B-0.000001)
1.2 < Unknown → Unknown Yes
<= Less than or equal to. The operator is defined as:

A<=B ⇔ (A≤B+0.000001)
Unknown <= Unknown → Unknown Yes
> More than. The operator is defined as:

A>B ⇔ (A>B+0.000001)
Yes
>= More than or equal to. The operator is defined as:

A>=B ⇔ (A≥B-0.000001)
Yes
6 = Is equal. The operator is defined as:

A=B ⇔ (A≥B-0.000001) and (A≤B+0.000001)
No 1
<> Not equal. The operator is defined as:

A<>B ⇔ (A<B-0.000001) or (A>B+0.000001)
No 1
7 and Logical AND 0 and Unknown → 0
1 and Unknown → Unknown
Unknown and Unknown → Unknown
Yes
8 or Logical OR 1 or Unknown → 1
0 or Unknown → Unknown
Unknown or Unknown → Unknown
Yes

1 String operand is still cast to numeric if:

  • another operand is numeric
  • operator other than = or <> is used on an operand

(If the cast fails - numeric operand is cast to a string operand and both operands get compared as strings.)

not, and and or operators are case-sensitive and must be in lowercase. They also must be surrounded by spaces or parentheses.

All operators, except unary - and not, have left-to-right associativity. Unary - and not are non-associative (meaning -(-1) and not (not 1) should be used instead of --1 and not not 1).

Evaluation result:

  • <, <=, >, >=, =, <> operators shall yield '1' in the trigger expression if the specified relation is true and '0' if it is false. If at least one operand is Unknown the result is Unknown;
  • and for known operands shall yield '1' if both of its operands compare unequal to '0'; otherwise, it yields '0'; for unknown operands and yields '0' only if one operand compares equal to '0'; otherwise, it yields 'Unknown';
  • or for known operands shall yield '1' if either of its operands compare unequal to '0'; otherwise, it yields '0'; for unknown operands or yields '1' only if one operand compares unequal to '0'; otherwise, it yields 'Unknown';
  • The result of the logical negation operator not for a known operand is '0' if the value of its operand compares unequal to '0'; '1' if the value of its operand compares equal to '0'. For unknown operand not yields 'Unknown'.
Пример 2

www.zabbix.com перегружен

{www.zabbix.com:system.cpu.load[all,avg1].last()}>5 or {www.zabbix.com:system.cpu.load[all,avg1].min(10m)}>2 

Это выражение будет истинным, когда либо текущая загрузка процессора станет более 5, либо загрузка процессора больше значения 2 за последние 10 минут.

Пример 3

/etc/passwd был изменен

Используется функция diff:

{www.zabbix.com:vfs.file.cksum[/etc/passwd].diff()}=1

Это выражение будет истинным, когда предыдущее значение контрольной суммы файла /etc/passwd отличается от самого нового значения.

Аналогичные выражения могут быть полезны для мониторинга изменений в важных файлах, таких как /etc/passwd, /etc/inetd.conf, /kernel и других.

Пример 4

Кто-то скачивает большой файл из Интернет

Используется функция min:

{www.zabbix.com:net.if.in[eth0,bytes].min(5m)}>100K

Это выражение будет истинным, когда количество полученных байт на eth0 превышает 100 КБ за последних 5 минут.

Пример 5

Оба узла кластера SMTP серверов недоступны

Примечание, в выражении используются два разных узла сети:

{smtp1.zabbix.com:net.tcp.service[smtp].last()}=0 and {smtp2.zabbix.com:net.tcp.service[smtp].last()}=0

Это выражение будет истинным, когда оба SMTP сервера недоступны на обоих smtp1.zabbix.com и smtp2.zabbix.com.

Пример 6

Zabbix агент нуждается в обновлении

Используется функция str():

{zabbix.zabbix.com:agent.version.str("beta8")}=1

Это выражение будет истинным, когда версия Zabbix агента содержит в себе 'beta8' (возможно 1.0beta8).

Пример 7

Сервер недоступен

{zabbix.zabbix.com:icmpping.count(30m,0)}>5

Это выражение будет истинным, если узел сети “zabbix.zabbix.com" недоступен более 5 раз за последние 30 минут.

Пример 8

Нет данных за последние 3 минуты

Используется функцию nodata():

{zabbix.zabbix.com:tick.nodata(3m)}=1

Для того, чтобы этот триггер заработал, элемент данных ‘tick’ должен быть задан как элемент данных типа Zabbix траппер. Узел сети должен периодически отправлять данные этому элементу данных, используя zabbix_sender. Если не было получено данных за последние 180 секунд, значением триггера станет ПРОБЛЕМА.

Обратие внимание, что 'nodata' можно использовать с любым типом элементов данных.

Пример 9

Активность CPU в ночное время

Используется функция time():

{zabbix:system.cpu.load[all,avg1].min(5m)}>2 and {zabbix:system.cpu.load[all,avg1].time()}>000000 and {zabbix:system.cpu.load[all,avg1].time()}<060000

Триггер может изменить свое состояние в истинное только в ночное время (00:00-06:00).

Пример 10

Проверка синхронизации времени на клиенте со временем на Zabbix сервере

Используется функция fuzzytime():

{MySQL_DB:system.localtime.fuzzytime(10)}=0

Триггер изменит состояние на проблему тогда, когда локальное время на сервере MySQL_DB и Zabbix сервере различаются более чем на 10 секунд.

Пример 11

Сравнение средней загрузки сегодня со средним значением загрузки за это же время вчера (использование второго параметра сдвиг_времени).

{server:system.cpu.load.avg(1h)}/{server:system.cpu.load.avg(1h,1d)}>2

Триггер изменит свое состояние на проблему, если средняя загрузка за последний час будет в два раза больше чем за аналогичный период времени вчера.

Пример 12

Использование значение другого элемента данных в качестве порогового значения триггера:

{Template PfSense:hrStorageFree[{#SNMPVALUE}].last()}<{Template PfSense:hrStorageSize[{#SNMPVALUE}].last()}*0.1

Триггер изменит свое состояние на проблему, если свободное пространство на диски упадет ниже 10 процентов.

Пример 13

Использование результата вычисления для получения количества триггеров больше порога:

({server1:system.cpu.load[all,avg1].last()}>5) + ({server2:system.cpu.load[all,avg1].last()}>5) + ({server3:system.cpu.load[all,avg1].last()}>5)>=2

Триггер изменит свое состояние на проблему, если по крайней мере два триггера из выражения будут больше 5.

Гистерезис

Порой нам необходим интервал между состояниями ОК и Проблема, а не просто порог. Например, мы бы хотели задать триггер, который переходит в состояние Проблема, когда температура в серверной комнате становится больше 20C и мы бы хотели чтобы он оставался в этом состоянии пока температура не опустится ниже 15C.

Чтобы это сделать, сначала мы зададим выражение триггера для события о проблеме. Затем выберем 'Выражение восстановления' в Формирование ОК события и укажем выражение восстановления для ОК события.

Обратите внимание, что выражение восстановления будет вычислено только при первом решении события о проблеме. Невозможно решить проблему при помощи выражения восстановления, если условие проблемы всё еще присутствует.

Пример 1

Температура в серверной комнате слишком высокая.

Выражение проблемы:

{server:temp.last()}>20

Выражение восстановления:

{server:temp.last()}<=15
Пример 2

Очень мало свободного места на диске

Выражение проблемы: если меньше 10ГБ за последние 5 минут

{server:vfs.fs.size[/,free].max(5m)}<10G

Выражение восстановления: если больше 40ГБ за последние 10 минут

{server:vfs.fs.size[/,free].min(10m)}>40G

Выражения с неподдерживаемыми элементами данных и неизвестными значениями

Версии до Zabbix 3.2 очень строго относились к неподдерживаемым элементам данных в выражениях триггеров. Любой неподдерживаемый элемент данных в выражении незамедлительно менял значение триггера на Неизвестно.

Начиная с Zabbix 3.2 существует более гибкий подход к неподдерживаемым элементам данных, допуская неизвестные значения при вычислении выражений:

  • У некоторых функций их значения не зависят от того поддерживается ли элемент данных или нет. Такие функции теперь вычисляются даже, если ссылаются на неподдерживаемые элементы данных. Смотрите список в разделе функции и неподдерживаемые элементы данных.
  • Логические выражения с ИЛИ и И могут быть вычислены для известных значений в двух случаях независимо от неизвестных операндов:
    • "1 or Неподдерживаемый_элемент_данных1.некая_функция() or Неподдерживаемый_элемент_данных2. некая_функция() or ..." может быть вычислена как '1' (Правда),
    • "0 and Неподдерживаемый_элемент_данных1. некая_функция() and Неподдерживаемый_элемент_данных2. некая_функция() and ..." может быть вычислена как '0' (Ложь).
      Zabbix пытается вычислить логические выражения принимая неподдерживаемые элементы данных как Неизвестные значения. В двух случаях, упомянутых выше, будет приниматься известное значение; в остальных случаях значением триггера будет Неизвестно.
  • Если вычисление триггера по поддерживаемому элементу данных приведет к ошибке, значением функции будет Неизвестно и оно будет частью дальнейшего вычисления выражения.

Обратите внимение на то, что неизвестные значения могут "исчезать" только в логических выражениях описанных выше. В арифметических выражениях неизвестные Неизвестному результату (за исключением деления на 0).

Если выражение триггера с несколькими неподдерживаемыми элементами данных вычисляется как Неизвестное, сообщение об ошибке в веб-интерфейсе ссылается на последний вычисленный неподдерживаемый элемент данных.

Example 15

Comparing two string values - operands are:

  • a function that returns a string
  • a combination of macros and strings

Problem: detect changes in the DNS query

The item key is:

net.dns.record[8.8.8.8,{$WEBSITE_NAME},{$DNS_RESOURCE_RECORD_TYPE},2,1]

with macros defined as

{$WEBSITE_NAME} = example.com
       {$DNS_RESOURCE_RECORD_TYPE} = MX

and normally returns:

example.com           MX       0 mail.example.com

So our trigger expression to detect if the DNS query result deviated from the expected result is:

last(/Zabbix server/net.dns.record[8.8.8.8,{$WEBSITE_NAME},{$DNS_RESOURCE_RECORD_TYPE},2,1])<>"{$WEBSITE_NAME}           {$DNS_RESOURCE_RECORD_TYPE}       0 mail.{$WEBSITE_NAME}"

Notice the quotes around the second operand.

Example 16

Comparing two string values - operands are:

  • a function that returns a string
  • a string constant with special characters \ and "

Problem: detect if the /tmp/hello file content is equal to:

\" //hello ?\"

Option 1) write the string directly

last(/Zabbix server/vfs.file.contents[/tmp/hello])="\\\" //hello ?\\\""

Notice how \ and " characters are escaped when the string gets compared directly.

Option 2) use a macro

{$HELLO_MACRO} = \" //hello ?\"

in the expression:

last(/Zabbix server/vfs.file.contents[/tmp/hello])={$HELLO_MACRO}
Example 17

Comparing long-term periods.

Problem: Load of Exchange server increased by more than 10% last month

trendavg(/Exchange/system.cpu.load,1M:now/M)>1.1*trendavg(/Exchange/system.cpu.load,1M:now/M-1M)

You may also use the Event name field in trigger configuration to build a meaningful alert message, for example to receive something like

"Load of Exchange server increased by 24% in July (0.69) comparing to June (0.56)"

the event name must be defined as:

Load of {HOST.HOST} server increased by {{?100*trendavg(//system.cpu.load,1M:now/M)/trendavg(//system.cpu.load,1M:now/M-1M)}.fmtnum(0)}% in {{TIME}.fmttime(%B,-1M)} ({{?trendavg(//system.cpu.load,1M:now/M)}.fmtnum(2)}) comparing to {{TIME}.fmttime(%B,-2M)} ({{?trendavg(//system.cpu.load,1M:now/M-1M)}.fmtnum(2)})

It is also useful to allow manual closing in trigger configuration for this kind of problem.

Hysteresis

Sometimes an interval is needed between problem and recovery states, rather than a simple threshold. For example, if we want to define a trigger that reports a problem when server room temperature goes above 20°C and we want it to stay in the problem state until the temperature drops below 15°C, a simple trigger threshold at 20°C will not be enough.

Instead, we need to define a trigger expression for the problem event first (temperature above 20°C). Then we need to define an additional recovery condition (temperature below 15°C). This is done by defining an additional Recovery expression parameter when defining a trigger.

In this case, problem recovery will take place in two steps:

  • First, the problem expression (temperature above 20°C) will have to evaluate to FALSE
  • Second, the recovery expression (temperature below 15°C) will have to evaluate to TRUE

The recovery expression will be evaluated only when the problem event is resolved first.

The recovery expression being TRUE alone does not resolve a problem if the problem expression is still TRUE!

Example 1

Temperature in server room is too high.

Problem expression:

last(/server/temp)>20

Recovery expression:

last(/server/temp)<=15
Example 2

Free disk space is too low.

Problem expression: it is less than 10GB for last 5 minutes

max(/server/vfs.fs.size[/,free],5m)<10G

Recovery expression: it is more than 40GB for last 10 minutes

min(/server/vfs.fs.size[/,free],10m)>40G

Expressions with unsupported items and unknown values

Versions before Zabbix 3.2 are very strict about unsupported items in a trigger expression. Any unsupported item in the expression immediately renders trigger value to Unknown.

Since Zabbix 3.2 there is a more flexible approach to unsupported items by admitting unknown values into expression evaluation:

  • For the nodata() function, the values are not affected by whether an item is supported or unsupported. The function is evaluated even if it refers to an unsupported item.
  • Logical expressions with OR and AND can be evaluated to known values in two cases regardless of unknown operands:
    • "1 or Unsupported_item1.some_function() or Unsupported_item2.some_function() or ..." can be evaluated to '1' (True),
    • "0 and Unsupported_item1.some_function() and Unsupported_item2.some_function() and ..." can be evaluated to '0' (False).
      Zabbix tries to evaluate logical expressions taking unsupported items as Unknown values. In the two cases mentioned above a known value will be produced; in other cases trigger value will be Unknown.
  • If a function evaluation for supported item results in error, the function value is Unknown and it takes part in further expression evaluation.

Note that unknown values may "disappear" only in logical expressions as described above. In arithmetic expressions unknown values always lead to result Unknown (except division by 0).

If a trigger expression with several unsupported items evaluates to Unknown the error message in the frontend refers to the last unsupported item evaluated.