基于ZabbixAPI快速生成多Keys监控图表_git

蔡斯 | Zabbix开源社区签约专家


  • Zabbix资深玩家,SRE高级运维,架构师。精通服务组件监控、模板制作及告警治理。
  • 擅长领域:Zabbix API定制化开发,对接企业蓝鲸,JMS保垒机等运维资产管理。


随着公司的业务规模不断扩大,运维纳管机器的数量也在增加,引入自动化手段为捉襟见肘的工作减压,已成为重中之重。本文分享笔者在企业DevOps过程中,是如何有效结合ZabbixAPI来实现批量监控的案例。

1. 前置条件

1.1. 接口分析

假若当前有个新的监控要求:业主希望快速将一批主机的某个监控项关联到一张图上来(非grpfunc叠加),即以CPU、MEM、DISK等维度纵向对比这批主机的资源使用情况。很显然,当主机数超过一定量时手工创建会非常枯燥和繁琐,所幸Zabbix提供了API。我们通过分析Zabbix Docs中的​​graph.create​​​图表接口,得知要提供的主机HostID、监控项键值ItemID,使用到的Zagbix Method主要有:​​User​​​​Host​​​​HostGroup​​​​Item​​​​Graph​​​等5种方法。基于ZabbixAPI快速生成多Keys监控图表_zabbix_02

如上图,描述本次批量创建图表的主要脚本逻辑,即先获取Zabbix的身份验证令牌,然后查询主机或主机群获得其HOSTID,接着以HOSTID依次获取指定监控键值ID加入列表池,最后一次性请求​​graph.create​​进行图表创建。

1.2. 环境约定

系统/工具

版本

Zabbix

5.0.1

CentOS

7.6.1810

Python

3.6.8

本自动化案例脚本在Zabbix5.0验证通过,理论上支持Zabbix5.4,主要版本内部具有向后兼容性。

2. 构建接口

2.1. 认证类(AUTH)

创建​​AUTH​​类并声明一个私有函数​​__init__​​,用来初始化Zabbix接口、Zabbix用户名,Zabbix密码。在条件允许的情况下,建议使用​​SuperAdmin​​超管用户,跑通之后再进行权限精细化管理。

class AUTH(object):    def  __init__(self):        self.zabbix_api = set.Zabbix["api"]        self.zabbix_user = set.Zabbix["user"]        self.zabbix_pass = set.Zabbix["pass"]

创建​​rcpResult​​函数,作为桥接Zabbix API数据通道的桥梁。Zabbix API使用JSON-RPC 2.0协议,作为Web前端的一部分提供,支持HTTP POST协议。

def rpcResult(self, params):    headers = {"Content-Type": "application/json-rpc"}    rsp = requests.post(url=self.zabbix_api, headers=headers, data=json.dumps(params))    try:        return  rsp.json()["result"]    except:        set.logger.error(rsp.json()["error"])        exit(1)

创建​​getToken​​函数,在进入ZabbixAPI神秘世界之前,需申请一张身份验证令牌。官方提供了一个叫​​user.login​​的method调用方法,其​​user​​,​​password​​参数为Web端账密信息,而​​id​​作为请求的标识符,其支持整形、浮点型、字符串3种数据类型。

def getToken(self):
params = {
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": self.zabbix_user,
"password": self.zabbix_pass,
},
"id": "Chasii"
}
return self.rpcResult(params)

通过调用AUTH类的Get_Token函数​​AUTH().Get_Token()​​,得到接口返回的​​result​​,就是我们通往神秘世界的一把钥匙。

{    "jsonrpc": "2.0",    "result": "22e6f614a89ccc1c1226429c4b7b08a0",    "id": "Chasii"}

值得注意的是,通过​​user.login​​方法申请到的身份验证令牌其永久生效,不会被系统释放。频繁调度会产生大量opensession记录,从而占用系统资源。这里给出了三种解决方案:

1、在Web端将对应用户的 Auto-logout
选项勾上并设置时间使其自动失效。

2、将身份校验令牌缓存成文本或存入中间件,可重复调用,

3、使用 user.logout
方法,即用即销,安全绿色。

如下​​destroyToken​​函数,提供了官网注销Token的方法。

def destroyToken(self, token):    params = {        "jsonrpc": "2.0",        "method": "user.logout",        "params": [],        "auth": token,        "id": "Chasii"    }    return self.rpcResult(params)


2.2. 主机类(HOST)

创建​​HOST​​类并声明​​__init__​​私有函数,通过入参​​zbx_token​​获取ZabbixAPI身份令牌,供本类函数调用。

class HOST(object):    def  __init__(self, zbx_token):        self.zbx_token = zbx_token

