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个数据取其平均值,这样在一定精确度内,图形会更好看

 

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