由于mq的队列数量不固定,经常删和新建队列,所以逐条添加每个队列的监控内容不太现实。所以使用python 实现自动发现mq队列(新创建队列也会发现),并发送给Zabbix。
一、获取rabbitmq的队列信息
这里使用python2.7
#coding=utf-8
__author__ = 'xuangey'
# 通过rabbitmq的接口获取所有队列
# 将队列名发送给zabbix
import json
import os
import requests
from urllib import urlencode
from sender_info import zabbix_sender
#mq的信息
mq_host="192.168.31.166" #Rabbitmq的地址
mq_port=15672
mq_user="admin"
mq_pass="******"
queues_url="http://%s:%d/api/queues" % (mq_host,mq_port)
#zabbix的信息
zab_ser='192.168.1.145' #zabbix服务器
zab_por=10051
zab_cli='1.187' #zabbix监控主机的名字
#获取rabbitmq的所有队列信息
def achive_info():
respones=requests.get(url=queues_url,auth=(mq_user,mq_pass))
# print respones.status_code 查看返回头信息
data=json.loads(respones.content.decode())
return data
#定义rabbit类
class rabbit:
#初始化队列的名字,消息数,消费者数等
def __init__(self,data):
self.queue_names=[]
self.queue_messge={}
self.queue_unack_messge={}
self.queue_ready={}
self.queue_consume={}
self.zabbix_send = zabbix_sender(zab_ser, zab_por)
for i in data:
self.queue_names.append(i['name'])
self.queue_messge[i['name']]=i['messages']
self.queue_unack_messge[i['name']]=i['messages_unacknowledged']
self.queue_ready[i['name']]=i['messages_ready']
self.queue_consume[i['name']]=i['consumers']
# print self.queue_messge
# print self.queue_consume
#队列名字转换为json格式发给zabbix,实现自动发现
def auto_discovery_mq(self):
queues = []
for i in self.queue_names:
queues += [{'{#QUE_NAME}': i}]
queues_data=json.dumps({'data':queues},sort_keys=True,indent=4)
self.zabbix_send.adddata(zab_cli,'discovery_queues',queues_data) #discovery_queues为zabbix服务端定义的key(监控消费者数量,消息总数,unack数量等)
def send_consumer(self):
for name in self.queue_consume.keys():
self.zabbix_send.adddata(zab_cli,'consumers[%s]' % name,self.queue_consume[name])
def send_ready(self):
for name in self.queue_ready.keys():
self.zabbix_send.adddata(zab_cli,'messages_ready[%s]' % name,self.queue_ready[name])
def send_unmgs(self):
for name in self.queue_unack_messge.keys():
self.zabbix_send.adddata(zab_cli,'messages_unacknowledged[%s]' % name,self.queue_unack_messge[name])
def send_msgs(self):
for name in self.queue_messge.keys():
self.zabbix_send.adddata(zab_cli,'messages[%s]' % name,self.queue_messge[name])
def main():
mq=rabbit(achive_info())
mq.auto_discovery_mq()
mq.send_consumer()
mq.send_ready()
mq.send_unmgs()
mq.send_msgs()
response = mq.zabbix_send.send()
print response
if __name__ == '__main__':
main()
二、发送数据给zabbix的脚本(网上有许多)
#coding=utf-8
# auther: xuangey
import json
import socket
import struct
class zabbix_sender:
def __init__(self,zbx_server_host,zbx_server_port):
self.zbx_server_host=zbx_server_host
self.zbx_server_port=zbx_server_port
self.zbx_header='ZBXD'
self.zbx_protocols_version=1
self.zbx_send_value={'request':'sender data','data':[]}
def adddata(self,host,key,value):
add_data={'host':host,'key':key,'value':value}
self.zbx_send_value['data'].append(add_data)
#按照协议封装数据包
def makesenddata(self):
zbx_send_json=json.dumps(self.zbx_send_value)
zbx_send_json_len=len(zbx_send_json)
self.zbx_send_data=struct.pack("<4sBq"+str(zbx_send_json_len)+"s",'ZBXD',1,zbx_send_json_len,zbx_send_json)
def send(self):
self.makesenddata()
zbx_server_socket=socket.socket()
zbx_server_socket.connect((self.zbx_server_host,self.zbx_server_port))
zbx_server_write_df=zbx_server_socket.makefile('wb')
zbx_server_write_df.write(self.zbx_send_data)
zbx_server_write_df.close()
zbx_server_read_df=zbx_server_socket.makefile('rb')
zbx_response_package=zbx_server_read_df.read()
zbx_server_read_df.close()
#按照协议解数据包
zbx_response_data=struct.unpack("<4sBq"+str(len(zbx_response_package) - struct.calcsize("<4sBq"))+"s",zbx_response_package)
return zbx_response_data[3]
if __name__ == '__main__':
pass
三、zabbix导入以下模板
以下内容复制为.xml文件并导入到zabbix模板
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>3.2</version>
<date>2020-04-17T06:56:20Z</date>
<groups>
<group>
<name>meme</name>
</group>
</groups>
<templates>
<template>
<template>rabbitmq_monitor</template>
<name>rabbitmq_monitor</name>
<description/>
<groups>
<group>
<name>meme</name>
</group>
</groups>
<applications/>
<items/>
<discovery_rules>
<discovery_rule>
<name>discovery_queues</name>
<type>2</type>
<snmp_community/>
<snmp_oid/>
<key>discovery_queues</key>
<delay>0</delay>
<status>0</status>
<allowed_hosts/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<delay_flex/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<filter>
<evaltype>0</evaltype>
<formula/>
<conditions/>
</filter>
<lifetime>2</lifetime>
<description/>
<item_prototypes>
<item_prototype>
<name>{#QUE_NAME}_consumers_消费者数目</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>consumers[{#QUE_NAME}]</key>
<delay>0</delay>
<history>60</history>
<trends>60</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description/>
<inventory_link>0</inventory_link>
<applications/>
<valuemap/>
<logtimefmt/>
<application_prototypes/>
</item_prototype>
<item_prototype>
<name>{#QUE_NAME}_messages_准备分发和未应答消息的总和(队列深度)</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>messages[{#QUE_NAME}]</key>
<delay>0</delay>
<history>60</history>
<trends>60</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description/>
<inventory_link>0</inventory_link>
<applications/>
<valuemap/>
<logtimefmt/>
<application_prototypes/>
</item_prototype>
<item_prototype>
<name>{#QUE_NAME}_messages_ready_准备分发给客户端的消息数目</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>messages_ready[{#QUE_NAME}]</key>
<delay>0</delay>
<history>60</history>
<trends>60</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description/>
<inventory_link>0</inventory_link>
<applications/>
<valuemap/>
<logtimefmt/>
<application_prototypes/>
</item_prototype>
<item_prototype>
<name>{#QUE_NAME}_messages_unacknowledged_分发到客户端但尚未应答的消息数目</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>messages_unacknowledged[{#QUE_NAME}]</key>
<delay>0</delay>
<history>60</history>
<trends>60</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description/>
<inventory_link>0</inventory_link>
<applications/>
<valuemap/>
<logtimefmt/>
<application_prototypes/>
</item_prototype>
</item_prototypes>
<trigger_prototypes>
<trigger_prototype>
<expression>{rabbitmq_monitor:consumers[{#QUE_NAME}].last()}=0</expression>
<recovery_mode>0</recovery_mode>
<recovery_expression/>
<name>{#QUE_NAME}_consumers_消费者数目</name>
<correlation_mode>0</correlation_mode>
<correlation_tag/>
<url/>
<status>0</status>
<priority>4</priority>
<description/>
<type>0</type>
<manual_close>0</manual_close>
<dependencies/>
<tags/>
</trigger_prototype>
<trigger_prototype>
<expression>{rabbitmq_monitor:messages[{#QUE_NAME}].last()}>20</expression>
<recovery_mode>0</recovery_mode>
<recovery_expression/>
<name>{#QUE_NAME}_messages_准备分发和未应答消息的总和(队列深度)</name>
<correlation_mode>0</correlation_mode>
<correlation_tag/>
<url/>
<status>0</status>
<priority>4</priority>
<description/>
<type>0</type>
<manual_close>0</manual_close>
<dependencies/>
<tags/>
</trigger_prototype>
</trigger_prototypes>
<graph_prototypes/>
<host_prototypes/>
</discovery_rule>
</discovery_rules>
<httptests/>
<macros/>
<templates/>
<screens/>
</template>
</templates>
</zabbix_export>
四、监控机绑定模板模板
我这里为最初脚本定义的名为1.187的机器;
然后设置脚本为每10分钟运行一次,zabbix即可收到监控信息。
Python新手大神手下留情。大家有更好的方法可以一起交流。如果不能使用,或使用时有问题可以联系我大家一起讨论。