基于Python调用zabbix监控的API接口详解,将数据展现到前台过程思路分析

Posted 抛物线.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Python调用zabbix监控的API接口详解,将数据展现到前台过程思路分析相关的知识,希望对你有一定的参考价值。


这是zabbix的官网,文档内容非常丰富,建议有需要的,可以多花点时间看一下官方的文档。
下面这是部署在我的虚拟机下的zabbix监控


上图中报红色的zabbix是因为那两个虚拟机我没有打开,只打开了zabbix-master
我们可以看到我使用了linux server这个模板,有51个监控项,以及触发器和图形。

我做的运维平台的监控原理大致是这样一个过程:

  1. 首先,zabbix部署了一个名为Linux Server的主机组,该主机组下面部署了3台linux主机,每台linux主机下面各设置了大约50各监控项。
  2. 我在后端调用zabbix的API接口,由主机组---------> 主机---------> 监控项---------> 获取数据,最后将获取的数据返回到前台。
  3. 后端获取的数据,在后端使用dataHandle(),去搜集数据(这里是json格式的),并且存为一个字典,然后在去遍历,并返回给前台。

举个例子:获取网络流量流出数据
1,首先定义一个接口方法:


def getNetOutDataTraffic(*args, **b):
    '''
    网络流出数据
    '''
    NetOutDataTraffic_data = json.dumps(
        "jsonrpc": "2.0",
        "method": "history.get",
        "params": 
            "output": "extend",
            # "itemids": b["parameter"],
            "itemids": 28461,  #  net.if.out[eno16777736] 网卡out数据
            "history": 3,  #这里有5个可选参数分别是0,1,2,3,4,默认是3,下面会介绍每个参数的意义
            "limit": 16
        ,
        "auth": b["session"],
        "id": 2
    )
    return NetOutDataTraffic_data

########################################################################

或者也可以单独去获取某个监控主机组下的单个主机的某个单独的监控项:

比如说:

def getfsused(*args, **b):
    '''
    获取磁盘使用量
    '''
    disk_data = json.dumps(
        "jsonrpc": "2.0",
        "method": "item.get",
        "params": 
            "output": "extend",
            "hostids": b["parameter"],
            "search": 
                "key_": "vfs.fs.size[/,used]"  # 只查询key_包含“vfs.fs.size[/,used]”字段的item
                # "key_": "vfs.fs.size[/,free]"
            
        ,
        "auth": b["session"],
        "id": 2
    )
    return disk_data


上面定义的方法,可以看出是获取eno16777736网卡,这个流出16条历史数据,也可以价格desc参数,进行排序,也可以基于一个时间段进行排序,也可以根据sortfield某个字段进行排序,等等。下面会进行详细解释。这是官网API文档。非常详细。

2,使用dataHandle(),去搜集通过API获取的数据,并且进行遍历,

  '''获取网络流量流出数据'''
        netOutDataTraffic_dict = dataHandle(func=getNetOutDataTraffic, hostid=hostid)

进行遍历获取到的16条历史数据:
 netOutdatalist = [] #首先定义一个空列表进行存value这个多条数据
        for i in netOutDataTraffic_dict:    # 然后进行遍历
            netOutdatalist.append(i['value'])
            netOutDataTraffic_now = netOutdatalist
            # netInDataTraffic_now  # 网络流量流入历史数据 net.if.in[eno16777736]

3,将遍历的结果返回给前台,用 **render()**进行渲染。

 "netOutDatatraffic_now": netOutDataTraffic_now,  # 网络流量流出数据
 

前台只需要使用Django的tag,就可以捕获到后台传来的数据。
整个核心代码:

@login_required
def getMonitor(request):
    """
    获取zabbix监控的主机列表

    """
    monitorform = monitorForm()
    zabbix_host_info = dataHandle(func=getZabbixHost)
    monitor_hostnames = []
    cpuutils_now = ''
    cpuload_now = ''
    fsused_now = ''
    fsfree_now = ''
    fshomefree_now = ''
    fshomeused_now = ''
    fsbootfree_now = ''
    fsbootused_now = ''
    fsmemsize_now = ''
    fsCpuUserHistory_now = ''
    fsCpuUserHistory_now_x = ''
    fsCpuSysHistory_now = ''
    netInDataTraffic_now = ''
    netInDataTraffic_now_x = ''
    netOutDataTraffic_now = ''
    for i in zabbix_host_info:
        monitor_hostid = i['hostid']
        monitor_hostname = i['host']
        monitor_hostnames = monitor_hostnames + [(monitor_hostid, monitor_hostname)]
    host_num = len(monitor_hostnames)
    monitorform.fields['monitorHost'].choices = monitor_hostnames

    '''获取提交的主机ID'''
    try:
        if request.method == "POST":
            if "monitorHost" in request.POST:  # name为monitorHost的表单提交
                hostid = request.POST.get('monitorHost', '')
            else:
                hostid = 10084
        else:
            hostid = 10084

        '''获取提交主机的itemids'''
        itemids = dataHandle(func=getZabbixitem,hostid=hostid)

        '''获取CPU使用率'''
        cpuutils_dict = dataHandle(func=getZabbixCPUutil, hostid=hostid)

        '''获取CPU负载'''
        cpuload_dict = dataHandle(func=getZabbixCPUload, hostid=hostid)

        '''获取硬盘使用量'''
        fsused_dict = dataHandle(func=getfsused, hostid=hostid)

        '''获取硬盘空闲'''
        fsfree_dict = dataHandle(func=getfsfree, hostid=hostid)

        '''获取home目录free空间'''
        fshomefree_dict = dataHandle(func=getfshomefree, hostid=hostid)

        '''获取home目录used空间'''
        fshomeused_dict = dataHandle(func=getfshomeused, hostid=hostid)

        '''获取boot目录free空间'''
        fsbootfree_dict = dataHandle(func=getfsbootfree, hostid=hostid)

        '''获取boot目录used空间'''
        fsbootused_dict = dataHandle(func=getfsbootused, hostid=hostid)

        '''获取memory的大小'''
        fsmemsize_dict = dataHandle(func=getmemsize, hostid=hostid)

        '''获取用户空间使用CPU比例历史数据'''
        fsCpuUserHistory_dict = dataHandle(func=getCpuUserHistory, hostid=hostid)

        '''获取内核空间使用CPU比例的历史数据'''
        fsCpuSysHistory_dict = dataHandle(func=getCpuSysHistory, hostid=hostid)

        '''获取网络流量流ru数据'''
        netInDataTraffic_dict = dataHandle(func=getNetInDataTraffic, hostid=hostid)

        '''获取网络流量流出数据'''
        netOutDataTraffic_dict = dataHandle(func=getNetOutDataTraffic, hostid=hostid)

        for i in cpuutils_dict:
            cpuutils_now = i['prevvalue']  # CPU当前使用率百分比
        for i in cpuload_dict:
            cpuload_now = i['prevvalue']  # CPU当前负载百分比
        for i in fsused_dict:
            fsused_now = i['prevvalue']  # 根磁盘使用量
        for i in fsfree_dict:
            fsfree_now = i['prevvalue']  # 根磁盘空闲
        for i in fshomefree_dict:
            fshomefree_now = i['prevvalue']  # home分区空闲
        for i in fshomeused_dict:
            fshomeused_now = i['prevvalue']  # home分区使用量
        for i in fsbootfree_dict:
            fsbootfree_now = i['prevvalue']  # boot分区空闲量
        for i in fsbootused_dict:
            fsbootused_now = i['prevvalue']  # boot分区使用量
        for i in fsmemsize_dict:
            fsmemsize_now = i['prevvalue']  # memory大小

        cpuuserdatalist = []
        for i in fsCpuUserHistory_dict:
            cpuuserdatalist.append(i['value'])
            fsCpuUserHistory_now = cpuuserdatalist
            # fsCpuHistory_now  # 历史数据大小 system.cpu.util[,user]

        cpuuserdatelist=[]
        for i in fsCpuUserHistory_dict:
            cpuuserdatelist.append(i['clock'])
            fsCpuUserHistory_now_x = cpuuserdatelist  # 历史数据时间轴 system.cpu.util[,user]


        cpusysdatalist = []
        for i in fsCpuSysHistory_dict:
            cpusysdatalist.append(i['value'])
            fsCpuSysHistory_now = cpusysdatalist
            # fsCpuSysHistory_now  # 内核空间使用CPU比例历史数据大小 system.cpu.util[,system]

        netIndatalist = []
        for i in netInDataTraffic_dict:
            netIndatalist.append(i['value'])
            netInDataTraffic_now = netIndatalist
            # netInDataTraffic_now  # 网络流量流入历史数据 net.if.in[eno16777736]

        netIndatelist = []
        for i in netInDataTraffic_dict:
            netIndatelist.append(i['clock'])
            netInDataTraffic_now_x = netIndatelist
            # netInDataTraffic_now  # 获取网络流量流入历史数据的时间戳 net.if.in[eno16777736]

        netOutdatalist = []
        for i in netOutDataTraffic_dict:
            netOutdatalist.append(i['value'])
            netOutDataTraffic_now = netOutdatalist
            # netInDataTraffic_now  # 网络流量流入历史数据 net.if.in[eno16777736]
    except KeyError as e:
        print(e)
        pass

    '''获取内存使用率最后..次的数据'''
    me_data = monitorMemory.objects.filter(hostid=hostid)
    '''返回的前端的字典'''
    monitor_dict = 
        "monitorform": monitorform,  # 监控主机的表单
        "monitor_hostnames": monitor_hostnames,  # 监控的主机的下拉菜单列表
        "host_num": host_num,  # 监控的主机个数
        "cpuutils_now": cpuutils_now,  # CPU当前使用率
        "cpuload_now": cpuload_now,  # CPU当前负载
        "fsused_now": fsused_now,  # 磁盘使用量
        "fsfree_now": fsfree_now,  # 磁盘空闲
        "fshomefree_now": fshomefree_now,  # home 空闲
        "fshomeused_now": fshomeused_now,  # home partation used
        "fsbootfree_now": fsbootfree_now,  # boot 分区free
        "fsbootused_now": fsbootused_now,  # boot 分区used
        "fsmemsize_now": fsmemsize_now,  # memory 大小
        "fsCpuUserHistory_now": fsCpuUserHistory_now,  # CPU用户空间 历史数据大小
        "fsCpuUserHistory_now_x": fsCpuUserHistory_now_x,  # CPU用户空间历史数据大小
        "fsCpuSysHistory_now": fsCpuSysHistory_now,  # CPU内核空间历史数据大小
        "netInDatatraffic_now": netInDataTraffic_now,  # 网络流量流入数据
        "netInDatatraffic_now_x": netInDataTraffic_now_x,  # 网络流量流入数据时间戳
        "netOutDatatraffic_now": netOutDataTraffic_now,  # 网络流量流出数据
        "data": me_data,
    
    return render(request, 'Monitor.html', monitor_dict)