创建​​getGroupID​​函数,通过查询指定​​groupid​​群主ID,返回该组内所有主机ID及其主机名。

def getHostID(self, groupid):    params = {        "jsonrpc": "2.0",        "method": "host.get",        "params": {            "output": ["hostid","host"],            "groupids": groupid        },        "auth": self.zbx_token,        "id": "Chasii"    }    return AUTH().rpcResult(params)


2.3. 群组类(HOSTGROUP)

创建​​HOSTGROUP​​类并声明​​__init__​​私有函数,通过入参​​zbx_token​​获取ZabbixAPI身份令牌,供本类函数调用。

class HOSTGROUP(object):    def  __init__(self, zbx_token):        self.zbx_token = zbx_token

创建​​getGroupID​​函数,通过查询指定群组名​​hostgroup​​,返回群组ID。

def getGroupID(self, hostgroup):    params = {        "jsonrpc": "2.0",        "method": "hostgroup.get",        "params": {            "output": "groupid",            "filter": {"name": [hostgroup]}        },        "auth": self.zbx_token,        "id": "Chasii"    }    return AUTH().rpcResult(params)


2.4. 指标类(ITEM)

创建​​ITEM​​指标类并声明一个私有函数,通过入参​​zbx_token​​获取ZabbixAPI身份令牌,供本类函数调用。

class ITEM(object):    def  __init__(self, zbx_token):        self.zbx_token = zbx_token

创建​​getItemID​​函数,通过查询指定主机名​​host​​和指标项​​key​​,返回监控项ID。

def getItemID(self, host, key):    params = {        "jsonrpc": "2.0",        "method": "item.get",        "params": {            "output": "itemid",            "host": host,            "search": { "key_": key},        },        "auth": self.zbx_token,        "id": "Chasii"    }    return AUTH().rpcResult(params)


2.5. 图表类(GRAPH)

Zabbix​​graph.create​​接口参数说明:


必选参数

支持类型

示例

name

字符串

图表的名称、如Biz_Group001_CPU、Biz_Group001_MEM

width

整数型

图表的高度,如900像素,在config.py文件中指定

height

整数型

图表的高度,如200像素,在config.py文件中指定

gitems

列表型

图标的监控项列表,如[{"itemid":"22828","color":"00AA00"}]

创建一个​​GRAPH​​指标类并声明一个私有函数,通过入参​​zbx_token​​获取ZabbixAPI身份令牌,供本类函数调用。

class GRAPH(object):    def  __init__(self, zbx_token):        self.zbx_token = zbx_token

创建​​createGrapth​​函数,指定图表名​​gname​​,图表宽度​​gwidth​​,图表高度​​gheigth​​,图表监控项参数​​gitems​​。

def createGrapth(self, gname, gwidth, gheight, gitems):    params = {        "jsonrpc": "2.0",        "method": "graph.create",        "params": {            "name": gname,"width": gwidth,"height": gheight,"gitems": gitems        },        "auth": self.zbx_token,        "id": "Chasii"    }    return AUTH().rpcResult(params)


3. 调用接口

3.1. 项目介绍

通过上面对官方API的解读,我们已经知道如何使用它了。那么接下来的任务就是如何将这些配件、模块组装起来,让它running起来。为更方便讲解本案例,笔者已将上述相关API脚本上传至Github。读者可关注和克隆到本地使用,未来会支持更多功能。


项目代码Git地址:https://github.com/Chasii/ZabbixCli.git


项目框架说明

ZabbixCli├── app # Zabbix接口│   └── api.py├── conf # Zabbix配置│   └── settings.py├── docs # Zabbix说明│   ├── Nginx-Established.png│   └── Sequence-Diagram.png├── logs # 程序日志│   └── zbx.log├── readme.md└── zbxcli.py # 统一入口


3.2. 配置分离

通过配置分离,将易变的模块拎出来作为独立文件,增强项目稳定性和可塑性。​​config.py​​文件定义了日志输出格式、日志输出方式(文件、控制台),同时指定Zabbix账号及图表的默认像素,读者可根据自身情况及需求进行调整,下面摘取部分代码进行展示。

# Log Set...log_fmt = '%(asctime)s  %(filename)s [line:%(lineno)d] %(levelname)s:%(message)s'# Export Console....logger.addHandler(rf_handler)# Export Logfile...logger.addHandler(f_handler)# Env SetZabbix = {    "api": "http://<your_ip>/api_jsonrpc.php",    "user": "<your_name>",    "pass": "<your_pass>",...}

3.3. 创建入口

