基於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,主要版本內部具有向後兼容性。

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調用方法,其userpassword參數爲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、函數handleHosthandleGroup負責處理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. 主機模式

指定主機host1host2,關聯操作系統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入門的同學來說也能輕鬆理解。最後希望本案例能給各位朋友帶來啓發,如有疑問歡迎一起交流。


推薦閱讀



_

● 基於TimeScaleDB(PG時序數據庫)離線部署Zabbix5.4-蔡斯


_


_

Zabbix全年在線課錄屏


_


_

● Zabbix學習資料、客戶案例申請(往屆峯會ppt)


_


_

● 兼容信創:如何在銀河麒麟系統上離線安裝Zabbix5.0?-蔡斯


_


備註“使用Zabbix年限+企業+姓名”

進入交流羣,4000+用戶已加入

一個人走得快,一羣人走得遠


本文分享自微信公衆號 - Zabbix開源社區(china_zabbix)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章