上面是大致的思路,比较简单。但是要想熟悉整个操作,那么zabbix的api必须要会使用,每个监控项的参数也会用。
######################################################################
这里先说一下web ui下添加监控项的参数:



大致就能明白后台读的监控项是怎么来的了,是我们自己创建的,或者说是使用的监控模板里面的,从最后一张图可以看出来,基本上每一个监控项后面都有参数,我们不难发现<> 包围起来的参数,是可选参数,而[],这个参数是必选。而且监控项是key:value 这种格式的。
下面开始一一介绍:

首先贴上官方文档:

https://www.zabbix.com/documentation/3.4/manual/api/reference/history/get

二、Zabbix API可以通过JSON RPC协议来获取历史数据。可以采用脚本或者任何支持JSON RPC的工具来使用API。
 基本请求格式
  Zabbix API 简化的JSON请求如下:
  
  "jsonrpc": "2.0",
  "method": "method.name",
  "params": 
  "param_1_name": "param_1_value",
  "param_2_name": "param_2_value"
  ,
  "id": 1,
  "auth": "a826fca79a0795ccc1224dc76329972f",
  

下面一行一行来看:
  ● “jsonrpc”: “2.0”-这是标准的JSON RPC参数以标示协议版本。所有的请求都会保持不变。
  ● “method”: “method.name”-这个参数定义了真实执行的操作。例如:host.create、item.update,history.get等等
  ● “params”-这里通过传递JSON对象来作为特定方法的参数。如果你希望创建监控项,"name"和"key_“参数是需要的,每个方法需要的参数在Zabbix API文档中都有描述。
  ● “id”: 1-这个字段用于绑定JSON请求和响应。响应会跟请求有相同的"id”。在一次性发送多个请求时很有用,这些也不需要唯一或者连续
  ● “auth”: “a826fca79a0795ccc1224dc76329972f”-这是一个认证令牌【authentication token】用以鉴别用户、访问API。这也是使用API进行相关操作的前提-获取认证ID。

举个例子:

获取192.168.211.60从2014.2.19 14:00:00到2014.2.19 14:10:00的cpu_idle值.

基于curl命令:
  (1):认证并且取得加密字段
  curl -i -X POST -H 'Content-Type: application/json' -d '"jsonrpc":
  "2.0","method":"user.login","params":"user":"xxxx","password":"xxxx","auth":
  null,"id":0' http://x.x.x.x/api_jsonrpc.php
  #之后会得到一串输出:"jsonrpc":"2.0","result":"a826fca79a0795ccc1224dc76329972f","id":0。记住这
  段输出。
  (2)获取监控主机的hostids
  curl -i -X POST -H 'Content-Type: application/json' -d '"jsonrpc": "2.0","method":"host.get","params":"output":["hostid"],"filter": "host":"192.168.211.60","auth": "a826fca79a0795ccc1224dc76329972f","id": 0' http://x.x.x.x/api_jsonrpc.php
  #"hostid":"10243"
  (3)获得监控项itemids
  curl -i -X POST -H 'Content-Type: application/json' -d '"jsonrpc": "2.0","method":"item.get","params":"output":"itemids","hostids":"10243","search":"key_":"system.cpu.util
  [,idle,avg1]","auth": "a826fca79a0795ccc1224dc76329972f","id": 0' http://x.x.x.x/api_jsonrpc.php
  #“item”:"24526"
  (4)获取监控项"system.cpu.util[,idle,avg1]"2014.2.19 14:00~14:20的值
  curl -i -X POST -H 'Content-Type: application/json' -d '"jsonrpc": "2.0","method":"history.get","params":"history":0,"itemids":["24526"],"time_from":"1392789600","time_till":"1392790200","output":"extend","auth": "a826fca79a0795ccc1224dc76329972f","id": 0' http://x.x.x.x/api_jsonrpc.php

