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

Zabbix. Zabbix Trapper и Zabbix Sender.

Сегодня мы с вами снова поговорим о системе мониторинга. Ирония в том, что я не особо люблю заниматься настройкой мониторинга, но слишком часто приходится. А раз уж я хочу реже сюда погружаться, нужно продумывать логику так, чтобы все работало максимально безотказно. Как говорится, лень - двигатель прогресса. На повестке дня - zabbix трапперы: интересная и увлекательная киллер фича, которая может помочь в комплексном мониторинге систем. Zabbix Trapper (также известный как zabbix_sender) — это тип элемента данных, который ожидает получения данных от внешних источников вместо активного опроса. Поскольку для траппера не требуется запуск задания с сервера, его использование позволяет нам: Простыми словами - мы создаем пассивный элемент данных, в который сами пишем то, что захотим. Простой пример, когда это очень удобно: У меня есть необходимость проверять доступность своих сайтов, их время отклика и контент, который они отдают. Предположим, я реализую это скриптами на python. В случае с
Оглавление

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

Как говорится, лень - двигатель прогресса.

На повестке дня - zabbix трапперы: интересная и увлекательная киллер фича, которая может помочь в комплексном мониторинге систем.

Zabbix Trapper

Zabbix Trapper (также известный как zabbix_sender) — это тип элемента данных, который ожидает получения данных от внешних источников вместо активного опроса.

Поскольку для траппера не требуется запуск задания с сервера, его использование позволяет нам:

  • Мониторить системы, которые не поддерживают стандартные протоколы
  • Отправлять данные из пользовательских скриптов и приложений
  • Реализовывать асинхронную отправку метрик
  • Собирать данные с систем, находящихся за NAT или в изолированных сетях

Простыми словами - мы создаем пассивный элемент данных, в который сами пишем то, что захотим.

Простой пример, когда это очень удобно:

У меня есть необходимость проверять доступность своих сайтов, их время отклика и контент, который они отдают. Предположим, я реализую это скриптами на python. В случае с активными проверками, мне придется делать 3 отдельных скрипта, каждый из которых будет выполняться независимо от двух других.

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

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

Как отправлять данные в траппер?

Мы сегодня будем разбирать 2 варианта: с помощью bash, и с помощью python скриптов.

Для начала, зайдем в веб интерфейс заббикс сервера, откроем элементы данных нашего клиента и создадим 2 элемента данных с типом "Zabbix траппер":

Теперь у нас есть 2 элемента с ключами test.key.1 и test.key.2, каждый из которых ожидает целое число.

Зайдем консольно на нашего клиента и начнем настраивать отправку данных:

Bash

Для отправки данных из консоли нам понадобится пакет zabbix-sender.

-2

При установке, он автоматически подтянет за собой еще и zabbix-agent.

Базовый синтаксис довольно простой:

zabbix_sender -z zabbix-server -s "hostname" -k "item.key" -o "value"

  • В нашем случае отправка метрики будет выглядеть так:
zabbix_sender -z zabbix-test.fb -s "test-client" -k "test.key.1" -o 0
-3

Заходим в веб интерфейса в наш элемент данных и видим, что сервер получил наши данные и записал их:

-4

  • Также мы можем не указывать каждый раз адрес сервера и имя клиента.

Для этого редактируем наш файл /etc/zabbix/zabbix_agentd.conf и указываем в нем:

Server=Адрес zabbix сервера
ServerActive=Адрес zabbix сервера
Hostname=Имя клиента, которое указано на сервере

В моем случае:

Server=zabbix-test.fb
ServerActive=zabbix-test.fb
Hostname=test-client

Теперь мы можем отправлять метрики, указывая при этом конфигурационный файл:

zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "test.key.1" -o 0
-5

  • И напоследок - отправляем сразу несколько значений:

Для этого заранее создадим файл zabbix_data.txt с содержимым:

-6

Синтаксис файла должен выглядеть так:

<hostname> <item key> <item value>

Поскольку я использую конфигурационный файл, вместо hostname я оставляю прочерки, чтобы zabbix_sender взял этот параметр из zabbix_agent.conf

Отправляем данные на сервер:

zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -i zabbix_data.txt
-7

Видим, что обе метрики успешно записались.

Python socket

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

-8
import socket
import json
import time
import struct
def send_to_zabbix(host, key, value):
data = {
"request": "sender data",
"data": [{
"host": host,
"key": key,
"value": value
}]
}
json_data = json.dumps(data).encode('utf-8')
header = b'ZBXD\x01' + struct.pack('<Q', len(json_data))
packet = header + json_data
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('zabbix-test.fb', 10051))
sock.sendall(packet)
response = sock.recv(1024)
sock.close()
return response
sender = send_to_zabbix("test-client", "test.key.1", 10)
print(sender)

Важно не забыть добавить заголовки в отправляемый пакет, иначе получите сообщение:

1307:20260103:160722.695 Message from 192.168.122.196 is missing header. Message ignored.

При вызове получаем ответ:

-9

И снова проверяем, что у нас все записывается:

-10

Python zabbix_utils

Устанавливаем официальную python библиотеку для zabbix:

pip install zabbix_utils

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

-11
from zabbix_utils import Sender
sender = Sender(server='zabbix-test.fb', port=10051)
sender.send_value(host='test-client', key='test.key.2', value=20)

Проверяем, что он отрабатывает корректно:

-12

В заключение хочу сказать, что все эти способы имеют право на жизнь. У вас может быть старая система, на которую невозможно поставить python3 в принципе, у вас может быть закрыта сеть, из-за чего вы не сможете скачать библиотеку, либо не сможете установить ее из-за старой версии python.