Использование Zabbix API. Когда не хватает стандартных графиков

Возникла задача получить некоторую статистику из Zabbix, делюсь опытом получения данных из базы Zabbix через API средствами Python.
3309e613e2d24ca7b1b40375928a00bf.png

Куски кода будут для 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

Благодарю за внимание.

Комментарии (0)

© Habrahabr.ru