UserParameters – Zabbix Tutorials

Alert скрипт

Собственно сам скрипт, который будет отправлять письма и выполнять наши функции:

Example 1

Starting as simple as possible.

I create an item to check isalive

Low-level discovery

Что касается смартов, то обычные Items и Triggers нам не подойдут, т. к. на разных машинах может быть разное количество смартов. В zabbix есть возможность сделать item и trigger prototype, которые будут создаваться для списка объектов, полученных с помощью low-level discovery rules, подробнее можно почитать

. Чтобы правило работало, нам нужно написать скрипт/приложение, которое будет при запуске выдавать список хардов в специальном JSON формате. Сначала я сделал скрипт на powershell, но на части машин скрипт периодически не успевал выполниться за 30 секунд, из-за того, что сам powershell очень долго инициализируется.

Пришлось отказаться от powershell и сделать exe приложение на c#(я его не знаю, но он показался достаточно простым, чтобы переписать скрипт). Приложение с помощью smartctl получает список hdd, убирает дублирующиеся(по серийникам) и выводит в нужном нам формате.

hddscan.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace hdd_scan
{
    class Program
    {
        static string[] smartctl(string arg)
        {
            Process p = new Process();
            p.StartInfo.FileName = "C:\Program Files\Zabbix\extra\smart\smartctl.exe";
            p.StartInfo.Arguments = arg;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.Start();
            string output = p.StandardOutput.ReadToEnd();
            string[] list = output.Split('n');
            p.WaitForExit();
            return list;
        }

        static void Main(string[] args)
        {
            try
            {

                string[] hddlist = smartctl("--scan");
                Dictionary<string, string> psarr = new Dictionary<string, string>();
                string pattern = @"^(?<1>/[w] )/(?<xer>[S] )s";
                foreach (string hdd in hddlist)
                {
                    var match = Regex.Match(hdd, pattern);
                    if (match.Success)
                    {
                        string shdd = match.Groups["xer"].Value;
                        string[] tmp = smartctl("-a "   shdd);
                        foreach (string line in tmp)
                        {
                            if (line.Contains("Serial") == true)
                            {
                                string[] serials = Regex.Split(line, @"^SerialsNumber:s ");
                                if (serials.Length < 2) continue;
                                string serial = serials[1];

                                if (!psarr.ContainsValue(serial))
                                {
                                    psarr.Add(shdd, serial);
                                }
                            }
                        }
                    }
                }

                //Starting output
                int cnt = 0;
                Console.WriteLine("{n");
                Console.WriteLine("t"data":[nn");
                foreach (KeyValuePair<string, string> kvp in psarr)
                {
                    string[] flist = smartctl("-a " kvp.Key);
                    string checkstring = "A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.";
                   
                    //
                    bool test= false;
                    for (int i = 0; i < flist.Length; i  )
                    {
                        if (flist[i].Contains(checkstring))
                        {
                            test = true;
                        }
                    }
                    if (!test)
                    {
                        cnt  ;
                        if (cnt > 1)
                        {
                            Console.WriteLine("t,n");
                        }
                        Console.WriteLine("t{n");
                        Console.WriteLine("tt"{{#HDDNAME}}":"{0}"n", kvp.Key);
                        Console.WriteLine("t}n");
                    }
                }

                Console.WriteLine("nt]n");
                Console.WriteLine("}n");

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
}
        }
    }
}

Да, на некоторых машинах смарт может быть отключен, поэтому добавим еще одну функцию firstrun, и разместим ее в сообщение правила авторегистрации Action-> Event Source->Auto registration добавляем пункт Send message to …via script, в тело размещаем:

S.m.a.r.t.


Для получения информации о дисках и их S.M.A.R.T используем утилиту

. Я беру последнюю версию 6.5. В этой версии нормально определяются паспорта USB, и новые манифесты для 10ки.

Скачиваем и кидаем в папку zabbixsmartmontools


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

c:>"Program Files"smartmontoolsbinsmartctl.exe --scan 

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

:/>  Где находится резервный конвертер ворд и как восстановить ворд документ если вы не сохранили внесенные в ворд документ изменения

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

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

c:>"Program Files"smartmontoolsbinsmartctl.exe -i /dev/sda -d ata 

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

c:>"Program Filessmartmontoolsbinsmartctl.exe" --smart=on --offlineauto=on --saveauto=on /dev/sda

Смотрим

c:>"Program Files"smartmontoolsbinsmartctl.exe -A /dev/sda -d ata


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

Смотрим SMART Health:

c:>"Program Files"smartmontoolsbinsmartctl.exe -H /dev/sda -d ata

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

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

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

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

Создаём в каталоге

zabbixscripts

файл

DiskInfoGenerationJSON.cmd

следующего содержания:

Zabbix agent

You know that the Zabbix agent is a utility that is widely used to monitor local resources and applications in any Zabbix infrastructure. This is definitely the most popular monitoring tool simply because the Zabbix agent is a super lightweight software that consumes just a couple of MBs and does not burden the CPU.

We have RPM packages for the most popular Linux versions. It is also possible to easily install the Zabbix agent on any Windows machine.

What are the benefits of the Zabbix agent? The Zabbix agent has a lot of metrics that you can monitor from the box. This means that it is not required to invent something new. You don’t need to write custom scripts or figure out complex monitoring scenarios.

In Configuration>Items>Item type>Zabbix agent, you will find all available monitoring items supported from the box that you can use without any additional configuration.

Simply go to the front end, create a host for your Zabbix agent, create a new item, and make the one that you need with the help of documentation. You can monitor service state or free disk space, network interfaces, memory, and many other things from the box, or do some discovery.

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

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

Готовим template

Необходимо создать шаблон для мониторинга, который будет прикрепляться к новым хостам, с помощью правила авторегистрации. (Action-> Event Source->Auto registration->Link to templates: Win_monitor) Я взял за основу стандартный шаблон zabbix для windows, а также APC Smart UPS Monitoring откуда-то с просторов, выкинул из них все лишнее и добавил то, что нужно мне.

:/>  Почему виндовс 8 и Windows 10 Home — это разные вещи?

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


В каталоге

zabbixscripts

создаём файл

Мониторинг в zabbix через powershell скрипты

Иногда может возникнуть необходимость мониторить такие параметры Windows, с которыми по умолчанию zabbix не умеет работать. Если нужное значение можно получить с помощью powershell команды или скрипта, то можно довольно просто научить zabbix это делать посредством функционала пользовательских параметров.

В общем виде задача состоит из трех этапов:

  1. создаем PS скрипт и сохраняем его
  2. настраиваем конфигурационный файл zabbix-агента (не забываем перезапустить агента)
  3. создаем необходимый item и триггер в zabbix

1) На первом шаге создаем и сохраняем скрипт. Возможно, потребуется настроить PowershellExecution Policy, но на серверных ОС она уже должна быть в нужном положении.

Подробно о Execution Policy я писал в данной статье.

2) В файле конфигурации агента (zabbix_agentd.win.conf или zabbix_agentd.conf) ищем закомментированный параметр #UserParameter, вместо него вставляем:

UserParameter = parameter_name, powershell -File "C:Scriptssome-script.ps1"

где parameter_name — произвольное имя вашего параметра, а ключ -File указывает путь к powershell скрипту

Для удобства правки, конфигурационный файл можно открыть в редакторе Notepad или подобном

По окончанию редактирования и сохранения файла, не забываем перезапустить zabbix-агент

net stop "zabbix agent"
net start "zabbix agent"

3) В zabbix при создании нового элемента данных (item) имя пишем произвольное, а вот ключ должен совпадать с именем параметра из конфигурационного файла, который мы прописали ранее (в моем случае, я назвал параметр «tsdrainmode»)

