Python拉取zabbix數據並使用matplotlib模塊繪圖

1.爲從zabbix拉取數據,我們可以新建一個類,初始化一些基本屬性

class ZabbixAPI():
    def __init__(self):
        self.url = 'http://zabbix_domain_name/api_jsonrpc.php'
        self.username = username
        self.password = password
        self.header = {"Content-Type": "application/json-rpc"}

2.封裝請求,方便每次調用,並簡單處理返回的響應

    def request(self, data):
        request = requests.post(url=self.url, headers=self.header, data=json.dumps(data))
        response = json.loads(request.text)
        request.close()
        print(response)
        if response.get("error"):
            print(response.get("error"))
            return None
        else:
            return response.get("result")

3.登錄API並獲取token

    def login(self):
        data = {
            "jsonrpc": "2.0",
            "method": "user.login",
            "params": {
                "user": self.username,
                "password": self.password
            },
            "id": 1
        }
        return self.request(data)

有了token之後我們就可以調用API接口完成想要做的事情,這裏只列舉幾個API方法,詳細的可以參考官方文檔

zabbix_api = ZabbixAPI()
token = zabbix_api.login()

4.獲取主機列表

    def host_list(self, token):
        data = {
            "jsonrpc": "2.0",
            "method": "host.get",
            "params": {
                "output": ["hostid"],
                "selectInterfaces": ["ip"]
            },
            "id": 2,
            "auth": token
        }
        return self.request(data)
hosts = zabbix_api.host_list(token)
print(hosts)
>>> [{'hostid': '10084', 'interfaces': [{'ip': '127.0.0.1'}]}...]

5.通過主機id獲取單個主機下所有監控項(id由主機列表中獲取)

    def host_metric_list(self, token, hostId):
        data = {
            "jsonrpc": "2.0",
            "method": "item.get",
            "params": {
                "output": ["itemids", "key_"],
                "hostids": hostId,
            },
            "auth": token,
            "id": 3
        }
        return self.request(data)
monitor_items = zabbix_api.host_metric_list(token, hosts[1]["hostid"])
print(monitor_items)
>>>[{'itemid': '29034', 'key_': 'perf_counter[\Processor(_Total)\% Processor Time]'}...]

6.通過監控項id獲取它的歷史數據(具體參數可查zabbix官網)

    def metric_id_data(self, token, itemids, time_from, history=3):
        data = {
            "jsonrpc": "2.0",
            "method": "history.get",
            "params": {
                "output": "extend",
                "history": history,
                "itemids": itemids,
                "sortfield": "clock",   # 按時間排序
                "limit": 50             # 取最近n條數據
                "time_from": time_from
                # "time_till": time_till
            },
            "auth": token,
            "id": 1
        }
        return self.request(data)
itemids:監控項id,上一個方法得到;

time_from(time_till):(時間戳形式)僅返回在給定時間時或之後(前)收到的值

histtory:  integer類型  歷史對象的類型,默認3
          0 - numeric float 數字浮點數;
          1 - character 字符; 
          2 - log 日誌;
          3 - numeric unsigned 數字符號; 
          4 - text.文本.   
import time

def datetime_control(datetime, para):
    timeArray = time.strptime(datetime, para)
    timeStamp = int(time.mktime(timeArray))
    return timeStamp

time_from = datetime_control("2019-4-5 00:00:00", "%Y-%m-%d %H:%M:%S")
history_data = zabbix_api.metric_id_data(token, "29034", time_from, 0)
print(history_data)
>>>[{'itemid': '29034', 'clock': '1554393654', 'value': '12.0000', 'ns': '168808299'}...]

  可以看到,zabbix返回了一個列表,其中每個元素就包含了該監控項在那個時間的值,這裏我們取的是“CPU使用百分比”

7.處理歷史監控數據

  將zabbix返回的clock時間戳轉換爲時間格式<class 'datetime.datetime'>

def timestamp_control(timeStamp, para):
    timeArray = time.localtime(int(timeStamp))
    date_time = time.strftime(para, timeArray)
    return datetime.datetime.strptime(date_time, "%Y-%m-%d %H:%M:%S")

x_values = []
y_values = []
for data_stamp in history_data:
    clock = timestamp_control(data_stamp["clock"], "%Y-%m-%d %H:%M:%S")
    value = float(data_stamp["value"])
    x_values.append(clock)
    y_values.append(value)

8.通過監控數據繪圖

import matplotlib.dates as mdate
import matplotlib.pyplot as plt


def draw_picture(picture_title, x_values, y_values):
    fig = plt.figure(1, (16, 6))
    ax = plt.gca()
    # 添加網格,透明度0.2
    ax.grid(alpha=0.2)
    # 設置y軸單位及保留小數位
    ax.yaxis.set_major_formatter(mticker.FormatStrFormatter("%.0f %%"))
    ax.plot_date(x_values, y_values, linestyle='-', marker='', linewidth=1)
    # 填充圖形陰影
    ax.fill_between(x=x_values, y1=min(y_values), y2=y_values, where=max(y_values) >= min(y_values), alpha=0.2)

    ax.set_xlim(np.datetime64(x_values[0], 'D'), np.datetime64(x_values[-1], 'D') + np.timedelta64(1, 'D'), auto=False)
    # 橫座標軸時間格式設置
    ax.xaxis.set_major_formatter(mdate.DateFormatter('%m-%d %H:%M'))

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
    plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號
    # 自動旋轉標記
    # plt.gcf().autofmt_xdate()
    # 線條粗細
    # plt.plot(x_values, y_values, linewidth=1)
    # 標題
    plt.title("{0}\nMaxinum: , Mininum: , Average: , Peak_Time: ".format(picture_title), fontsize=20)

    # 座標軸標題設置(文本, 字體大小, 水平放置)
    # plt.xlabel(label, fontsize=20, rotation="horizontal")
    # plt.ylabel(label, fontsize=10, rotation="horizontal")

    # 設置刻度的樣式
    plt.tick_params(axis='both', labelsize=20)

    plt.show()
    plt.close(fig)
draw_picture("服務器CPU使用率(%)", x_values, y_values)

有時候,如果採集的數據過多,可以處理一下,比如每10個數據取其平均值,這樣在一定精確度內,圖形會更好看

 

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