创建​​ZBXCLI​​入口类并声明一个私有函数,调用​​AUTH​​类获得初始ZabbixAPI身份令牌,供本类函数调用。

class  ZBXCLI(object):    def  __init__(self):        self.zbx_token = zbx.AUTH().getToken()

如下函数主要处理CLI传来参数,其中函数​​randomColor​​返回随机16进制颜色码、函数​​handleItem​​根据主机名和监控指标获取ItemID、函数​​handleHost​​、​​handleGroup​​负责处理HostID,函数​​createGraph​​请求接口创建图表。

def  randomColor(self):     return ("".join(random.choice("0123456789ABCDEF") for  i  in  range(6)))def  handleItem(self, key, hosts):     items = []     for host in hosts:         items.append(zbx.ITEM(self.zbx_token).getItemID(host, key)[0]["itemid"])     return itemsdef  handleHost(self, hosts):     items = self.handleItem(args.key, hosts)     self.createGraph(items)     ...def  handleGroup(self, groups):     for group  in  groups:         result = zbx.HOSTGROUP(self.zbx_token).getGroupID(group)     ...def  createGraph(self, items):     gitems = []     ...


3.4. 调用示例

ZabbixCli参数说明

参数

说明

key

监控键值(Key),注意不是监控的指标名

name

图表名,需保持唯一性,支持中文

type

支持类型指定主机群组or主机,有特殊字符请加上双引号

nargs

主机群组/主机列表参数,多参数请使用空格分开,支持中文

$ python3 zbxcli.py -husage: zbxcli.py [-h] -key KEY -name NAME -type {hostgraph,groupgraph} -nargs                 NARGS [NARGS ...]=== Zabbix Cli ===optional arguments:  -h, --help            show this help message and exit  -key KEY              Zabbix Item Key  -type {hostgraph,groupgraph}  -nargs NARGS [NARGS ...]


3.4.1. 主机模式

指定主机​​host1​​,​​host2​​,关联操作系统CPU负载的键值​​system.cpu.load[all,avg5]​​,并将图表命名为​​RELATE_GRAPH.CPU.LOAD.AVG5​​。

$ python3 zbxcli.py -key "system.cpu.load[all,avg5]" \-name "RELATE_GRAPH.CPU.LOAD.AVG5" \-type hostgraph \-nargs "host1" "host2"2021-12-11 17:32:58,507 zbxcli.py [line:52] INFO:{'graphids': ['57138']}

打开任意指定主机的​​Graph​​配置项,查找​​RELATE_GRAPH.CPU.LOAD.AVG5​​图表名字可以看到,我们创建的主机键值已经关联到一张图表上了,通过Preview可正常显示。基于ZabbixAPI快速生成多Keys监控图表_群组_03基于ZabbixAPI快速生成多Keys监控图表_群组_04


3.4.2. 群组模式

指定群组​​BizGroup001主机群组​​,​​BizGroup002主机群组​​,关联所有主机的Nginx-Established链接数,键值为​​tcp_conn_established​​自定义Key,图表命名为​​RELATE_GRAPH.TCP_CONN_ESTABLISH​​。

$ python3 zbxcli.py -key "tcp_conn_established" -name "RELATE_GRAPH.TCP_CONN_ESTABLISH" -type groupgraph -nargs "BizGroup001主机群组" "BizGroup002主机群组"2021-12-11 17:45:36,212 zbxcli.py [line:42] INFO:"BizGroup001主机群组" includes these hosts: host1,host2,...2021-12-11 17:45:36,851 zbxcli.py [line:52] INFO:{'graphids': ['57139']}2021-12-11 17:45:36,212 zbxcli.py [line:42] INFO:"BizGroup002主机群组" includes these hosts: host3,host4,...2021-12-11 17:45:36,851 zbxcli.py [line:52] INFO:{'graphids': ['57140']}

通过指定单台/多台群组,自动将指标值关联到一张表上。我们通过控制台日志可以看到,​​ZabbixCli​​​分别在​​BizGroup001主机群组​​,​​BizGroup002主机群组​​的主机里创建​​graphids​​为57139和57140的图表,通过快速访问​​https://<your_ip>/chart2.php?graphid=<your_graphids>​​得知它们展示的数据一样。基于ZabbixAPI快速生成多Keys监控图表_git_05

本文从监控需求分析入手,介绍了整个自动化思路、ZabbixAPI调用方法、图形接口构建与整合、统一Cli入口,相信对于Zabbix和Python入门的同学来说也能轻松理解。最后希望本案例能给各位朋友带来启发,如有疑问欢迎一起交流。


一个人走得快,一群人走得远


微信公众号 - Zabbix开源社区(china_zabbix)。