Настраиваем поле «тип информации» исходя из наших потребностей (типа получаемых данных из скрипта).

Подключаем агенты по dns-имени

По дефолту агенты регистрируются так, что zabbix подключается к ним по ip. Меня это не устраивает, поэтому пишем скрипт, который это поправит, а заодно и сообщит о проблемах lookup. За основу взял какой-то скрипт из примеров pyzabbix и немного переделал.

use_fqdn.py

#!/usr/bin/python
#
# -*- coding: utf-8 -*-

import socket
from getpass import getpass
from pyzabbix import ZabbixAPI, ZabbixAPIException


zapi = ZabbixAPI(server='https://127.0.0.1/zabbix/')
zapi.session.verify = False
zapi.login('apirobot', '*******')

body = ''
err = ''

def send_mail(recipient, subject, body):

    import smtplib
    from email.MIMEText import MIMEText
    from email.Header import Header
    from email.Utils import formatdate
    encoding='utf-8'
    SMTP_SERVER = 'smtp'
    SENDER_NAME = u'zabbix@domain.local'
    MAIL_ACCOUNT = 'zabbix@domain.local'
    session = None
    msg = MIMEText(body, 'plain', encoding)
    msg['Subject'] = Header(subject, encoding)
    msg['From'] = Header(SENDER_NAME, encoding)
    msg['To'] = recipient
    msg['Date'] = formatdate()
    try:
        session = smtplib.SMTP(SMTP_SERVER)
        session.sendmail(MAIL_ACCOUNT, recipient, msg.as_string())
    except Exception as e:
        raise e
    finally:
                # close session
        if session:
            session.quit()


