Мониторинг скорости интернет каналов в Zabbix

Kate

Administrator
Команда форума
Всем привет!

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

Собрав все инструменты, что у меня есть, я решил сделать мониторинг скорости интернета на базе Zabbix. Для замеров скорости используется утилита iperf3. Весь код сделан на python.

Схема работы​

В общем случае, схема мониторинга выглядит следующим образом:

Схема работы мониторинга скорости интернет каналов
Схема работы мониторинга скорости интернет каналов
На объектах установлены сетевые шлюзы на Linux, на которых поднят iperf3 в режиме сервера. В каждом филиале есть сервер Zabbix Proxy, на котором запускается iperf3 в режиме клиента и замеряет скорость интернета, после он в Zabbix trap записывает данные замера.

Настройка и запуск iperf3 на удаленном объекте​

Как уже писал выше, на объектах установлены сетевые шлюзы на Linux. На них был установлен iperf3 и создана задача на запуск iperf3 при старте шлюза. Запуск осуществляется следующей командой, где <IP_address> интерфейса, через который осуществляется замер скорости:

/usr/bin/iperf3 -B <IP_address> -Ds

Настройка iperf3 на Zabbix Proxy сервере​

Для начала необходимо установить следующие пакеты: iperf3, python-pip, python. Из pip нам необходимо установить py-zabbix и protobix.

apt install iperf3 python-pip python
pip install py-zabbix
pip install protobix
Далее создаем папку iperf в /usr/lib/zabbix/externalscripts/. В папке создаем два файла iperf3_speed_testing.py и iperf3_task.py (один для замера скорости из Zabbix, второй для периодических замеров всех). И даем им нужные разрешения. Владельцем папки делаем пользователя zabbix.

mkdir /usr/lib/zabbix/externalscripts/iperf
touch /usr/lib/zabbix/externalscripts/iperf/iperf3_speed_testing.py
touch /usr/lib/zabbix/externalscripts/iperf/iperf3_task.py
chown -R zabbix:zabbix /usr/lib/zabbix/externalscripts/iperf
chmod +x /usr/lib/zabbix/externalscripts/iperf/iperf3_speed_testing.py
chmod +x /usr/lib/zabbix/externalscripts/iperf/iperf3_task.py

Описание и содержимое скриптов​

Скрипт /usr/lib/zabbix/externalscripts/iperf/iperf3_speed_testing.py необходим для выполнения запуска замера скорости на текущий момент. Он запускает запуск замеров на выбранном хосте в Zabbix.

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

import protobix
import argparse
import subprocess
import sys
import json
import time

proxy = subprocess.Popen(['hostname'], stdout=subprocess.PIPE)
proxy = proxy.communicate()[0]

def showResult(_upload, _download):
print "Отправка: " + str(round(_upload/1000000,2)) + " Мбит/с"
print "Получение: " + str(round(_download/1000000,2)) + " Мбит/с"

def sendData(_upload, _download):
host_moria = sys.argv[2]
host_status = {}
host_status['speed_upload'] = _upload
host_status['speed_download'] = _download
zbx_datacontainer = protobix.DataContainer()
zbx_datacontainer.server_active = proxy.split('\n')[0]
zbx_datacontainer.server_port = 10051
zbx_datacontainer.data_type = "items"
zbx_datacontainer.add({host_moria: host_status})
# print json.dumps({host_moria: host_status}, indent=4)
zbx_datacontainer.send()
showResult(_upload, _download)

