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

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

1.2. 环境约定
系统/工具 版本
Zabbix 5.0.1
CentOS 7.6.1810
Python 3.6.8
本自动化案例脚本在Zabbix5.0验证通过,理论上支持Zabbix5.4,主要版本内部具有向后兼容性。

  1. 构建接口
    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)
Zabbixgraph.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 Set

Zabbix = {
“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 items
def 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 -h
usage: 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可正常显示。图片图片

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调用方法、图形接口构建与整合、统一Cli入口,相信对于Zabbix和Python入门的同学来说也能轻松理解。最后希望本案例能给各位朋友带来启发,如有疑问欢迎一起交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值