Zabbix - это open source система мониторинга, универсальный инструмент для отслеживания работы серверного и сетевого оборудования, сервисов и приложений. В нашем банке на мониторинге zabbix стоит более 4000 хостов, на большинстве хостов реализованы уникальные проверки. По триггерам многих хостов рассылки происходят на разные группы оповещений, то есть с одного хоста оповещения о разных триггерах рассылаются на разные группы. В связи с этим мы только планируем переход на более новую версию zabbix.

В этой статье описана логика рассуждений при необходимости реализации уникальных проверок в том случае, если рецепты с githab по каким-то причинам не подходят. Также подробно рассмотрены создание userparameter и preprocessing javascript.

Когда я впервые увидела правила автообнаружения (Discovery rules), мне показалось, что это какая-то магия. Zabbix сам создает метрики, сам создает триггеры. Оказалось, что это очень нужная функция, доступная для освоения.

В данной статье будет рассмотрено автообнаружение на примере мониторинга учетных записей в AD с подробными объяснениями, как это можно использовать для других целей. Рецепт https://github.com/asand3r/zbx-adusers мне не подошел. Задача следующая: у разных подразделений есть технические доменные учетные записи (их немного). У учетных записей может истечь пароль, их могут просто отключить, или они могут заблокироваться, и тогда сервис остановится. Нужно средствами в заббикс мониторить количество дней до истечения пароля и другие важные свойства, и оповещать конкретные подразделения по разным каналам. Кроме того, нужно все это выводить на разные дашборды в графане, чтобы владельцы учетной записи могли видеть нужные свойства всегда, а не только в течение 90 дней до истечения пароля. У нас сроки пароля разные для разных (УЗ) учетных записей. Но повторюсь, суть не в моей задаче. А в том, как использовать автообнаружение для своей задачи, как изобрести свой конкретный велосипед, когда магазинные в чем-то не устраивают.

Давайте рассмотрим, в каких ситуациях стоит использовать автообнаружение.

Условие: Объекты должны быть однотипные, и нам нужно мониторить какое-то одно и то же свойство у каждого.

Когда стоит использовать автообнаружение:

  • Объектов слишком много, и не хочется создавать вручную кучу почти одинаковых метрик и триггеров.

  • Объектов любое количество, но они могут динамически появляться и исчезать. Например, сертификаты на сервере. Сегодня у нас пять сертификатов, завтра один убрали и добавили два новых. Или у нас в папке создается каждый день новый файл с именем даты, и нам нужно следить, появился он или нет.

Шаги автообнаружения.

1. Что собственно будем мониторить.

Берем один объект из нашего списка и создаем для него метрику. Например, нам нужно мониторить срок истечения пароля учетной записи. Берем тестовую учетную запись и думаем, как нам узнать, когда же истечет пароль. У меня есть удобный скрипт для этих целей. Нужно добавить, что мониторим мы с сервера (назовем его SERVER1), введенного в домен. Заббиксагент на нем запущен от доменной УЗ, которая имеет соответствующие права).