start_time = time.time()
result = subprocess.Popen(['/usr/bin/iperf3', '-c', sys.argv[1], '-J', '-P', '5'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

wait = time.time()-start_time
while wait < 45 and result.poll() == None:
wait = time.time()-start_time
if wait > 40 and wait < 45 :
result.kill()
stdout_value = {"error":"Timeout error"}
stdout_json = stdout_value
stdout_value = str(stdout_value)
break

else:
stdout_value, stderr_value = result.communicate()
stdout_json = json.loads(stdout_value)

while stdout_value.find('error') != -1 and stdout_json['error'] == 'error - unable to receive results: Resource temporarily unavailable':
result = subprocess.Popen(['/usr/bin/iperf3', '-c', sys.argv[1], '-J', '-P', '5'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_value, stderr_value = result.communicate()
stdout_json = json.loads(stdout_value)

if stdout_value.find('error') == -1:
sendData(stdout_json['end']['sum_sent']['bits_per_second'],stdout_json['end']['sum_received']['bits_per_second'])
else:
print stdout_json['error']

Скрипт /usr/lib/zabbix/externalscripts/iperf/iperf3_task.py необходим для запуска задачи на замер скорости в выбранных группах хостов Zabbix. Для работы данного скрипта также необходимо создать пользователя с доступом к Zabbix API. В данном скрипте используются следующие переменные:

  • zabbix_user - пользователь с доступом к API
  • zabbix_password - пароль пользователя API
  • zabbix_server - адрес сервера zabbix
  • group - группа или группы в Zabbix, для которых необходимо делать замер скорости интернета
#!/usr/bin/python
# - *- coding: utf- 8 - *-
from pyzabbix.api import ZabbixAPI
import protobix
import argparse
import subprocess
import sys
import json
import time

zabbix_user = <zabbix_api_user>
zabbix_password = <zabbix_api_password>
group = ('Gateway_branch_1','Gateway_branch_2')

start_time_script = time.time()

proxy = subprocess.Popen(['hostname'], stdout=subprocess.PIPE)
proxy = proxy.communicate()[0]

def sendData(host, upload, download):
host_moria = host
host_status = {}
host_status['speed_upload'] = upload
host_status['speed_download'] = download
zbx_datacontainer = protobix.DataContainer()
zbx_datacontainer.server_active = proxy.split('\n')[0]
zbx_datacontainer.server_port = 10051
zbx_datacontainer.data_type = "items"
zbx_datacontainer.add({host_moria: host_status})
# print json.dumps({host_moria: host_status}, indent=4)
zbx_datacontainer.send()

def getZabbixGroupID(groupName):
groups = zapi.hostgroup.get(filter={'name':groupName})
for group in groups:
return group['groupid']


zapi = ZabbixAPI(url=zabbix_server, user=zabbix_user, password=zabbix_password)

hosts = zapi.host.get(groupids=[getZabbixGroupID(group[0]),getZabbixGroupID(group[1])], selectInterfaces=['ip'])

for host in hosts:

# print (host['host'])
start_time = time.time()
result = subprocess.Popen(['/usr/bin/iperf3', '-c', host['interfaces'][0]['ip'], '-J', '-P', '5'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

wait = time.time()-start_time
while wait < 45 and result.poll() == None:
wait = time.time()-start_time
if wait > 40 and wait < 45 :
result.kill()
stdout_value = {"error":"Timeout error"}
stdout_json = stdout_value
stdout_value = str(stdout_value)
break

else:
stdout_value, stderr_value = result.communicate()
stdout_json = json.loads(stdout_value)

while stdout_value.find('error') != -1 and stdout_json['error'] == 'error - unable to receive results: Resource temporarily unavailable':
result = subprocess.Popen(['/usr/bin/iperf3', '-c', host['interfaces'][0]['ip'], '-J', '-P', '5'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_value, stderr_value = result.communicate()
stdout_json = json.loads(stdout_value)

if stdout_value.find('error') == -1:
sendData(host['host'], stdout_json['end']['sum_sent']['bits_per_second'], stdout_json['end']['sum_received']['bits_per_second'])

zapi.user.logout()

related_time = time.time() - start_time_script

host_moria = proxy.split('\n')[0]
host_status = {}
host_status['iperf_task_time'] = float(round(related_time,2))
zbx_datacontainer = protobix.DataContainer()
zbx_datacontainer.server_active = 'hqpv-zbxcl1.megafon-retail.ru'
zbx_datacontainer.server_port = 10051
zbx_datacontainer.data_type = "items"
zbx_datacontainer.add({host_moria: host_status})
zbx_datacontainer.send()
Создаем задачу в crontab

0 2,6,10,14,18,22 * * * /usr/lib/zabbix/externalscripts/iperf/iperf3_task.py

Мы делаем замер раз в 4 часа. Нам этого хватает.

Если у вас используется просто Zabbix сервер, то на нем нужно сделать то же самое.

Настройка шаблонов и скриптов в Zabbix​

Для начала необходимо создать шаблон с элементами данных замеров скорости интернета. Я назвал шаблон Internet Speed Testing

Шаблон Inernet speed testing


Шаблон Inernet speed testing

В данном шаблоне необходимо создать следующие элементы данных:

  • Speed Upload
0fcadf37497aa613e856e861539add2e.png

  • Speed Download
ecb07ed4ecd22fbbe62a760e92eb2ecc.png

Триггеры:

  • Нет данных замеров скорости более 48 часов
  • Низкая скорость загрузки
  • Низкая скорость выгрузки
Триггеры
Триггеры
Макросы:

  • {$LOW_SPEED} - для записи скорости, при которой срабатывает триггер
6e77c907a647254ce33039348be295a6.png

Также добавляем Скрипт для замера скорости вручную (Администрирование -> Скрипты -> Создать скрипт)

Данные для настройки скрипта ручного замера


Данные для настройки скрипта ручного замера

В поле команда вставляем путь к скрипту в следующем виде /usr/lib/zabbix/externalscripts/iperf/iperf3_speed_testing.py {HOST.CONN} '{HOST.HOST}'

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

Нажимаем на нужный хост и выбираем Скорость интернета. Получаем ответ:

Результат замера скорости


Результат замера скорости

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

Статистика замеров скорости интернета


Статистика замеров скорости интернета

На этом всё. Спасибо за внимание! 😊

 
Сверху