输出:

#输出:
  ["itemid":"24526","clock":"1392789646","value":"95.7539","ns":"138978589",
  "itemid":"24526","clock":"1392789706","value":"84.9595","ns":"578198422",
  "itemid":"24526","clock":"1392789766","value":"94.5259","ns":"186216653",
  "itemid":"24526","clock":"1392789826","value":"96.2286","ns":"789434167",
  "itemid":"24526","clock":"1392789886","value":"94.7712","ns":"191954191",
  "itemid":"24526","clock":"1392789946","value":"90.8338","ns":"781241168",
  "itemid":"24526","clock":"1392790006","value":"89.1735","ns":"294674458",
  "itemid":"24526","clock":"1392790066","value":"92.3015","ns":"877714419",
  "itemid":"24526","clock":"1392790126","value":"96.3051","ns":"426421789",
  "itemid":"24526","clock":"1392790186","value":"97.7931","ns":"174500891"]
  #“value”就是cpu idle值,采样间隔时间与监控项的数据更新时间一致。


补充:获取192.168.211.60监控项"system.cpu.util[,idle,avg1]"20190911日 下午2:02:46 的值
  curl -i -X POST -H 'Content-Type: application/json' -d '"jsonrpc": "2.0","method":"history.get","params":"history":0,"itemids":["24526"],"time_from":"1392789600","time_till":"1392790200","output":"extend","filter":"clock":"1572789766","auth": "a826fca79a0795ccc1224dc76329972f","id": 0' http://x.x.x.x/api_jsonrpc.php
  #"value":"94.5259"要获取的值
三、根据zabbix的参数选项是否为必须,进行解释

address:是我的项目测试地址:192.168.36.133,这里由于是本机直接使用127.0.0.1
一定要注意后面获取历史数据时,参数得到问题,要把history改为0,不然会出现获取不到数据。
一定要注意,因为这个问题,我一直没发现是这个原因,后来仔细看了官方文档才发现问题出在这里。

1,user.login方法获得认证密钥。

1)请求的方法参数

参数名称值类型说明是否必须
jsonrpcstr接口版本
methodstr请求方法
paramsjson请求方法参数
userstrzabbix账号
passwordstrzabbix密码
authstr认证的key
idint认证id

2) 请求的示例

[root@zabbix-master cmdd]# curl -i -X POST -H 'Content-Type:application/json' -d '"jsonrpc":"2.0","method":"user.login","params":"user":"Admin","password":"zabbix","auth":null,"id":0' http://127.0.0.1/zabbix/api_jsonrpc.php
HTTP/1.1 200 OK
Date: Fri, 13 Sep 2019 11:32:10 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
X-Powered-By: PHP/5.4.16
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST
Access-Control-Max-Age: 1000
Content-Length: 68
Content-Type: application/json

返回得到response数据格式
"jsonrpc":"2.0","result":"e66e63d8916eebceeae3cddf721f4e93","id":0[root@zabbix-master cmdd]# 
2, hostgroup.get方法获取所有主机组ID
参数名称值类型说明是否必须
jsonrpcstr接口版本
methodstr请求方法
paramsjson请求方法参数
outputarray输出格式
groupidstr主机组id
namestr主机组名
authstr认证的key
idint认证id
  1. 请求的示例
root@zabbix-master cmdd]# curl -i -X POST -H 'Content-Type:application/json' -d '"jsonrpc": "2.0","method":"hostgroup.get","params":"output":["groupid","name"],"auth":"e66e63d8916eebceeae3cddf721f4e93","id": 0' http://127.0.0.1/zabbix/api_jsonrpc.php                                
HTTP/1.1 200 OK
Date: Fri, 13 Sep 2019 11:37:57 GMT
Server: Apache/2.4.6 (CentOS以上是关于基于Python调用zabbix监控的API接口详解,将数据展现到前台过程思路分析的主要内容,如果未能解决你的问题,请参考以下文章

zabbix批量添加主机监控-zabbix api调用

基于Django实现Linux运维管理平台的整个实现过程和各种API接口调用以及Echarts绘图项目介绍记录点滴生活

调用zabbix的api接口导出主机的SLA数据

python3调用zabbix api接口对自动发现添加的主机修改主机名

Python调用Zabbix API接口批量修改(禁用/启用)触发器trigger

zabbix调用api接口批量添加主机