Zabbix与RRDtool绘图篇(1)_用ZabbixAPI取监控数据

经过一个星期的死磕,Zabbix取数据和RRDtool绘图都弄清楚了,做第一运维平台的时候绘图取数据是直接从Zabbix的数据库取的,显得有点笨拙,不过借此也了解了Zabbix数据库结构还是有不少的收获。

学习Zabbix的API官方文档少不了,官方文档地址链接https://www.zabbix.com/documentation/ 大家选择对应的版本就好了,不过2.0版本的API手册位置有点特别开始我还以为没有,后来找到了如下https://www.zabbix.com/documentation/2.0/manual/appendix/api/api   用ZabbixAPI取监控数据的思路大致是这样的,先获取所有监控的主机,再遍历每台主机获取每台主机的所有图形,最后获取每张图形每个监控对象(item)的最新的监控数据或者一定时间范围的数据。   下面按照上面的思路就一段一段的贴出我的程序代码:

1、登录Zabbix获取通信token

#!/usr/bin/env python
#coding=utf-8
import json
import urllib2
import sys

##########################
class Zabbix:
	def __init__(self):
		self.url = "http://xxx.xxx.xxx.xxx:xxxxx/api_jsonrpc.php"
		self.header = {"Content-Type": "application/json"}
		self.authID = self.user_login()
	def user_login(self):
		data = json.dumps({
							"jsonrpc": "2.0",
							"method": "user.login",
							"params": {"user": "用户名",	"password": "密码"},
							"id": 0})
		request = urllib2.Request(self.url,data)
		for key in self.header:
			request.add_header(key,self.header[key])
		try:
			result = urllib2.urlopen(request)
		except URLError as e:
			print "Auth Failed, Please Check Your Name And Password:",e.code
		else:
			response = json.loads(result.read())
			result.close()
			authID = response['result']
			return authID

	##################通用请求处理函数####################
	def get_data(self,data,hostip=""):
		request = urllib2.Request(self.url,data)
		for key in self.header:
			request.add_header(key,self.header[key])
		try:
			result = urllib2.urlopen(request)
		except URLError as e:
			if hasattr(e, 'reason'):
				print 'We failed to reach a server.'
				print 'Reason: ', e.reason
			elif hasattr(e, 'code'):
				print 'The server could not fulfill the request.'
				print 'Error code: ', e.code
				return 0
		else:
			response = json.loads(result.read())
			result.close()
			return response

2、获取所有主机

#####################################################################
	#获取所有主机和对应的hostid
	def hostsid_get(self):
		data = json.dumps({
							"jsonrpc": "2.0",
							"method": "host.get",
							"params": { "output":["hostid","status","host"]},
							"auth": self.authID,
							"id": 1})
		res = self.get_data(data)['result']
		#可以返回完整信息
		#return res
		hostsid = []
		if (res != 0) and (len(res) != 0):
			for host in res:
				if host['status'] == '1':
					hostsid.append({host['host']:host['hostid']})
				elif host['status'] == '0':
					hostsid.append({host['host']:host['hostid']})
				else:
					pass
		return hostsid

返回的结果是一个列表,每个元素是一个字典,字典的key代表主机名,value代表hostid zabbixget01

3、获取每台主机的每张图形

###################################################################
	#查找一台主机的所有图形和图形id
	def hostgraph_get(self, hostname):
		data = json.dumps({
							"jsonrpc": "2.0",
							"method": "host.get",
							"params": { "selectGraphs": ["graphid","name"],
										"filter": {"host": hostname}},
							"auth": self.authID,
							"id": 1})
		res = self.get_data(data)['result']
		#可以返回完整信息rs,含有hostid
		return res[0]['graphs']

注意传入的参数是主机名而不是主机id,结果也是由字典组成的列表。zabbixget02

4、获取每张图的监控对象item

	#可以返回完整信息rs,含有hostid
		tmp = res[0]['items']
		items = []
		for value in tmp:
			if '$' in value['name']:
				name0 = value['key_'].split('[')[1].split(']')[0].replace(',', '')
				name1 = value['name'].split()
				if 'CPU' in name1:
					name1.pop(-2)
					name1.insert(1,name0)
				else:
					name1.pop()
					name1.append(name0)		
				name = ' '.join(name1)
				tmpitems = {'itemid':value['itemid'],'delay':value['delay'],'units':value['units'],'name':name,'value_type':value['value_type'],'lastclock':value['lastclock'],'lastvalue':value['lastvalue']}
			else:
				tmpitems = {'itemid':value['itemid'],'delay':value['delay'],'units':value['units'],'name':value['name'],'value_type':value['value_type'],'lastclock':value['lastclock'],'lastvalue':value['lastvalue']}
			items.append(tmpitems)
		return items

返回的数据已经包含了最新的一次监控数据的值和取值的时间戳,如果只需要取最新的监控数据,到这里其实就可以了,记得这次传入的参数是graphid。 zabbixget03

5、根据itemid取得更多的监控数据,下面是取10条监控数据,可以任意更改参数获取更多的数据,全凭自己所需了。

################################################################
	#获取历史数据,history必须赋值正确的类型0,1,2,3,4 float,string,log,integer,text
	def history_get(self, itemid, i):
		data = json.dumps({
							"jsonrpc": "2.0",
							"method": "history.get",
							"params": { "output": "extend",
										"history": i,
										"itemids": itemid,
										"sortfield": "clock",
										"sortorder": "DESC",
										"limit": 10},
							"auth": self.authID,
							"id": 1})
		res = self.get_data(data)['result']
		return res

zabbixget04