Get-ADUser -Identity petrov_pp -Properties msDS-UserPasswordExpiryTimeComputed,PasswordNeverExpires,Enabled,LockedOut| Select-Object  PasswordNeverExpires,@{Name="RemainingDays";Expression={(new-timespan -start (Get-Date) -end ([datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed"))).Days}},Enabled,LockedOut|Convertto-json

Кроме срока истечения пароля по этому скрипту мы получаем еще ряд важных параметров:

  • PasswordNeverExpires – истекает ли вообще пароль.

  • RemainingDays – сколько дней осталось до истечения пароль.

  • Enabled – включена ли УЗ (административно).

  • LockedOut – заблокирована ли УЗ.

Теперь нам нужно как-то заставить заббикс запустить этот скрипт самому. Для этого в zabbix_agentd.conf на сервере SERVER1 добавляем userparameter:

UserParameter=account[*],C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Get-ADUser -Identity $1 -Properties msDS-UserPasswordExpiryTimeComputed,PasswordNeverExpires,Enabled,LockedOut| Select-Object  PasswordNeverExpires,@{Name=\"RemainingDays\";Expression={(new-timespan -start (Get-Date) -end ([datetime]::FromFileTime($_.\"msDS-UserPasswordExpiryTimeComputed\"))).Days}},Enabled,LockedOut|Convertto-json"

Обратите внимание на следующие моменты:

  1. account[*]. Слово "account" – это мы сами придумываем, но это тот самый ключ, который будет дергать заббикс. После чего заббикс-агент будет запускать команду после запятой.

    * указывает на то, что вместо нее можно вставить любое значение. На это значение будет заменено $1 в скрипте. Например, если мы в заббиксе укажем ключ account[petrov_pp], заббикс агент запустит указанный выше скрипт для -Identity petrov_pp.

  2. Все двойные кавычки внутри скрипта должны быть экранированы. Это крайне важно!

Итак, у нас есть рабочая метрика. Теперь нужно заббиксу сообщить, какие же объекты ему нужно создать.

2. Найти объекты автообнаружения.

Zabbix должен как-то найти объекты, для которых нужно создать метрики и триггеры. Найти он их может из результатов отдельной метрики. Лучше создать именно отдельную метрику, чтобы всегда знать, что заббикс получает на входе. Однажды автообнаружение может сломаться, и только вывод этой самой ключевой метрики покажет, что не так.

На нашем примере по учетным записям исходно такого объекта нет. Подразделения сами обращаются и просят мониторить конкретные УЗ. Мы можем создать файлик на нашем SERVER1 со списком этих УЗ определенного формата. Файлик этот нужно положить в ту папку, которую может читать zabbix agent на хосте. Метрика заббикса будет этот список читать и получать нужную информацию.

Создаем метрику:

  • Name accounts_txt;

  • Type Zabbix agent;

  • Key vfs.file.contents[C:\Zabbix\Scripts\accounts.txt].

Но как заполнять этот файлик? Как привести эти данные к нужному формату?

Заббикс хорошо понимает формат json:

{"data":[{"{#ACC}": "petrov_pp","{#TAG}": "otdel1"}, {"{#ACC}": "smirnov_ii","{#TAG}": "otdel2"}, {"{#ACC}": "ivanov_mm","{#TAG}": "otdel3"}]}

Здесь у нас представлены две переменные {#ACC} и {#TAG}. Это макросы, которые мы сможем использовать в прототипах метрик и триггеров.

Всего в этом примере три объекта, у каждого объекта по два свойства. Первый объект – это {"{#ACC}": "petrov_pp","{#TAG}": "otdel1"}. В данном случае имя учетной записи petrov_pp, а второе свойство нам понадобиться для триггеров.

Таким образом, мы можем создать файлик такого формата и добавлять в него новые объекты. Но вдруг сотрудник, который будет добавлять, ошибется в скобочках? И всё разом сломается.

Поэтому решено было сделать самый простой файлик и с помощью препроцессинга преобразовывать его к нужному формату.

Файл следующего вида:

petrov_pp otdel1
smirnov_ii otdel2
ivanov_mm otdel3

Далее делаем препроцессинг для этой метрики с помощью javascript.

Вообще javascript – это великая мощь! Он позволяет из одного текста сделать совершенно другой, тот, что нам нужен, сохранив важные нам переменные значения исходного текста. Освоив его, Вам станет абсолютно все равно, в каком виде приходят данные в заббикс.

Скрипт препроцессинга:

var str_new=value.replace(/\r\n/g,',')
var str_new1=str_new.replace(/ /g,';')
var str_new2=str_new1.replace(/\,/g,'"}, {"{#ACC}": "')
var str_new5=str_new2.replace(/;/g,'","{#TAG}": "')
var strnew3 = "\{\"data\"\:\[\{\"\{\#ACC\}\"\: \"";
strnew3 += str_new5;
strnew3 += "\"\}]\}";
return strnew3

Немного о функции замены.

value.replace(/aaa/g,'bbb')

value – переменная, в которой текст, подлежащий замене. Изначально, всё, что получила метрика заббикс, попадает в переменную value.

Рассмотриv, что на что заменяется на примере (/aaa/g,'bbb').

aaa - то, что хотим заменить. Часто нужно экранировать спецсимволы обратной коcой чертой \ .

Особняком здесь стоит символ нижнего подчеркивания. При необходимости заменить строку с нижним подчеркиванием, нужно его обрамить круглыми скобками. Например, хотим заменить good_evening.

Пишем (/good(_)evening/g,'bbb').

bbb – на что хотим заменить.

g – заменять столько раз, сколько встречается выражение aaa.

Теперь рассмотрим код скрипта по строкам:

Строка 1. в переменную str_new записыванием исходный текст, в котором все enter заменены запятыми. Шаг необязательный, но захват нечитаемых символов очень неочевидная вещь. Если мы просто попытаемся протестировать работу этой строки на тексте из latest data заббикса, то не получим нужный результат. А вот если скопируем из блокнота на SERVER1, то получим. Вот такая особенность. В latest data не всегда точно отображается то, что получает метрика.

Строка 2. Заменяем все пробелы на точку с запятой.

Строка 3. Заменяем все запятые на "}, {"{#ACC}": "

Строка 4. Также производим замену, аналогично строке 3.

Строки 5-7: собираем в переменную strnew3 по порядку указанные значения.

Строка 8. Выводим значение итоговой переменной в метрику заббикс. При отладке мы можем указать любую из указанных выше переменных, чтобы посмотреть каждое преобразование.

То есть у нас был исходный текст и был желаемый текст. И здесь указано, что на что нужно заменить, чтобы исходный текст превратился в желаемый. Также можно поступить при необходимости автообнаружения файла с именем в виде текущей даты. Мы берем метрику localtime, и Javascript, преобразовываем вывод в нужный вид.

3. Создать правила автообнаружения.

В zabbix на  SERVER1 создаем новое правило автообнаружения. Правило автообнаружения – это по сути та же метрика, результат которой мы непосредственно посмотреть не можем. Поэтому я всегда делаю ее зависимой метрикой. В данном случае, это зависимая метрика от accounts.txt.

Параметры следующие:

  • Name accounts_discovery;

  • Type Dependent item;

  • Key accounts_discovery;

  • Master item SERVER1: accounts_txt;

  • Keep lost resources period 1h.

Период сохранения потерянных ресурсов следует выбирать исходя из задачи.

Вопрос: где стоит прикручивать препроцессинг? На правиле обнаружения или на исходной метрике?

Я стараюсь прикручивать препроцессинг на правило автообнаружения, потому что исходная метрика может пригодиться для других проверок. Но при тестировании автообнаружения вначале следует прикрутить препроцессинг к исходной метрике, а после успешного тестирования уже перенести на правило автообнаружения.

4. Создать прототипы метрик и триггеров.

Напомню, что наш скрипт возвращает следующие данные:

{ "PasswordNeverExpires":  false,
    "RemainingDays":  23,
    "Enabled":  true,
    "LockedOut":  false }

Имеет смысл сделать основной прототип метрики, которая возвращает все эти данные, и 4 зависимых прототипа метрик.

Основной прототип метрики:

  • Name {#ACC};

  • Type Zabbix agent;

  • Key account[{#ACC}].

Также можно добавить прототип приложения. То есть все наши 5 метрик будут в одном приложении, которое будет носить имя УЗ. Это удобно для отображения результатов в grafana.

New application prototype {#ACC}

 Я предпочитаю переводить такого рода данные в нормальный Json format следующим скриптом препроцессинга (javascript).

var strnew = "\{\"data\"\:\[ ";
strnew += value;
strnew += "\]\}";
return strnew;

В результате будут создаваться метрики, в имени которых будет имя аккаунта из списка.

Далее необходимо создать еще 4 прототипа метрик.

Для метрики по определению включена УЗ или нет, например:

  • Name {#ACC} Enabled;

  • Type Dependent item;

  • Key Enabled_[{#ACC}];

  • Master item SERVER1: {#ACC};

  • Application prototypes {#ACC}.

Обратите внимание, здесь в качестве master item выбираем item prototype.

В препроцессинге выбираем Jsonpath $.data[0].Enabled.

Почему так?

Давайте рассмотрим наш итоговый вывод по конкретной УЗ:

{"data":[ {
    "PasswordNeverExpires":  true,
    "RemainingDays":  null,
    "Enabled":  true,
    "LockedOut":  false
}]}

У нас здесь один объект с четырьмя свойствами. Наш Jsonpath берет нулевой объект (отсчет идет с нуля) и считывает значение свойства Enabled.

Если бы у нас было несколько объектов в {}  через запятую и нам нужно было бы свойство LockOut третьего, например, объекта, мы бы написали:

$.data[2].LockedOut

В нашем случае объект один, поэтому в квадратных скобках будет только 0, а меняться будет только последнее слово.

Например, метрика по количеству дней до истечения пароля будет иметь следующий препроцессинг:

$.data[0].RemainingDays

Обратите внимание, в прототипе этой метрике тип данных должен быть числовой.

После создания всех нужных прототипов метрик нужно создать прототипы триггеров на свой вкус.

  • Name До истечения пароля учетной записи {#ACC} осталось < 10 дней;

  • Expression {SERVER1:RemainingDays_[{#ACC}].last()}<10.

А теперь для чего же мы вводили {#TAG}?

У нас триггеры по одному серверу направляются на разные группы оповещения исходя из trigger tag. Изменить или добавить тег в триггер, созданный автообнаружением, невозможно. Поэтому добавляем его здесь.

triggertag {#TAG}

Мы могли бы добавить третью переменную и писать что-нибудь в комментарий.

Заключение

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

Комментарии (0)