Возникла задача получить некоторую статистику из Zabbix, делюсь опытом получения данных из базы Zabbix через API средствами Python.
Куски кода будут для Python 2.7
Для работы с zabbix-api есть готовая библиотека py-zabbix, документация по ней доступна тут, но примеров там не много. Официальное руководство по Zabbix API.
Итак, после стандартной установки:
pip install py-zabbix
Пробуем подключиться к серверу Zabbix:
from pyzabbix import ZabbixAPI
z = ZabbixAPI('https://172.16.1.10', user='user1', password='pass1')
answer = z.do_request('apiinfo.version')
print "Version:",answer['result']
Формат ответа от сервера — JSON:
{u'jsonrpc': u'2.0', u'result': u'3.0.2', u'id': u'1'}
Скрипт печатает содержимое поля result:
Version: 3.0.2
Теперь можно приниматься за решение интересующей задачи. Задача — получить среднее значение Disk Idle Time со всех виртуальных машин за неделю (Пн-Пт) в рабочее время (с 10:00 до 19:00) за определенную неделю. Я не хочу заострять внимание на актуальности этих параметров, а просто поделиться опытом работы с Zabbix API на примере этой конкретной задачи.
Итак, виртуальные машины в Zabbix лежат в отдельной группе, для начала получим список доступных групп с помощью метода hostgroup.get:
#Get List of available groups
groups = z.hostgroup.get(output=['itemid','name'])
for group in groups:
print group['groupid'],group['name']
Параметром output можно определить, какие поля вернет API:
38 _Local Domains
53 _Local NAS
23 _Local Servers Linux
27 _Local Servers Virtual Linux
25 _Local Servers Virtual Windows
24 _Local Servers Windows
35 _Local Switches
Затем можно получить список хостов в конкретной группе с помощью метода host.get:
#Get List of hosts in the group
hosts = z.host.get(groupids=25, output=['hostid','name'])
for host in hosts:
print host['hostid'],host['name']
Параметр groupids определяет идентификатор группы:
10197 DC1_--172.16.1.4--
10204 DC2_--172.16.1.5--
10637 LocalDB_--172.16.1.12--
10686 WSUS_--172.16.1.16--
10708 Jira_--172.16.1.24--
Для получения списка items по определенному хосту используется метод item.get:
#Get List of items on the host
items = z.item.get(hostids=10637, output=['itemid','name'])
for item in items:
print item['itemid'],item['name']
Результат:
525617 ICMP ping
525618 ICMP loss
525619 ICMP response time
940205 Input Microsoft Hyper-V Network Adapter #2
940206 Output Microsoft Hyper-V Network Adapter #2
990808 Disk Idle time on C:
990809 Disk Idle time on D:
Как видно из ответа, выбранный хост имеет 2 диска, нужно вывести минимальное значение из нескольких. Для доступа к данным по items используется метод history.get. Следующий код не претендует на оптимальность, я только начал осваивать Python, но в целом с поставленной задачей скрипт справился.
Для метода history.get нужно определить следующие параметры:
- history — тип возвращаемого значения
- itemids — id интересующего item
- time_from — начало временного интервала
- time_till — конец временного интервала
Скрипт, собирающий статистику:
from pyzabbix import ZabbixAPI
import time
import sys
z = ZabbixAPI('https://172.16.1.10', user='user1', password='pass1')
groupid = 25 #Local Servers Virtual Windows
hosts = z.host.get(groupids=groupid , output=['hostid','name'])
#Список имен хостов
host_names = [host['name'] for host in hosts]
#Список идентификаторов
host_ids = [host['hostid'] for host in hosts]
nameindex = 0
#Константа, кол-во секунд в сутках
increment = 60*60*24
for host_id in host_ids:
#параметр search позволяет найти все items, в имени которых есть заданная строка
items = z.do_request('item.get',{'hostids':[host_id],'output': ['itemid','name'],'search':{'name': 'Idle time'}})
#массив найденных дисков
disk_ids = [item['itemid'] for item in items['result']]
#длина массива соответствует кол-ву дисков
num_disks = len(disk_ids)
avg_list=[]
#цикл подсчета среднего для каждого диска
for disk in disk_ids:
#для определения временных рамок используется функция из time
#первый день, за который нужна статистика - 27 марта 2017 года, с 9:00 до 18:00
time_from = time.mktime((2017,3,27,9,0,0,0,0,0))
time_till = time.mktime((2017,3,27,18,0,0,0,0,0))
history_sum=0
history_len=0
#цикл для 5 дней с 27 по 31 марта
for day in range(0,5):
data = z.history.get(history = 0, itemids=disk, time_from=time_from, time_till=time_till)
#массив содержит список значений из истории
graph = [float(item['value']) for item in data]
#если список не пустой, добавляем его в массив для вычисления среднего
if(len(graph)!=0):
history_sum+=sum(graph)
history_len+=len(graph)
#увеличиваем интервалы на сутки
time_from += increment
time_till += increment
#если очередь не пустая, добавляем среднее значение по диску в список
if(history_len!=0):
avg_list.append(history_sum/history_len)
else:
avg_list.append(0)
#если список не пустой, берем минимальное значение
if(len(avg_list)>0):
sys.stdout.write(host_names[nameindex])
print ',',num_disks,',',min(avg_list)
nameindex+=1
В результате получаем разделенные запятой имя хоста, кол-во винтов и min idle time:
DC1_--172.16.1.4--, 1 , 99.0758766296
DC2_--172.16.1.5--, 1 , 97.0989181683
LocalDB_--172.16.1.12--, 2 , 98.9930628704
Благодарю за внимание.
Автор: Коваленко Александр