zabbix запуск скрипта по триггеру
Zabbix. Отправка триггера с комментарием
Приветствую!
Решил поделиться небольшим скрипом (немного модифицированный оригинальный) по отправке уведомлений в Zabbix’е с пользовательскими комментариями.
Суть задачи: на работе используется Zabbix в основном для мониторинга удаленных сетей (доступность, немного качества). При отсутствии связи с удаленной сетью по должностной инструкции мы должны извещать об этом определенные отделы. Настроить обычную отправку почты не составило труда, но при такой отправке неясности у отделов хватало — по какой причине отключилась «сеть», как долго её не будет. Поэтому задался целью вставить в отсылаемое письмо комментарий водимый в дашборде при подтверждении триггера.
По сути, это тот же скрипт, что лежит в официальной документации Zabbix’а с одной небольшой вставкой:
Теперь про настройку действий:
В моем случае, отправка сообщения происходит спустя 30 минут, после возникновения триггера, в связи с тем, что требуется время для уточнения информации о причинах недоступности сети и ее устранения. По истечении 30 минут, если проблема не устранена, происходит уведомление пользователей, находящихся в группе «notification».
Недоработки скрипта:
1) Скрипт не понимает многостроковые комментарии. В этом случае он присылает текст во вложении. Кто знает как исправить — поделитесь мыслью.
2) Т.к. я, можно сказать единственный, кто взаимодействует с фронтэндом заббикса — то не делал вставку автора комментария. Но это в принципе реализуемо:
3) Сделано через стандартный mail, можно переделать через mutt, что бы добавить html и сделать все красиво.
Теперь об особенностях. Местоположение хоста берется из «Инвентарные данные» — «Местоположение»
Разделитель — «;»
Текст прописанный в действии:
В принципе можно менять все что угодно, главное найти соответствующий макрос, который можно посмотреть здесь
Я понимаю, что это слишком маленькое исправление, но возможно — кому-нибудь пригодится.
UPD: Тут на форуме, спустя недельку подсказали, что я изобрел велосипед, и было достаточно добавить в стандартный способ вывода.
Zabbix Documentation 5.4
Sidebar
Table of Contents
2 Выражение триггера
Обзор
Используемые в триггерах выражения являются очень гибкими. Вы можете использовать их для создания сложных логических тестов, учитывая статистику по мониторингу.
Простое полезное выражение может выглядеть примерно так:
Функции
Функции триггеров позволяют ссылаться на собранные значения, текущее время и другие факторы.
Параметры функций
Большинство числовых функций принимают количество секунд в качестве параметра.
Вы можете использовать префикс #, чтобы указать что этот параметр должен иметь другой смысл:
ВЫЗОВ ФУНКЦИИ | СМЫСЛ |
---|---|
sum(600) | Сумма всех значений за 600 секунд |
sum(#5) | Сумма последних 5 значений |
Вы можете использовать поддерживаемые суффиксы преобразований в выражениях триггеров, например, ‘5m’ (минут) вместо ‘300’ секунд или ‘1d’ (день) вместо ‘86400’ секунд. ‘1K’ будет состоять из ‘1024’ байт.
Операторы
Следующие операторы поддерживаются для триггеров (представлены по убыванию приоритета выполнения):
A>B ⇔ (A>B+0.000001)
A>=B ⇔ (A≥B-0.000001)
A=B ⇔ (A≥B-0.000001) и (A≤B+0.000001)
A<>B ⇔ (A B+0.000001)
1 and Неизвестно → Неизвестно
Неизвестно and Неизвестно → Неизвестно
0 or Неизвестно → Неизвестно
Неизвестно or Неизвестно → Неизвестно
Операторы not, and and or регистрозависимы и должны быть в нижнем регистре. Они также должны быть окружены символами пробелов или круглыми скобками.
Все операторы, кроме унарных — и not, имеют ассоциативность слева на право. Унарные — и not не ассоциативны (имеется в виду необходимо использовать -(-1) и not (not 1) вместо —1 и not not 1).
Кэширование значений
Значения, которые требуются для вычисления триггеров, кэшируются Zabbix сервером. По этой причине такое вычисление триггеров на некоторое время приводит к более высокой загрузке базы данных после перезапуска сервера. Кэш значений не очищается, когда значения истории элементов данных удаляются (либо вручную, либо при помощи автоматической очистки истории), поэтому сервер будет использовать кэшированные значения пока они не станут старше, чем периоды времени, которые заданы в функциях триггеров, либо пока сервер не будет перезапущен.
Примеры триггеров
Пример 1
Высокая загрузка процессора на www.zabbix.com.
Пример 2
Это выражение будет истинным, когда либо текущая загрузка процессора станет более 5, либо загрузка процессора больше значения 2 за последние 10 минут.
Пример 3
/etc/passwd был изменен
Используется функция diff:
Это выражение будет истинным, когда предыдущее значение контрольной суммы файла /etc/passwd отличается от самого нового значения.
Аналогичные выражения могут быть полезны для мониторинга изменений в важных файлах, таких как /etc/passwd, /etc/inetd.conf, /kernel и других.
Пример 4
Кто-то скачивает большой файл из Интернет
Используется функция min:
Это выражение будет истинным, когда количество полученных байт на eth0 превышает 100 КБ за последних 5 минут.
Пример 5
Оба узла кластера SMTP серверов недоступны
Примечание, в выражении используются два разных узла сети:
Это выражение будет истинным, когда оба SMTP сервера недоступны на обоих smtp1.zabbix.com и smtp2.zabbix.com.
Пример 6
Zabbix агент нуждается в обновлении
Используется функция str():
Это выражение будет истинным, когда версия Zabbix агента содержит в себе ‘beta8’ (возможно 1.0beta8).
Пример 7
Это выражение будет истинным, если узел сети “zabbix.zabbix.com“ недоступен более 5 раз за последние 30 минут.
Пример 8
Нет данных за последние 3 минуты
Используется функцию nodata():
Для того, чтобы этот триггер заработал, элемент данных ‘tick’ должен быть задан как элемент данных типа Zabbix траппер. Узел сети должен периодически отправлять данные этому элементу данных, используя zabbix_sender. Если не было получено данных за последние 180 секунд, значением триггера станет ПРОБЛЕМА.
Обратие внимание, что ‘nodata’ можно использовать с любым типом элементов данных.
Пример 9
Активность CPU в ночное время
Используется функция time():
Триггер может изменить свое состояние в истинное только в ночное время (00:00-06:00).
Пример 10
Проверка синхронизации времени на клиенте со временем на Zabbix сервере
Используется функция fuzzytime():
Триггер изменит состояние на проблему тогда, когда локальное время на сервере MySQL_DB и Zabbix сервере различаются более чем на 10 секунд.
Пример 11
Сравнение средней загрузки сегодня со средним значением загрузки за это же время вчера (использование второго параметра сдвиг_времени ).
Триггер изменит свое состояние на проблему, если средняя загрузка за последний час будет в два раза больше чем за аналогичный период времени вчера.
Пример 12
Использование значение другого элемента данных в качестве порогового значения триггера:
Триггер изменит свое состояние на проблему, если свободное пространство на диски упадет ниже 10 процентов.
Пример 13
Использование результата вычисления для получения количества триггеров больше порога:
Триггер изменит свое состояние на проблему, если по крайней мере два триггера из выражения будут больше 5.
Гистерезис
Порой нам необходим интервал между состояниями ОК и Проблема, а не просто порог. Например, мы бы хотели задать триггер, который переходит в состояние Проблема, когда температура в серверной комнате становится больше 20C и мы бы хотели чтобы он оставался в этом состоянии пока температура не опустится ниже 15C.
Чтобы это сделать, сначала мы зададим выражение триггера для события о проблеме. Затем выберем ‘Выражение восстановления’ в Формирование ОК события и укажем выражение восстановления для ОК события.
Обратите внимание, что выражение восстановления будет вычислено только при первом решении события о проблеме. Невозможно решить проблему при помощи выражения восстановления, если условие проблемы всё еще присутствует.
Пример 1
Температура в серверной комнате слишком высокая.
Пример 2
Очень мало свободного места на диске
Выражение проблемы: если меньше 10ГБ за последние 5 минут
Выражение восстановления: если больше 40ГБ за последние 10 минут
Выражения с неподдерживаемыми элементами данных и неизвестными значениями
Начиная с Zabbix 3.2 существует более гибкий подход к неподдерживаемым элементам данных, допуская неизвестные значения при вычислении выражений:
Обратите внимение на то, что неизвестные значения могут “исчезать” только в логических выражениях описанных выше. В арифметических выражениях неизвестные Неизвестному результату (за исключением деления на 0).
Решаем практические задачи в Zabbix с помощью JavaScript
Тихон Усков, инженер команды интеграции Zabbix
Zabbix — кастомизируемая платформа, которая используется для мониторинга любых данных. С самых ранних версий Zabbix у администраторов мониторинга была возможность запускать различные скрипты через Actions для проверок на целевых узлах сети. При этом запуск скриптов приводил к возникновению ряда сложностей, в том числе таких, как необходимость поддержки скриптов, их доставки на узлы связи и прокси, а также поддержки разных версий.
JavaScript для Zabbix
В апреле 2019 года был представлен Zabbix 4.2 с функцией предобработки на JavaScript. Многие загорелись идеей отказаться от написания скриптов, которые где-то забирают данные, переваривают их и предоставляют уже в понятном для Zabbix формате, а выполнять простые проверки, которые будут получать неготовые для хранения и обработки Zabbix данные, а потом обрабатывать этот поток данных с использованием средств Zabbix и JavaScript. В связке с низкоуровневым обнаружением и зависимыми элементами данных, которые появились в Zabbix 3.4, получилось достаточно гибкая концепция для сортировки и управления полученными данными.
В Zabbix 4.4, как логическое продолжение предобработки на JavaScript, появился новый способ оповещения — Webhook, который можно использовать для простой интеграции оповещений Zabbix со сторонними приложениями.
JavaScript и Duktape
Почему были выбраны именно JavaScript и Duktape? Рассматривались различные варианты языков и движков:
Основными критериями выбора были распространенность, простота интеграции движка в продукт, низкое потребление ресурсов и общая производительность движка, и безопасность внедрения кода на этом языке в мониторинг. По совокупности показателей победил JavaScript на движке Duktape.
Критерии выбора и performance testing
— Стандарт ECMAScript E5/E5.1
— Модули Zabbix для Duktape:
ПРИМЕЧАНИЕ. Duktape соответствует стандартам ACME. В Zabbix используется версия скрипта 2015 года. Последующие изменения незначительны, поэтому их можно игнорировать.
Магия JavaScript
Вся магия JavaScript заключена в динамической типизации и приведении типов: строковых, числовых и логических.
Это означает, что не нужно заранее объявлять какого типа переменная должна возвращать значение.
При математических операциях значения, которые возвращаются операторами-функциями, преобразуются в числа. Исключение из таких операций — сложение, поскольку, если хотя бы одно из слагаемых является строкой, ко всем слагаемым применяется строковое преобразование.
ПРИМЕЧАНИЕ. Методы, отвечающие за такие преобразования, как правило, реализованы в родительских прототипах объектов, valueOf и toString. valueOf вызывается при численном преобразовании и всегда перед методом toString. Метод valueOf обязан возвращать примитивные значения, иначе его результат игнорируется.
Для объекта вызывается метод valueOF. Если он не найден или не возвращает примитивное значение, вызывается метод toString. Если метод toString не найден, производится поиск valueOf в прототипе объекта, и все повторяется до завершения обработки значения и приведения всех значений в выражении к одному типу. Если для объекта реализован метод toString, который возвращает примитивное значение, то именно он используется для строкового преобразования. При этом результатом применения этого метода не обязательно является строка.
Например, если для для объекта ‘obj‘ определяется метод toString,
метод toString возвращает именно строку, и при сложении строки с числом мы получаем склеенную строку:
Но если переписать toString, чтобы метод возвращал число, при сложении объекта будет выполняться математическая операция с числовым преобразованием и получается результат математического сложения.
При этом, если мы выполняем сложение со строкой, выполняется строковое преобразование, и мы получаем склеенную строку.
Именно в этом кроется причина большого количества ошибок начинающих пользователей JavaScript.
В метод toString можно вписать функцию, которая будет увеличивать текущее значения объекта на 1.
Выполнение скрипта при условии, что переменная равна 3, и она же равна 4.
При сравнении с приведением типов (==) каждый раз выполняется метод toString с функцией увеличения значения. Соответственно, при каждом последующем сравнении значение увеличивается. Этого можно избежать путем использования сравнения без приведения типов (===).
Сравнение без приведения типов
ПРИМЕЧАНИЕ. Не используйте сравнение с приведением типов без необходимости.
Для сложных скриптов, например, Webhook со сложной логикой, в которых необходимо сравнение с приведением типов, рекомендуется предварительно написать проверки для значений, которые возвращают переменные и обработать несоответствия и ошибки.
Webhook Media
В конце 2019 года и в начале 2020 года команда интеграции Zabbix занималась активной разработкой Webhooks и интеграций «из коробки», которые поставляются в дистрибутиве Zabbix.
Ссылка на документацию
Preprocessing
ПРИМЕЧАНИЕ. Значения тайм-аута в 10 секунд достаточно много, потому что сбор условных тысяч элементов данных за 1 секунду по достаточно «тяжелому» сценарию предобработки может замедлить работу Zabbix. Поэтому не рекомендуется использовать предобработку для выполнения полноценных скриптов на JavaScript через так называемые теневые элементы данных (dummy items), которые запускаются только для выполнения предобработки.
Проверить свой код можно через тест предобработки или с помощью утилиты zabbix_js:
Практические задачи
Задача 1
Заменить вычисляемый элемент данных предобработкой.
Условие: получаем с датчика температуру в градусах по Фаренгейту для хранения в градусах по Цельсию.
Раньше мы создали бы элемент данных, который собирает температуру в градусах по Фаренгейту. После этого — еще один элемент данных (вычисляемый), который по формуле преобразовывал бы градусы по Фаренгейту в градусы по Цельсию.
Проблемы:
Одним из решений был отказ от гибких интервалов проверок в пользу фиксированных интервалов, чтобы гарантированно вычислять вычисляемый элемент данных после элемента данных, получающего данные (в нашем случае — температура в градусах по Фаренгейту).
Но если, например, шаблон мы используем для проверки большого количества устройств, и проверка выполняется раз в 30 секунд, 29 секунд Zabbix «халтурит», а в последнюю секунду начинает проверки и вычисления. Это приводит к созданию очереди и влияет на производительность. Поэтому рекомендуется использовать фиксированные интервалы, только если это действительно необходимо.
В данной задаче оптимальное решение — предобработка из одной строки на JavaScript, которая конвертирует градусы по Фаренгейту в градусы по Цельсию:
Это быстро и просто, не нужно создавать лишних элементов данных и хранить по ним историю, а также можно использовать для проверок гибкие интервалы.
Но, если в гипотетической ситуации необходимо полученный элемент данных сложить, например, с какой-либо константой, определенной в макросе, необходимо учитывать, что параметр value раскрывается в строку. При операции сложения строк, две строки просто объединяются в одну.
Для получения результата математического действия, необходимо привести типы полученных значений в числовой формат. Для этого можно использовать функцию parseInt(), которая выдает целое число, функцию parseFloat(), которая выдает десятичную дробь, или функцию number, которая выдает целое число или десятичную дробь.
Задача 2
Получить время в секундах до окончания сертификата.
Условие: некий сервис выдает дату окончания сертификата в формате «Feb 12 12:33:56 2022 GMT».
В ECMAScript5 Date.parse() принимает дату в формате ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ). Необходимо привести к нему строку в формате MMM DD YYYY HH:mm:ss ZZ
Проблема: значение месяца выражено текстом, а не числом. Данные в таком формате не принимаются Duktape.
Пример решения:
В первую очередь объявляется переменная, которая принимает значение (весь скрипт — объявление переменных, которые перечислены через запятую).
В первой строке мы получаем дату в параметре value и разделяем ее пробелами методом split. Таким образом, мы получаем массив, где каждому элементу массива, начиная с индекса 0, соответствует один элемент даты до и после пробела. split(0) — месяц, split(1) — число, split(2) — строка с временем и т. д. После этого к каждому элементу даты можно обращаться по индексу в массиве.
Данные в полученном формате — количество секунд с 1970 года до какого-то момента в будущем. Использовать данные в полученном формате в триггерах практически невозможно, потому что Zabbix позволяет оперировать только макросами и , которые возвращают дату и время в понятном для пользователя формате.
В триггере можно указать выражение ‘last
Мониторим всё: расширение агентов Windows и Linux при помощи скриптов
Если нам нужно мониторить состояние серверов и прочих компьютеризированных рабочих мест при помощи Zabbix, то это можно сделать двумя способами.
Первый способ — это при помощи SNMP-запросов, с отправкой которых Zabbix замечательно справляется. Так можно вытащить и загрузку сетевых интерфейсов, и загрузку процессора, памяти. Поверх этого, производители сервера могут выдать нам по SNMP еще много информации о состоянии железа.
Второй заключается в использовании Zabbix агента, который мы будем запускать на наблюдаемой системе. Список наблюдаемых параметров включает в себя как и такие простые вещи, как загрузка процессора, использование памяти, так и более хитрые, такие как чтение текстовых лог-файлов с поддержкой ротации или отслеживание факта изменения любого файла. Можно даже в качестве параметра использовать вывод любой произвольной команды на системе. Возможности Zabbix агента растут от версии к версии.
Что делать, если того, что мы хотим контролировать через Zabbix нет в списке возможностей Zabbix агента? Ждать пока это имплементируют разработчики в следующем релизе? Не обязательно.
Нам оставили несколько стандартных интерфейсов для того, чтобы расширить возможности Заббикса по мониторингу серверов настолько, насколько позволит нам наша фантазия и наличие свободного времени на написание скриптов. Интерфейсы эти UserParameter и zabbix_sender. О первом и пойдет речь, а в качестве примеров будет показано как можно собирать состояние S.M.A.R.T жестких дисков и контролировать, когда кто-то удаляет или устанавливает новые программы на своей Windows-машине.
Немного матчасти
Если вы уже хоть раз настраивали Zabbix агент на сервере, то начать использовать UserParameter не составит труда. Чтобы добавить новый параметр нужно сделать несколько вещей:
— уникальное имя, которое мы придумываем сами. Будем его использовать при настройке элемента данных в Zabbix.
— команда, которую нужно выполнить на наблюдаемом узле сети.
А вот сразу очень простой пример, который лежит в каждом стандартном конфиге для Linux:
и затем выставляем ключ такой же, как указали в конфиг-файле, а тип Zabbix агент:
Мониторинг SMART через UserParameter
Пример выше имеет мало практического применения, учитывая, что уже итак существует стандартный ключ system.users.num, который делает ровно тоже самое.
Так что теперь рассмотрим пример, который уже больше будет походить на реалистичный.
Если нам интересно мониторить момент, когда пора планово менять жесткие диски, то есть два варианта:
и утилита готова к использованию.
Для каждого диска, который есть в системе сначала проверим, что SMART включен:
если вдруг SMART поддерживается диском, но выключен, то активируем его:
Теперь мы можем проверять статус SMART командой:
Именно эту команду мы и запишем в наш zabbix_agentd.conf:
где uHDD.health — ключ.
Мониторинг SMART через Flexible UserParameter
Тут возникает резонный вопрос, как быть если дисков два. Легче всего решить эту проблему поможет способность UserParameter передавать параметры агенту, про которую мы еще не упоминали. Но делается все очень просто, сразу пример:
В веб-интерфейсе Zabbix в ключе мы будем подставлять параметры в квадратные скобки вместо *. Например, для одного элемента данных мы напишем sda, а для другого sdb. В команде этот параметр найдет отражение там, где стоит переменная $1.
Создадим для второго диска элемент данных:
И через некоторое время сможем наблюдать результат в последних данных:
Мониторинг SMART через Flexible UserParameter c Low-level Discovery
Все получилось. Но тут возникает резонный вопрос, как быть если дисков не два, а двадцать два. И тут нам пригодится замечательная возможность низкоуровнего обнаружения (LLD), про которую мы уже говорили.
Низкоуровневое обнаружение позволяет системе мониторинга обнаруживать какое количество однотипных элементов присутствует на узле сети и динамически по шаблону создавать необходимые элементы данных, триггеры и графики для этих элементов. «Из коробки» системе доступна возможность находить файловые системы, сетевые интерфейсы и SNMP OID’ы. Однако, и здесь разработчики оставили возможность дополнить стандартные возможности, нужно просто передать в систему информацию о том, какие элементы обнаружены в формате JSON. Этим и воспользуемся.
Создадим маленький скрипт на perl, smartctl-disks-discovery.pl. Он будет находить все диски в системе и выводить эту информацию в JSON, передавая также информацию, включен ли у диска SMART или нет, а также попытается сам включить SMART, если он выключен:
При запуске скрипт выдает:
Теперь, для того чтобы скрипт автоматически запускался Zabbix’ом, просто добавим еще один UserParameter в zabbix_agentd.conf:
Покончив с настройкой конфига, переходим в веб-интерфейс, где создаем новое правило обнаружения для smartctl:
Обратите внимание на ключ и на фильтр, (<#SMART_ENABLED>=1) благодаря последнему будут добавляться только те обнаруженные диски, которые поддерживают SMART. Теперь мы можем переписать два наших элемента данных для дисков sda и sdb в один прототип элементов данных, просто заменив имя диска на макрос <#DISKNAME>:
Последнее, перед тем, как Zabbix сможет запускать команды, которые мы прописали в zabbix_agentd.conf из-под root и мониторить SMART, нужно добавить разрешения для его пользователя запускать эту команду без ввода пароля, для этого добавим в /etc/sudoers строчку:
Готовый шаблон для мониторинга SMART с остальными элементами данных, триггерами прикладываю, так же как и настроенный под него конфиг.
Контроль за установкой новых программ на Windows
Zabbix агент, установленный на Windows, точно также может быть расширен через UserParameter, только команды будут уже другие. Хотя, например, smartctl — кроссплатформенная утилита, и точно также можно ее использовать для контроля за жесткими дисками в Windows.
Кратко рассмотрим еще другой пример. Задача получать уведомление каждый раз, когда пользователь самостоятельно удаляет или устанавливает программы.
Для этого будем использовать наш vbs-скрипт:
Для его интеграции с Zabbix добавим UserParameter в конфиг-файл:
Добавим элемент данных в шаблон для Windows:
Добавим триггер:
и действие, которое будет отправлять e-mail уведомление:
Весь процесс мониторинга выглядит так: каждый час запускается скрипт Zabbix агентом, который сравнивает два списка программ: текущий и предыдущий. Затем скрипт выписывает все изменения в отдельный файл. Если же изменений нет, то в файл пишется 0x0
Содержимое файла уходит на Zabbix сервер, где поднимается триггер в случае, если значение элемента данных uDiffProgramms отлично от 0x0. Затем отдельное действие отправляет по почте уведомление со списком того, что было установлено или удалено на данном компьютере:
В итоге
UserParameter — отличная и простая возможность расширить функционал системы самостоятельно. Стоит упомянуть и альтернативы: zabbix_sender, который, например, подойдет для тех случаев, когда нужно отправлять данные в Zabbix не по расписанию, (как это делает UserParameter), а по какому-то событию; и system.run[], который похож на UserParameter, но удобнее тем, что не нужно вносить изменения во все конфиги агентов, достаточно просто добавить этот элемент данных в шаблон. Более того, в следующем крупном релизе Zabbix 2.2 нас ожидает еще один новый способ расширить возможности агента- это подключаемые модули. Ждем с нетерпением!
Вот так, считайте, что если вы можете узнать что-то о системе скриптом или командой, значит, вы всегда можете передать это в Zabbix.