# Loop through all hosts interfaces, getting only "main" interfaces of type "agent"
for h in zapi.hostinterface.get(output=["dns","ip","useip"],selectHosts=["host"],filter={"main":1,"type":1}):
    #print h
    # Make sure the hosts are named according to their FQDN
    #
    if len(h['dns']) == 0:
        try:
            zapi.hostinterface.update(interfaceid=h['interfaceid'], dns = socket.gethostbyaddr(h['hosts'][0]['host'])[0])
        except:
            body  = ('FQDN_UPD_ERR: '   h['hosts'][0]['host'])   'n'
    try:
        a = socket.gethostbyaddr(h['hosts'][0]['host'])[2][0]
        b = socket.gethostbyaddr(h['dns'])[2][0]
        if (a != b):
            body  = ('Warning: %s has dns "%s"' % (h['hosts'][0]['host'], h['dns']))   'n'

    except:
        body  = ('DNS_LOOKUP_ERR: '   h['hosts'][0]['host'])   'n'

    # Make sure they are using hostnames to connect rather than IPs (could be also filtered in the get request)
    if h['useip'] == '1':
        body  = ('%s is using IP instead of hostname. Fixing.' % h['hosts'][0]['host'])   'n'
        try:
            zapi.hostinterface.update(interfaceid=h['interfaceid'], useip=0)
        except ZabbixAPIException as e:
            #print(e)
            err  = str(e) 'n'
            err  = 'n'
        continue

body  = 'nZabbix Errors:'   err
if  len(body) > 16:
    send_mail('admin@domain.local','check agents',body)

Постскриптум

» Все скрипты, шаблон и прочие необходимые файлы выложены на

:/>  Сон и гибернация что это и в чем разница?

» Мониторим клиентские ПК в Microsoft AD с помощью Zabbix. Часть 1 — Автоустановка

Пример.


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

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

Enter:

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


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

И так далее с каждым хостом. После заполнения файла заходим в кабинет Zabbix —

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

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

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


Я создам для примера два прототипа атрибута

Spin_Retry_Count

и добавлю в группу элементов данных Pre-fail: Spin_Retry_Count. Первый будет получать

VALUE

значение, второй

THRESHOLD

из таблицы атрибутов смарт для каждого обнаруженного диска


Обратимся ещё раз к файлу

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

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

LogFile=C:zabbixlogslogs.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:zabbixpskZ_agent.psk	# путь к файлу с pre-shared ключом
TLSPSKIdentity=			# уникальный идентификатор

Уникальными для каждого хоста тут являются поля

Hostname=TLSPSKIdentity=

в конфигурационном файле. А также pre-shared ключ в файле

zabbixpskZ_agent.psk

. Следовательно, определим эти значения в переменные.

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

Results

In Monitoring>Latest data, I can check the results by specifying the hostname, ticking off Show details and clicking Apply.

Оставьте комментарий