上面的所有代码加起来就是一个Zabbix取数据的类。取出来的数据可以用RRDtool绘图或做其它用途了。 原创转载请注明出处: http://www.xiaomastack.com/2014/08/17/rrdtool-1/  谢谢!

8 Comments

 Add your comment
  1. 博主,您好,在运行你脚本的时候,出现了这样的错误:
    “D:\Program Files (x86)\python33\python.exe” “F:/python 文件/zabbix-1.py”
    File “F:/python 文件/zabbix-1.py”, line 105
    return items
    SyntaxError: ‘return’ outside function

    Process finished with exit code 1

    请解答,谢谢。

  2. 怪我路!你代码缩进没有问题吧。

  3. 没有啊,都是你的脚本,没有更改
    #查找一台主机的所有图形和图形id
    def hostgraph_get(self, hostname):
    data = json.dumps({
    “jsonrpc”: “2.0”,
    “method”: “host.get”,
    “params”: { “selectGraphs”: [“graphid”,”name”],
    “filter”: {“host”: hostname}},
    “auth”: self.authID,
    “id”: 1})
    res = self.get_data(data)[‘result’]
    #可以返回完整信息rs,含有hostid
    return res[0][‘graphs’]

    tmp = res[0][‘items’]
    items = []
    for value in tmp:
    if ‘$’ in value[‘name’]:
    name0 = value[‘key_’].split(‘[‘)[1].split(‘]’)[0].replace(‘,’, ”)
    name1 = value[‘name’].split()
    if ‘CPU’ in name1:
    name1.pop(-2)
    name1.insert(1,name0)
    else:
    name1.pop()
    name1.append(name0)
    name = ‘ ‘.join(name1)
    tmpitems = {‘itemid’:value[‘itemid’],’delay’:value[‘delay’],’units’:value[‘units’],’name’:name,’value_type’:value[‘value_type’],’lastclock’:value[‘lastclock’],’lastvalue’:value[‘lastvalue’]}
    else:
    tmpitems = {‘itemid’:value[‘itemid’],’delay’:value[‘delay’],’units’:value[‘units’],’name’:value[‘name’],’value_type’:value[‘value_type’],’lastclock’:value[‘lastclock’],’lastvalue’:value[‘lastvalue’]}
    items.append(tmpitems)
    return items

  4. 能否加QQ交流一下,谢谢

  5. 你看是不是zabbix api版本不一样造成的,我zabbix的版本是2.0.9的。

  6. 请问: 获取每张图的监控对象item 调用的是zabbix 什么 method?

    def graphitems_get(self,graphid):
    method”: “???”,
    “params”: { “???”: [???],
    “filter”: {???}},

  7. 获取item的途径很多,上面就是通过图形id获取每张图形的itemid,然后从历史记录history中根据itemid获取item的值。
    还可以根据hostid和监控项key值获取到itemid,这时返回值会有个最新的item值,如果要取更多需要根据itemid到history中取值,不知道新版本的zabbixapi有无变化,比如第二种方法类似这样:
    #获取item value
    def item_get(self, hostid, key):
    #获取主机监控key的itemid
    data = json.dumps({
    “jsonrpc”: “2.0”,
    “method”: “item.get”,
    “params”: {
    “output”: “extend”,
    “hostids”: hostid,
    “search”: {“key_”: key},
    },
    “auth”: self.authID,
    “id”: 1})
    res = self.get_data(data)[‘result’]
    try:
    itemid = res[0][‘itemid’]
    except:
    return False
    #一般上面的res都会包含一个item的lastvalue,但是发现获取的item类型为text的时候需要指定获取值的类型,不然值会被截断
    data = json.dumps({
    “jsonrpc”: “2.0”,
    “method”: “history.get”,
    “params”: {
    “output”: “extend”,
    “history”: 4,
    “itemids”: itemid,
    “sortfield”: “clock”,
    “sortorder”: “DESC”,
    “limit”: 1
    },
    “auth”: self.authID,
    “id”: 1})
    res = self.get_data(data)[‘result’]
    try:
    return res[0][‘value’]
    except:
    return False

  8. 谢谢:)
    以下的方法报错: 可以帮忙看看?谢谢
    获取每张图的监控对象item 中的function
    def graphitems_get(self,graphid):
    data = json.dumps({
    “jsonrpc”: “2.0”,
    “method”: “item.get”,
    “params”: { “output”: “extend”,
    “graphids”: graphid},
    “auth”: self.authID,
    “id”: 1})
    res = self.get_data(data)[‘result’]
    #可以返回完整信息rs,含有hostid
    tmp = res[0][‘items’]
    items = []
    for value in tmp:
    if ‘$’ in value[‘name’]:
    name0 = value[‘key_’].split(‘[‘)[1].split(‘]’)[0].replace(‘,’, ”)
    name1 = value[‘name’].split()
    if ‘CPU’ in name1:
    name1.pop(-2)
    name1.insert(1,name0)
    else:
    name1.pop()
    name1.append(name0)
    name = ‘ ‘.join(name1)
    tmpitems = {‘itemid’:value[‘itemid’],’delay’:value[‘delay’],’units’:value[‘units’],’name’:name,’value_type’:value[‘value_type’],’lastclock’:value[‘lastclock’],’lastvalue’:value[‘lastvalue’]}
    else:
    tmpitems = {‘itemid’:value[‘itemid’],’delay’:value[‘delay’],’units’:value[‘units’],’name’:value[‘name’],’value_type’:value[‘value_type’],’lastclock’:value[‘lastclock’],’lastvalue’:value[‘lastvalue’]}
    items.append(tmpitems)
    return items

发表评论:

你的电子邮件地址将不会被公开.

× 6 = 24