Найти в Дзене
Записки сисадмина

Zabbix. Python. Создаем свой шаблон.

Лунная призма, дай мне оптимизма. Оригинал этой переделанной фразы не пропустит цензура, как и не пропустит ваши эмоции, если один из сайтов в вашей зоне ответственности вдруг ляжет. А еще хуже - если вы не заметите этого падения. Ведь быстро поднятое, упавшим не считается. А вот за долгий даунтайм придется отвечать, и иногда - головой. Поэтому сегодня будем писать проверки сайтов, объединив это сразу в шаблон, чтобы иметь возможность масштабировать наше решение. Итак, ТЗ: у нас есть список сайтов, нам нужно получать их время ответа и http код. Без лишних слов, начинаем разбираться. Я назову свой шаблон "Check sites", т.к. в примере мы будем собирать статистику по сайтам: Добавляем шаблон и сразу переходим внутрь него во вкладку "Правила обнаружения". Имя - любое на ваше усмотрение. Ключ - ключ, на который будет откликаться zabbix-agent на клиенте. Интервал - обычно 1 час, для ускорения я выставил 1 минуту. Теперь заставим нашего агента реагировать на этот ключ. UserParameter=sites.d

Лунная призма, дай мне оптимизма. Оригинал этой переделанной фразы не пропустит цензура, как и не пропустит ваши эмоции, если один из сайтов в вашей зоне ответственности вдруг ляжет.

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

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

Итак, ТЗ: у нас есть список сайтов, нам нужно получать их время ответа и http код.

Без лишних слов, начинаем разбираться.

  • Заходим в Сбор данных - Шаблоны и нажимаем "Создать шаблон".

Я назову свой шаблон "Check sites", т.к. в примере мы будем собирать статистику по сайтам:

-2

Добавляем шаблон и сразу переходим внутрь него во вкладку "Правила обнаружения".

  • Создаем новое правило обнаружения:
-3
Имя - любое на ваше усмотрение.
Ключ - ключ, на который будет откликаться zabbix-agent на клиенте.
Интервал - обычно 1 час, для ускорения я выставил 1 минуту.

Теперь заставим нашего агента реагировать на этот ключ.

  • На клиенте в /etc/zabbix/zabbix_agentd.conf добавляем строчку:
-4
UserParameter=sites.discover,/etc/zabbix/scripts/site_discover.py -d

  • Создаем скрипт /etc/zabbix/scripts/site_discover.py с содержимым:
-5

Требования к формату JSON:

  1. Корневой элемент — объект с единственным обязательным полем data.
  2. Значение data — всегда массив (даже если обнаружен один объект).
  3. Каждый элемент массива — объект, содержащий макросы.
  4. Имена макросов должны быть в верхнем регистре, начинаться с {# и заканчиваться }, например {#SITE}.
  5. Значения макросов — строки, которые Zabbix будет подставлять в прототипы.

В нашем случае правильным выводом будет JSON:

{"data": [{"{#SITE}": "https://google.com"}, {"{#SITE}": "https://dzen.ru"}]}

  • Перезапускаем агента на клиенте:
systemctl restart zabbix-agent

  • Возвращаемся обратно в наше правило обнаружения на zabbix сервере и нажимаем "Тест", подставив значения нашего клиента:
-6

  • Создаем прототип элемента данных:
-7

Поскольку в полученном из обнаружения JSON макросы называются "{#SITE}", мы должны так же добавлять их и в элементы данных.

  • Также добавим сразу и пассивный элемент Zabbix траппер, в который будем записывать данные по времени ответа:
-8
  • И напоследок - создадим простой триггер (код ответа сайта не 200). Для этого переходим в "Прототипы триггеров":
-9

Сохраняем все изменения и переходим к клиенту.

  • Добавляем нашему клиенту шаблон:
-10

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

-11

Теперь пора немного доработать скрипт на клиенте:

  • В конфигурации zabbix агента на клиенте дописываем:
-12
UserParameter=site_status_code[*],/etc/zabbix/scripts/site_discover.py -c $1

Даже учитывая то, что мы сделали два элемента данных, параметры прописываются только для активных.

  • Дорабатываем наш скрипт:
-13
import sys
import json
import requests
from zabbix_utils import Sender
if sys.argv[1] == '-d':
zabbix_discovery = {"data": [{"{#SITE}": "https://google.com"}, {"{#SITE}": "https://dzen.ru"}]}
print(json.dumps(zabbix_discovery))
elif sys.argv[1] == '-c':
site_name = sys.argv[2]
response = requests.get(site_name)
print(int(response.status_code))
sender = Sender(server='zabbix-test.fb', port=10051)
sender.send_value(host='test-client', key=f'site_request_time[{site_name}]', value=response.elapsed.microseconds)

  • Перезапускаем zabbix агента на клиенте и смотрим последние данные (Мониторинг - Последние данные):
-14

В чем удобство:

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

Также, если мы хотим расширить область проверок, мы можем в JSON обнаружения в скрипте добавить и другие данные. Например так:

Было:

zabbix_discovery = {"data": [{"{#SITE}": "https://google.com"}, {"{#SITE}": "https://dzen.ru"}]}

Стало:

zabbix_discovery = {"data": [{"{#SITE}": "https://google.com"}, {"{#SITE}": "https://dzen.ru"}, {"{#SITE}": "https://web.max.ru"}, {"{#SITE}": "https://mail.yandex.ru"}]}

После изменений данных в скрипте, они автоматически подтянутся в zabbix:

-15

В следующей статье мы доработаем наш шаблон, запустив также проверку SSL сертификатов на наших сайтах.