蔡斯 | 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,主要版本內部具有向後兼容性。
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)
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入門的同學來說也能輕鬆理解。最後希望本案例能給各位朋友帶來啓發,如有疑問歡迎一起交流。
推薦閱讀
|
|||
|
|||
|
|||
|
備註“使用Zabbix年限+企業+姓名”
進入交流羣,4000+用戶已加入
一個人走得快,一羣人走得遠
本文分享自微信公衆號 - Zabbix開源社區(china_zabbix)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。