Zabbix 3.0.4: Агент Windows с TLS, LLD дисков, простой пример S.M.A.R.T. и только командная строка

    Будем считать, что сервер Zabbix 3.0.4 у нас установлен. Для скриптов установки агента будем использовать, по хардкору, только родную командную строку Windows, без питонов, перлов и т.п., т.е. без дополнительных инсталляций в систему агента. Шифрование настроим с помощью PSK.

    Внешний IP Zabbix сервера пусть будет — 30.0.1.1
    Локальный IP Zabbix сервера – 10.3.10.1
    Адрес тестового узла – 30.0.1.3
    По форвардинг портов тут говориться не будет. Узел в примере будет слушать 10050, сервер – 10051.

    Постановка задачи:

    1) Упростить установку агентов на системы Windows
    2) Настроить шифрование между агентом и сервером.
    3) Настроить обнаружение дисков (имена, модели, серийные номера, типы) c помощью утилиты smartmontools, контроль S.M.A.R.T.
    4) Создать масштабируемый шаблон сценария развёртывания.
    5) Настроить оповещение.
    6) Использовать только командную строку.

    Агенты Windows почему-то ещё не имеют поддержку TLS, но есть скомпилированные версии, которые можно скачать отсюда. Обсуждение.

    Распаковываем. Нам понадобится только каталог bin. Дефолтный конфиг нам не понадобится.

    Создаём каталог zabbix и копируем в него каталог bin из распакованного агента. Далее создаём в каталоге zabbix подкаталоги conf, disks, logs, psk, scripts, smartmontools. Сразу примем решение что размещать папку zabbix мы будем в корне тома C:\


    conf – тут будет файл конфига
    disks – сюда будет генерироваться информация о дисках в JSON
    logs – логи
    pks – тут будет лежать файл Z_agent.psk содержащий pre-shared ключ
    scripts – скрипты
    smartmontools – сюда помещаем одноимённую программу S.M.A.R.T.

    Сразу подготовим PSK ключи и файл данных. Создаём на сервере файл pskgen4ik:

    #!/bin/bash
    echo -n  "Сколько ключей нужно? : "
    read LIMIT
    a=1
    echo \# > /home/appliance/agent_psk
    while [ "$a" -le $LIMIT ]
    do
      openssl rand -hex 64 >> /home/appliance/agent_psk
      let "a++"
    done
    less /home/appliance/agent_psk

    Сохраняем, делаем исполняемым (chmod +x ), запускаем, и копируем результат в файл данных, я приведу пример Excel для наглядности. Можно использовать и базу данных. Что-то типа этого:



    Поле Host name мы заполним после создания конфига агента (если конечно же нет уже составленного списка). Придумываем и дописываем уникальные идентификаторы PSK ID. Сохраняем файл данных, делаем бэкап, строго ограничиваем к нему доступ и удаляем файл «agent_psk». Всё у нас есть файл данных с ключами и идентификаторами, которые будем использовать.

    S.M.A.R.T.


    Для получения информации о дисках и их S.M.A.R.T используем утилиту Smartmontools. Я беру последнюю версию 6.5. В этой версии нормально определяются паспорта USB, и новые манифесты для 10ки. Обо всех исправлениях в релизе.

    Скачиваем и кидаем в папку zabbix\smartmontools

    Знакомство с утилитой.


    Смотрим список подключенных дисков:

    c:\>"Program Files"\smartmontools\bin\smartctl.exe --scan 


    Ключ –d указывает на тип диска.

    Заинтересуемся диском /dev/sda. Пока он мало о чём говорит кроме того, что он ATA-типа и скорей всего загрузочный.

    Смотрим информацию о нём:

    c:\>"Program Files"\smartmontools\bin\smartctl.exe -i /dev/sda -d ata 


    Уже интересней. Как видно СМАРТ отключён. Включаем его:

    c:\>"Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on /dev/sda

    Смотрим таблицу атрибутов S.M.A.R.T.

    c:\>"Program Files"\smartmontools\bin\smartctl.exe -A /dev/sda -d ata


    Таблицу смарт у RAID посмотреть не получится, но статус health получить сможем.

    Смотрим SMART Health:

    c:\>"Program Files"\smartmontools\bin\smartctl.exe -H /dev/sda -d ata


    Теперь то же самое нужно сделать для остальных 1000 дисков ) Создавать для каждого шаблоны уже не может быть и речи, более того мне, например, ещё нужно получать модель и серийник каждого диска в отчёте. На помощь приходит Zabbix LLD.

    Поскольку Zabbix имеет возможность обработки данных по протоколу JSON, предоставленной его API, мы будем генерить нужную информацию из smartmontools в JSON формат и пассивно передавать на сервер.

    Начинаем создавать сценарии. Для начала придумаем макросы обнаружения и определимся с данными:
    Макрос {#DISKPORT} — имя диска в системе (/dev/sda, /dev/sdb и т.д.),
    Макрос {#DISKTYPE} — тип диска (ata,scsi,sat, csmi и т.д.),
    Макрос {#DISKMODEL} – модель диска,
    Макрос {#DISKSN} — серийный номер.

    Создаём в каталоге zabbix\scripts файл DiskInfoGenerationJSON.cmd следующего содержания:

    @echo off
    echo @echo off > c:\zabbix\disks\disks.cmd
    echo echo {"data": >> c:\zabbix\disks\disks.cmd
    echo echo    [ >> c:\zabbix\disks\disks.cmd
    for /F "tokens=1,3" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^
    do (for %%s in ("Device Model" "Product") ^
    do (for /F "tokens=2*" %%c in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%s ') ^
    do (for %%i in ("Serial Number") do (for /F "tokens=3*" %%k in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%i ') ^
    do echo echo      {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},>> c:\zabbix\disks\disks.cmd))))
    echo echo      {"{#SMARTV}":"Smartctl 6.5"}>> c:\zabbix\disks\disks.cmd
    echo echo    ] >> c:\zabbix\disks\disks.cmd
    echo echo } >> c:\zabbix\disks\disks.cmd
    

    Сохраняем DiskInfoGenerationJSON.cmd

    Мне не удалось упрощённо решить проблему последней запятой с помощью cmd (да я и не начинал её решать, ибо это бред сумасшедшего), в строке…

    {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},

    … которая нарушает синтаксис JSON. Поэтому я просто добавил строчку {"{#SMARTV}":«Smartctl 6.5»}, которая закрывает тело без запятой.

    При запуске файла DiskInfoGenerationJSON.cmd. В итоге мы должны получить файл c:\zabbix\disks\disks.cmd со следующим содержимым:



    Создаём в каталоге zabbix\scripts файл GetSmartAllDisk.cmd следующего содерания:

    rem включаем СМАРТ у всех дисков которые это позволят:
    for /F "tokens=1" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^
    do "C:\Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on %%a

    Сохраняем GetSmartAllDisk.cmd

    Генерации конфига


    Генерация будет разбита на две части: настройки подключения и пользовательские параметры.

    Создание конфига


    Анализируем будущий конфигурационный файл агента:

    LogFile=C:\zabbix\logs\logs.log  	# журнал логов
    LogFileSize=100 			# ограничение размера файла логов
    Server=30.0.1.1			# сервер пассивных проверок
    ServerActive=30.0.1.1		# сервер активных проверок
    StartAgents=3 			# кол-во пре-форков
    Timeout=30 				# не более 30 сек на обработку
    Hostname=				# уникальное имя хоста
    
    # TLS
    TLSConnect=psk			# тип исходящих подключений (активная проверка)	
    TLSAccept=psk			# тип входящих подключений (пассивная проверка)	
    TLSPSKFile=C:\zabbix\psk\Z_agent.psk	# путь к файлу с pre-shared ключом
    TLSPSKIdentity=			# уникальный идентификатор
    

    Уникальными для каждого хоста тут являются поля Hostname= и TLSPSKIdentity= в конфигурационном файле. А также pre-shared ключ в файле zabbix\psk\Z_agent.psk. Следовательно, определим эти значения в переменные.

    В каталоге zabbix\scripts создаём файл AgentConfigGeneration.cmd:

    @echo off
    chcp 866 > nul
    set /P CLIENT="Enter Organization name: "
    set /P PSKID=" Enter PSKIdentity: "
    set /P PSKkey="Enter PSKkey: "
    
    rem Генерация конфига
    @echo # zabbix_agent 3.0.1> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >>C:\zabbix\conf\zabbix_agentd.conf
    @echo %PSKkey%>>C:\zabbix\psk\Z_agent.psk
    @echo LogFile=C:\zabbix\logs\logs.log >> C:\zabbix\conf\zabbix_agentd.conf
    @echo LogFileSize=100 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Server=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo ServerActive=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo StartAgents=3 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Timeout=30 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Hostname=%CLIENT%.%COMPUTERNAME%>> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >> C:\zabbix\conf\zabbix_agentd.conf
    
    @echo ##### TLS ###########>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSConnect=psk>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSAccept=psk>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSPSKFile=C:\zabbix\psk\Z_agent.psk>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSPSKIdentity=%PSKID%>> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >> C:\zabbix\conf\zabbix_agentd.conf

    Всё просто. При запуске вводим название организации, например, Organization1 и получаем Hostname в конфиге в виде «Organization1.Имя_хоста». В пределах сети одной организации как правило исключается использование одинаковых имён узлов, поэтому мы будем иметь уникальные имена. Далее вводим PSK ID из ранее составленного файла данных и ключ. Но пока мы ничего не запускаем.

    Добавление в конфиг пользовательских параметров


    В каталоге zabbix\scripts создаём файл UserParameters.txt, который будет содержать пользовательские параметры (UserParameter=<ключ>,<shell команда>)

    ##### Обнаружение дисков.
    UserParameter=HDD.discovery,for /F "tokens=*" %a in ('C:\zabbix\disks\disks.cmd') do @echo %a
    
    ##### S.M.A.R.T.
    # RAW_VALUE
    UserParameter=HDD.raw[*], for /F "tokens=10" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a
    # VALUE
    UserParameter=HDD.value.[*], for /F "tokens=4" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2^| find "$3"') do @echo %a
    # WORST
    UserParameter=HDD.worst.[*], for /F "tokens=5" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a
    # THRESOLD
    UserParameter=HDD.thresh.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a
    # WHEN_FAILED
    UserParameter=HDD.when.failed.[*], for /F "tokens=9" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a
    # HEALTH Status
    UserParameter=HDD.health.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -H $1 -d $2 ^| find "test"') do @echo %a
    

    Сохраняем UserParameters.txt. Мы придумали ключи и циклы для получения данных. И в конец файла AgentConfigGeneration.cmd добавляем следующую строчку:

    type C:\zabbix\scripts\UserParameters.txt>> C:\zabbix\conf\zabbix_agentd.conf

    Нам ещё нужно открыть порт на узле, если брандмауэр включён. Создаём файл OpenLocalPort.cmd

    @echo off
    
    set localportname=10050
    set rulename=zabbix
    set dirrname=in
    set protocolname=TCP
    set actionname=allow
    netsh advfirewall firewall add rule name=%rulename% dir=%dirrname% action=%actionname% protocol=%protocolname% localport=%localportname%

    Итак, сценарии мы написали. Вот что у нас получается:


    Теперь нужно определиться в очерёдности запусков этого добра:

    1) Ввод переменных
    2) Установка smartmontools в тихом режиме
    3) Установка службы Zabbix Agent
    4) Генерация конфига с пользовательскими параметрами — AgentConfigGeneration.cmd
    5) Генерация списка дисков — DiskInfoGenerationJSON.cmd
    6) Включение S.M.A.R.T. — GetSmartAllDisk.cmd.cmd
    7) Открыть порт — OpenLocalPort.cmd
    8) Запуск службы Zabbix Agent

    Создаём в корне каталога zabbix файл INSTALL_AGENT.cmd и объединяем в нём все шаги наших сценариев:

    @echo off
    chcp 866 > nul
    set /P CLIENT="Client NAME: "
    set /P PSKID="PSKIdentity: "
    set /P PSKkey="Enter PSKkey: "
    cls
    
    rem Устанавливаем smartmontools в тихом режиме
    C:\zabbix\smartmontools\smartmontools-6.5-1.win32-setup.exe /S
    
    rem Открывает порт 10050 в брандмауэре
    set localportname=10050
    set rulename=zabbix
    set dirrname=in
    set protocolname=TCP
    set actionname=allow
    netsh advfirewall firewall add rule name=%rulename% dir=%dirrname% action=%actionname% protocol=%protocolname% localport=%localportname%
    echo "port %localportname% was open on host %hostname%"
    
    rem создание конфига
    @echo # zabbix_agent 3.0.1> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >>C:\zabbix\conf\zabbix_agentd.conf
    @echo %PSKkey%>C:\zabbix\psk\Z_agent.psk
    @echo LogFile=C:\zabbix\logs\logs.log >> C:\zabbix\conf\zabbix_agentd.conf
    @echo LogFileSize=100 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Server=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo ServerActive=30.0.1.1 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo StartAgents=3 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Timeout=30 >> C:\zabbix\conf\zabbix_agentd.conf
    @echo Hostname=%CLIENT%.%COMPUTERNAME%>> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >> C:\zabbix\conf\zabbix_agentd.conf
    @echo ##### TLS ###########>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSConnect=psk>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSAccept=psk>> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSPSKFile=C:\zabbix\psk\Z_agent.psk >> C:\zabbix\conf\zabbix_agentd.conf
    @echo TLSPSKIdentity=%PSKID%> C:\zabbix\conf\zabbix_agentd.conf
    @echo. >> C:\zabbix\conf\zabbix_agentd.conf
    rem Добавляем пользовательские параметры
    type C:\zabbix\scripts\UserParameters.txt>> C:\zabb\conf\zabbix_agentd.conf
    
    rem Создание списка дисков
    @echo off
    echo @echo off > c:\zabbix\disks\disks.cmd
    echo echo {"data": >> c:\zabbix\disks\disks.cmd
    echo echo    [ >> c:\zabbix\disks\disks.cmd
    for /F "tokens=1,3" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^
    do (for %%s in ("Device Model" "Product") ^
    do (for /F "tokens=2*" %%c in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%s ') ^
    do (for %%i in ("Serial Number") do (for /F "tokens=3*" %%k in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%i ') ^
    do echo echo      {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},>> c:\zabbix\disks\disks.cmd))))
    echo echo      {"{#SMARTV}":"Smartctl 6.5"}>> c:\zabbix\disks\disks.cmd
    echo echo    ] >> c:\zabbix\disks\disks.cmd
    echo echo } >> c:\zabbix\disks\disks.cmd
    
    rem Включение смарт на всех дисках
    for /F "tokens=1" %%a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe --scan') ^
    do "C:\Program Files\smartmontools\bin\smartctl.exe" --smart=on --offlineauto=on --saveauto=on %%a
    
    rem Установка службы Zabbix Agent
    if DEFINED ProgramFiles(x86) (goto :x64) else (goto :x86)
    :x64
    C:\zabbix\bin\win64\zabbix_agentd.exe -i -c C:\zabbix\conf\zabbix_agentd.conf
    goto :NEXT
    :x86
    C:\zabbix\bin\win32\zabbix_agentd.exe -i -c C:\zabbix\conf\zabbix_agentd.conf
    goto :NEXT
    
    :NEXT
    rem Запуск службы Zabbix Agent
    net start "Zabbix Agent"
    echo.
    echo OK!
    
    @echo ------------------------------------
    @echo Hostname: %CLIENT%.%COMPUTERNAME%
    @echo ------------------------------------
    @echo.
    Pause

    Упаковываем каталог zabbix в SFX-архив и шифруем паролем при необходимости

    Пример.


    Имеем сервер в организации «Организация 1». Помещаем zabbix.exe на сервер и распаковываем в корень тома C:\

    Запускаем INSTALL_AGENT.cmd от имени Администратора. Вводим без пробелов название Организации, копируем из файла данных идентификатор PSK и ключ:


    Enter:


    Проверяем файл логов C:\zabbix\logs\logs.log:


    Копируем Hostname “Organization1.SUNSET” в файл данных:


    И так далее с каждым хостом. После заполнения файла заходим в кабинет Zabbix — 10.3.10.1/zabbix — и добавляем из него группы, узлы. В настройках шифрования узла отмечаем PSK и ждём онлайна.



    Ждём несколько секунд:


    О шифровании и об ограничениях

    LLD


    Русифицирую кабинет для разнообразия )

    Создаём Шаблон S.M.A.R.T. и группы элементов данных. Для примера я создал следующие группы по атрибутам смарта:


    Выбираем «Правила обнаружения» и создаём правило:


    В поле «Ключ» указываем тот самый придуманный нами пользовательский параметр из файла C:\zabbix\scripts\UserParameters.txt

    UserParameter=HDD.discovery,for /F "tokens=*" %a in ('C:\zabbix\disks\disks.cmd') do @echo %a

    А во вкладке «Фильтры» пишем наши макросы из созданного файла c:\zabbix\disks\disks.cmd и жмём «Добавить»



    Создадим «Прототипы элементов данных»


    Я создам для примера два прототипа атрибута Spin_Retry_Count и добавлю в группу элементов данных Pre-fail: Spin_Retry_Count. Первый будет получать VALUE значение, второй THRESHOLD из таблицы атрибутов смарт для каждого обнаруженного диска
    Обратимся ещё раз к файлу C:\zabbix\scripts\UserParameters.txt (ну или уже созданному конфигу). И посмотрим какие циклы у нас вытаскивают нужные нам данные:

    UserParameter=HDD.value.[*], for /F "tokens=4" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2^| find "$3"') do @echo %a
    UserParameter=HDD.thresh.[*], for /F "tokens=6" %a in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -A $1 -d $2 ^| find "$3"') do @echo %a

    Как видно из скрипта для ключей HDD.value.[*] и HDD.thresh.[*] нам нужно на вход три аргумента $1 – диск (/dev/*), $2 – тип диска (ata,sat и т.д.), $3 – атрибут (в нашем случае Spin_Retry_Count). В итоге ключ получит такой формат HDD.value.[$1,$2,$3]. Например для нашего диска /dev/sda типа «ata», будет так HDD.value.[/dev/sda,ata,Spin_Retry_Count]. Но поскольку мы создали макросы для каждого обнаруженного диска, формат ключа в прототипе элемента данных будет таков HDD.value.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count]. Этот ключ будет перебирать каждый диск по данному атрибуту.

    Кстати, можем проверить ключ с сервера, c помощью zabbix_get

    root@zabbix:~# zabbix_get -s 30.0.1.3 -k HDD.value.[/dev/sda,ata,Spin_Retry_Count] --tls-connect psk --tls-psk-identity "ZP10001AA" --tls-psk-file /root/Organization1.SUNSET.psk
    


    И также для Threshold:


    Итак, создаём наш прототип данных для VALUE и используем пассивную проверку:



    Аналогично создаём прототип для Threshold. В итоге имеем:



    Создаём «Прототип триггера». Даём имя, например, для наглядности:

    S.M.A.R.T.: ВНИМАНИЕ! Диск {#DISKMODEL} ( {#DISKPORT} — {#DISKTYPE} ). Ожидается сбой и\или полный отказ диска в ближайшие 24 часа! Значение атрибута хуже критического порога

    В «Поле выражение» пишем условие:

    ({S.M.A.R.T.:HDD.value.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()}-{S.M.A.R.T.:HDD.thresh.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()})<0

    Смысл в том, что если Value меньше Threshold — нужно выдать проблему. Last() – показывает последнее полученное значение (подробней о функициях). В поле «Описание» пишем, например:

    Диск: {#DISKPORT}
    Тип дика: {#DISKTYPE}
    Модель: {#DISKMODEL}
    Серийный номер: {#DISKSN}
    
    Объяснение:
    
    Threshold — это порог: если Value больше Threshold — атрибут в порядке; если меньше либо равен — с атрибутом проблемы. Именно по такому критерию утилиты, читающие S.M.A.R.T., выдают отчёт о состоянии диска либо отдельного атрибута вроде «Good» или «Bad».
    
    Если VALUE стало меньше THRESH в случае Pre-fail атрибута - существует большая вероятность, что диск вылетит в ближайшие 24 часа.
    
     / Spin_Retry_Count /
    Число повторных попыток раскрутки дисков до рабочей скорости в случае, если первая попытка была неудачной. Если значение атрибута увеличивается, то велика вероятность неполадок с механической частью.

    Важность ставим «Чрезвычайная»


    Будем считать, что оповещение у нас настроено по EMAIL. Если нет, то сюда.

    Идём в «Настройка» > «Действия». Создаём форму репорта. Жмём «Создать действие»

    Имя: Отчёты о проблемах
    Тема по умолчанию: ПРОБЛЕМА! [ {HOST.NAME} ] — {TRIGGER.NAME} ({EVENT.ID})
    Сообщение по умолчанию:

    Обнаружена проблема!
    Категория: {TRIGGER.SEVERITY}
    
        Узел: {HOST.NAME}
        Описание узла: {HOST.DESCRIPTION}
        Дата: {EVENT.DATE}
        Время: {EVENT.TIME}
    
    {TRIGGER.NAME}
    
    Описание события:
    {TRIGGER.DESCRIPTION}
    
    Проблема получена на основе сл. данных:
    1. {ITEM.NAME1} = {ITEM.VALUE1}. Ключ: {ITEM.KEY1}
    2. {ITEM.NAME2} = {ITEM.VALUE2}. Ключ: {ITEM.KEY2}
    {TRIGGER.EXPRESSION}
    
    Event ID: {EVENT.ID}
    

    Заполняем сообщение о восстановлении:
    Тема восстановления: ОК. [ {HOST.NAME} ]
    Сообщение о восстановлении:

    Проблема события "{EVENT.ID}" сейчас устранена.
    
        Узел: {HOST.NAME}
        Описание узла: {HOST.DESCRIPTION}
        Дата и время события: {EVENT.DATE} {EVENT.TIME}
        Дата и время восстановления: {EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME}
    
    Ранее была проблема: {TRIGGER.NAME}
    Категория: {TRIGGER.SEVERITY}
    Нынешний статус: ИСПРАВЛЕНО
    
    Данные:
    1. {ITEM.NAME1} = {ITEM.VALUE1}. Ключ: {ITEM.KEY1}
    2. {ITEM.NAME2} = {ITEM.VALUE2}. Ключ: {ITEM.KEY2}
    
    URL: {TRIGGER.URL}
    Event ID: {EVENT.ID}
    

    Включим «Активировать»

    Переходим на вкладку «Условия» и заполняем как показано ниже:


    Я указал только «Чрезвычайные» проблемы для примера. Условия можно задавать какие душе угодно.

    Переходим во вкладку «Операции» и добавляем либо группу нашего пользователя, либо указываем только себя. Тут в принципе комментировать нечего.


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

    ({S.M.A.R.T.:HDD.value.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()}-{S.M.A.R.T.:HDD.thresh.[{#DISKPORT},{#DISKTYPE},Spin_Retry_Count].last()})>0

    Арифметику думаю объяснять не нужно.

    Ждём некоторое время и получаем проблему:


    И спустя пару секунд приходит сообщение на почту:


    После восстановления получим следующее сообщение:


    Если есть ошибки, или что-то можно делать проще, пожалуйста сообщите! Писал тему пару часов со скринами, вроде дважды проверил на удачно.

    Скачать готовый шаблон

    PS: Особенного огонь когда zabbix отсылает поставщику сообщение с просьбой выставить счёт на новый диск или, например, когда заканчивается тонер в принтере кидает саппорту тикет на заправку картриджа, но это уже другая история…
    Share post

    Similar posts

    Comments 13

      +1
      Спасибо за статью. По поводу ошибок не знаю, но вот на Powershell скрипты точно были бы проще и понятнее.
        0
        Ну не знаю куда уж проще cmd имхо ) На powershell кода было бы больше
        +1
        Спасибо, статья интересная и подробно описана.
        Есть одна оговорка. SMART для дисков за контроллером в некотором случае получить можно. Для этого есть ключ "-d". Тут лучше сказать, что за контроллером чаще всего стоят SAS диски, у которых вывод SMART упрощенный.
          0
          Очень круто! А можно шаблон?
            0
            Без проблем. Позже скину
            0
            Спасибо, очень интересно! прям руки зачесались внедрить для особо важных машин (для моей например).
            Маленькая придирка: уберите пожалуйста символ ">" из путей в разделе «знакомство с утилитой»
            как то так:

            было
            c:\>"Program Files"\smartmontools\bin\smartctl.exe --scan 
            


            стало
            c:\"Program Files"\smartmontools\bin\smartctl.exe --scan 
            
              0
              Круто, надо попробовать обновиться
                0
                Сурово!
                  0
                  А для чего вывод скрипта DiskInfoGenerationJSON.cmd перенаправлять в файл? Почему его сразу не использовать как discovery script?
                  В вашем случае нет динамического автообнаружения новых дисков/удаления старых, т.к. disks.cmd один раз сформировали и всё.
                    0
                    Конечно можно и так. Только если мы не хотим отслеживать замену без нашего ведома (утащю ка я диск по тихому). Иначе создаётся отдельный ключ и добавляется в папку scripts то что вы предложили. Данные обновляемого списка сравниваются с disks.cmd. Если данные отличаются — создаётся триггер и по проблеме удалённо запускается DiskInfoGenerationJSON.cmd. Мы обновили список дисков и имеем доказательную базу замены/удаления. К сожалению всё в одно статье не описать. Поэтому приведены только основы для творчества.
                    0
                    Потрясающий материал и впечатляющий объем проделанной работы. Как раз возникла потребность реализовать данное решение.
                    Не затруднит ли вас выложить готовый архив с шаблоном и готовыми скриптами заббикс-агента.
                      0
                      Добавил ссылку в конец статьи.
                      0
                      Немного извращенного кода)))
                      @echo off
                      set tmpfile=c:\zabbix_station\scripts\disks_tmp.cmd
                      echo @echo off > %tmpfile%
                      echo echo {"data": >> %tmpfile%
                      echo echo [ >> %tmpfile%
                      for /F "tokens=1,3" %%a in ('"C:\Program Files\smartmontools\bin\smartctl.exe" --scan') ^
                      do (for %%s in ("Device Model" "Product") ^
                      do (for /F "tokens=2*" %%c in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%s ') ^
                      do (for %%i in ("Serial Number") do (for /F "tokens=3*" %%k in ('C:\"Program Files"\smartmontools\bin\smartctl.exe -i %%a -d %%b ^| find %%i ') ^
                      do echo echo {"{#DISKPORT}":"%%a","{#DISKTYPE}":"%%b","{#DISKMODEL}":"%%d","{#DISKSN}":"%%k"},>> %tmpfile%))))
                      echo echo {"{#SMARTV}":"Smartctl 6.5"}>> %tmpfile%
                      echo echo ] >> %tmpfile%
                      echo echo } >> %tmpfile%
                      echo exit >> %tmpfile%
                      start cmd /C "ping -n 2 127.0.0.1 > nul && del %tmpfile%"
                      %tmpfile%

                      Only users with full accounts can post comments. Log in, please.