监控模板和脚本github地址:https://github.com/jasonmcintosh/rabbitmq-zabbix/tree/master/scripts/rabbitmq

.将rabbitmq监控相关的文件拷贝到/usr/local/zabbix_agents_3.2.0/scripts目录下

[root@eus_pe_web02:/usr/local/zabbix_agents_3.2.0/scripts]# ls -la rabbitmq/
total
drwxr-xr-x root root Oct : .
drwxr-xr-x root root Oct : ..
-rwxr-xr-x root root Oct : api.py
-rwxr-xr-x root root Oct : list_rabbit_nodes.sh
-rwxr-xr-x root root Oct : list_rabbit_queues.sh
-rwxr-xr-x root root Oct : list_rabbit_shovels.sh
-rw-r--r-- root root Oct : .rab.auth
-rwxr-xr-x root root Oct : rabbitmq-status.sh .添加api配置文件(rabbitmq的账户信息)
.rab.auth USERNAME=admin
PASSWORD=admin
CONF=/usr/local/zabbix_agents_3.2.0/conf/zabbix_agentd.conf
LOGLEVEL=INFO
LOGFILE=/var/log/zabbix/rabbitmq_zabbix.log
PORT= .添加配置文件
[root@eus_pe_web02:/usr/local/zabbix_agents_3.2.0/scripts]# cat ../conf/zabbix_agentd/zabbix-rabbitmq.conf
UserParameter=rabbitmq.discovery_queues,/usr/local/zabbix_agents_3.2.0/scripts/rabbitmq/list_rabbit_queues.sh
UserParameter=rabbitmq.discovery_shovels,/usr/local/zabbix_agents_3.2.0/scripts/rabbitmq/list_rabbit_shovels.sh
UserParameter=rabbitmq.discovery_nodes,/usr/local/zabbix_agents_3.2.0/scripts/rabbitmq/list_rabbit_nodes.sh
UserParameter=rabbitmq[*],/usr/local/zabbix_agents_3.2.0/scripts/rabbitmq/rabbitmq-status.sh $ $ $ .导入rabbitmq模板 .重新启动zabbix-agent,并在被监控机器添加监控模板即可 # 主要的api接口
# cat api.py #!/usr/bin/env /usr/bin/python
'''Python module to query the RabbitMQ Management Plugin REST API and get
results that can then be used by Zabbix.
https://github.com/jasonmcintosh/rabbitmq-zabbix
'''
from __future__ import unicode_literals import io
import json
import optparse
import socket
import urllib2
import subprocess
import os
import logging class RabbitMQAPI(object):
'''Class for RabbitMQ Management API''' def __init__(self, user_name='guest', password='guest', host_name='',
port=, conf='/usr/local/zabbix_agents_3.2.0/conf/zabbix_agentd.conf', senderhostname=None, protocol='http'):
self.user_name = user_name
self.password = password
self.host_name = host_name or socket.gethostname()
self.port = port
self.conf = conf or '/usr/local/zabbix_agents_3.2.0/conf/zabbix_agentd.conf'
self.senderhostname = senderhostname or socket.gethostname()
self.protocol = protocol or 'http' def call_api(self, path):
'''Call the REST API and convert the results into JSON.'''
url = '{0}://{1}:{2}/api/{3}'.format(self.protocol, self.host_name, self.port, path)
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, url, self.user_name, self.password)
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
logging.debug('Issue a rabbit API call to get data on ' + path + " against " + self.host_name)
logging.debug('Full URL:' + url)
return json.loads(urllib2.build_opener(handler).open(url).read()) def list_queues(self, filters=None):
'''
List all of the RabbitMQ queues, filtered against the filters provided
in .rab.auth. See README.md for more information.
'''
queues = []
if not filters:
filters = [{}]
for queue in self.call_api('queues'):
logging.debug("Discovered queue " + queue['name'] + ", checking to see if it's filtered...")
for _filter in filters:
check = [(x, y) for x, y in queue.items() if x in _filter]
shared_items = set(_filter.items()).intersection(check)
if len(shared_items) == len(_filter):
element = {'{#NODENAME}': queue['node'],
'{#VHOSTNAME}': queue['vhost'],
'{#QUEUENAME}': queue['name']}
queues.append(element)
logging.debug('Discovered queue '+queue['vhost']+'/'+queue['name'])
break
return queues def list_shovels(self, filters=None):
'''
List all of the RabbitMQ shovels, filtered against the filters provided
in .rab.auth. See README.md for more information.
'''
shovels = []
if not filters:
filters = [{}]
try:
for shovel in self.call_api('shovels'):
logging.debug("Discovered shovel " + shovel['name'] + ", checking to see if it's filtered...")
for _filter in filters:
check = [(x, y) for x, y in shovel.items() if x in _filter]
shared_items = set(_filter.items()).intersection(check)
if len(shared_items) == len(_filter):
element = {'{#VHOSTNAME}': shovel['vhost'],
'{#SHOVELNAME}': shovel['name']}
shovels.append(element)
logging.debug('Discovered shovel '+shovel['vhost']+'/'+shovel['name'])
break
return shovels
except urllib2.HTTPError as err:
if err.code == :
return shovels
else:
raise err def list_nodes(self):
'''Lists all rabbitMQ nodes in the cluster'''
nodes = []
for node in self.call_api('nodes'):
# We need to return the node name, because Zabbix
# does not support @ as an item parameter
name = node['name'].split('@')[]
element = {'{#NODENAME}': name,
'{#NODETYPE}': node['type']}
nodes.append(element)
logging.debug('Discovered nodes '+name+'/'+node['type'])
return nodes def check_queue(self, filters=None):
'''Return the value for a specific item in a queue's details.'''
return_code =
if not filters:
filters = [{}] buffer = io.StringIO() try:
for queue in self.call_api('queues'):
success = False
logging.debug("Filtering out by " + str(filters))
for _filter in filters:
check = [(x, y) for x, y in queue.items() if x in _filter]
shared_items = set(_filter.items()).intersection(check)
if len(shared_items) == len(_filter):
success = True
break
if success:
self._prepare_data(queue, buffer)
except urllib2.HTTPError as err:
if err.code == :
buffer.close()
return return_code
else:
raise err return_code = self._send_data(buffer)
buffer.close()
return return_code def check_shovel(self, filters=None):
'''Return the value for a specific item in a shovel's details.'''
return_code =
if not filters:
filters = [{}] buffer = io.StringIO() try:
for shovel in self.call_api('shovels'):
success = False
logging.debug("Filtering out by " + str(filters))
for _filter in filters:
check = [(x, y) for x, y in shovel.items() if x in _filter]
shared_items = set(_filter.items()).intersection(check)
if len(shared_items) == len(_filter):
success = True
break
if success:
key = '"rabbitmq.shovels[{0},shovel_{1},{2}]"'
key = key.format(shovel['vhost'], 'state', shovel['name'])
value = shovel.get('state', )
logging.debug("SENDER_DATA: - %s %s" % (key,value))
buffer.write("- %s %s\n" % (key, value))
except urllib2.HTTPError as err:
if err.code == :
buffer.close()
return return_code
else:
raise err return_code = self._send_data(buffer)
buffer.close()
return return_code def _prepare_data(self, queue, file):
'''Prepare the queue data for sending'''
for item in ['memory', 'messages', 'messages_unacknowledged',
'consumers']:
key = '"rabbitmq.queues[{0},queue_{1},{2}]"'
key = key.format(queue['vhost'], item, queue['name'])
value = queue.get(item, )
logging.debug("SENDER_DATA: - %s %s" % (key,value))
file.write("- %s %s\n" % (key, value))
## This is a non standard bit of information added after the standard items
for item in ['deliver_get', 'publish', 'ack']:
key = '"rabbitmq.queues[{0},queue_message_stats_{1},{2}]"'
key = key.format(queue['vhost'], item, queue['name'])
value = queue.get('message_stats', {}).get(item, )
logging.debug("SENDER_DATA: - %s %s" % (key,value))
file.write("- %s %s\n" % (key, value)) def _send_data(self, file):
'''Send the queue data to Zabbix.'''
args = 'zabbix_sender -vv -c {0} -i -'
if self.senderhostname:
args = args + " -s " + self.senderhostname
return_code =
process = subprocess.Popen(args.format(self.conf),
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = process.communicate(input=file.getvalue())
logging.debug("Finished sending data")
return_code = process.wait()
logging.info("Found return code of " + str(return_code))
if return_code == :
logging.error(out)
logging.error(err)
else:
logging.debug(err)
logging.debug(out)
return return_code def check_aliveness(self):
'''Check the aliveness status of a given vhost.'''
return self.call_api('aliveness-test/%2f')['status'] def check_server(self, item, node_name):
'''First, check the overview specific items'''
if item == 'message_stats_deliver_get':
return self.call_api('overview').get('message_stats', {}).get('deliver_get_details', {}).get('rate',)
elif item == 'message_stats_publish':
return self.call_api('overview').get('message_stats', {}).get('publish_details', {}).get('rate',)
elif item == 'message_stats_ack':
return self.call_api('overview').get('message_stats', {}).get('ack_details', {}).get('rate',)
elif item == 'message_count_total':
return self.call_api('overview').get('queue_totals', {}).get('messages',)
elif item == 'message_count_ready':
return self.call_api('overview').get('queue_totals', {}).get('messages_ready',)
elif item == 'message_count_unacknowledged':
return self.call_api('overview').get('queue_totals', {}).get('messages_unacknowledged',)
elif item == 'rabbitmq_version':
return self.call_api('overview').get('rabbitmq_version', 'None')
'''Return the value for a specific item in a node's details.'''
node_name = node_name.split('.')[]
nodeInfo = self.call_api('nodes')
for nodeData in nodeInfo:
logging.debug("Checking to see if node name {0} is in {1} for item {2} found {3} nodes".format(node_name, nodeData['name'], item, len(nodeInfo)))
if node_name in nodeData['name'] or len(nodeInfo) == :
logging.debug("Got data from node {0} of {1} ".format(node_name, nodeData.get(item)))
return nodeData.get(item)
return 'Not Found' def main():
'''Command-line parameters and decoding for Zabbix use/consumption.'''
choices = ['list_queues', 'list_shovels', 'list_nodes', 'queues', 'shovels', 'check_aliveness',
'server']
parser = optparse.OptionParser()
parser.add_option('--username', help='RabbitMQ API username', default='esignnew')
parser.add_option('--password', help='RabbitMQ API password', default='tAjFxsjEE4JXzXp')
parser.add_option('--hostname', help='RabbitMQ API host', default=socket.gethostname())
parser.add_option('--protocol', help='Use http or https', default='http')
parser.add_option('--port', help='RabbitMQ API port', type='int', default=)
parser.add_option('--check', type='choice', choices=choices, help='Type of check')
parser.add_option('--metric', help='Which metric to evaluate', default='')
parser.add_option('--filters', help='Filter used queues (see README)')
parser.add_option('--node', help='Which node to check (valid for --check=server)')
parser.add_option('--conf', default='/usr/local/zabbix_agents_3.2.0/conf/zabbix_agentd.conf')
parser.add_option('--senderhostname', default='', help='Allows including a sender parameter on calls to zabbix_sender')
parser.add_option('--logfile', help='File to log errors (defaults to /var/log/zabbix/rabbitmq_zabbix.log)', default='/var/log/zabbix/rabbitmq_zabbix.log')
parser.add_option('--loglevel', help='Defaults to INFO', default='INFO')
(options, args) = parser.parse_args()
if not options.check:
parser.error('At least one check should be specified')
logging.basicConfig(filename=options.logfile or "/var/log/zabbix/rabbitmq_zabbix.log", level=logging.getLevelName(options.loglevel or "INFO"), format='%(asctime)s %(levelname)s: %(message)s') logging.debug("Started trying to process data")
api = RabbitMQAPI(user_name=options.username, password=options.password,
host_name=options.hostname, port=options.port,
conf=options.conf, senderhostname=options.senderhostname,
protocol=options.protocol)
if options.filters:
try:
filters = json.loads(options.filters)
except KeyError:
parser.error('Invalid filters object.')
else:
filters = [{}]
if not isinstance(filters, (list, tuple)):
filters = [filters]
if options.check == 'list_queues':
print json.dumps({'data': api.list_queues(filters)})
elif options.check == 'list_nodes':
print json.dumps({'data': api.list_nodes()})
elif options.check == 'list_shovels':
print json.dumps({'data': api.list_shovels()})
elif options.check == 'queues':
print api.check_queue(filters)
elif options.check == 'shovels':
print api.check_shovel(filters)
elif options.check == 'check_aliveness':
print api.check_aliveness()
elif options.check == 'server':
if not options.metric:
parser.error('Missing required parameter: "metric"')
else:
if options.node:
print api.check_server(options.metric, options.node)
else:
print api.check_server(options.metric, api.host_name) if __name__ == '__main__':
main()

上面的方法如果当rabbitmq的队列很多,自动发现会有几百个监控项,对服务器造成很大压力,有一种简单的方式获取队列

# 获取rabbitmq积压队列个数
UserParameter=queues_num,/usr/sbin/rabbitmqctl list_queues | grep -v delay | grep -v queues >> /tmp/rabbitmq.txt && awk '{total+=$2}END{print total}' /tmp/rabbitmq.txt

可以配置当队列数大于30或根据业务配置合适的值触发报警

上面的方法在zabbix_get的时候会报错

[root~]# zabbix_get -s 1.1.1.1 -k 'queues_num'
erlexec: HOME must be set
0

采用下面的方法获取队列

1.配置计划任务

# 3分钟获取一次rabbitmq的队列
*/3 * * * * /usr/sbin/rabbitmqctl list_queues | grep -v delay | grep -v queues > /tmp/rabbitmq.txt

2.配置item

UserParameter=queues_num,awk '{total+=$2}END{print total}' /tmp/rabbitmq.txt

# 有时候通过rabbitmqctl命令获取不到数据,此时我们可以通过 rabbitmqadmin 这个工具来输入账号密码来获取具体的信息
# cd /usr/bin/
# wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-management/v3.7.8/bin/rabbitmqadmin

/usr/bin/rabbitmqadmin -H 1.1.1.1 -P 15672 -u rabbit -p 'pass' -f tsv -q list queues >> /tmp/rabbitmq.txt && awk '{total+=$2}END{print total}' /tmp/rabbitmq.txt

# 获取rabbitmq积压队列个数
UserParameter=queues_num,/usr/bin/rabbitmqadmin -H 1.1.1.1 -P 15672 -u rabbit -p 'pass' -f tsv -q list queues >> /tmp/rabbitmq.txt && awk '{total+=$2}END{print total}' /tmp/rabbitmq.txt

可以配置当队列数大于30或根据业务配置合适的值触发报警

采用下面的方法获取队列

1.配置计划任务

# 3分钟获取一次rabbitmq的队列
*/3 * * * * /usr/bin/rabbitmqadmin -H 172.20.73.208 -P 15672 -u rabbit -p 'pass' -f tsv -q list queues > /tmp/rabbitmq.txt

2.配置item
UserParameter=queues_num,awk '{total+=$2}END{print total}' /tmp/rabbitmq.txt

zabbix3.2监控rabbitmq集群的更多相关文章

  1. 使用Prometheus和Grafana监控RabbitMQ集群 (使用RabbitMQ自带插件)

    配置RabbitMQ集群 官方文档:https://www.rabbitmq.com/prometheus.html#quick-start 官方github地址:https://github.com ...

  2. prometheus-operator 监控 Rabbitmq集群

    首先我们监控服务需要知道prometheus-operator是如何去工作的,才好去写相关的yaml配置,这里我划分成了5个部分,如果容器服务本身就以k8s来编排的,那就只需要三步,这里因为我的rab ...

  3. k8s中安装rabbitmq集群

    官方文档地址:https://www.rabbitmq.com/kubernetes/operator/quickstart-operator.html 要求 1.k8s版本要1.18及其以上 2.能 ...

  4. RabbitMq 集群搭建

        实验环境: 操作系统为 Centos 7.2 IP hostName 192.168.190.132 node132 192.168.190.139 node139 192.168.190.1 ...

  5. RabbitMQ 集群+负载均衡

    负载均衡 集群的配置已经搭建好了,代码也成功跑通,成功做到了高可用,但是我们的程序连接节点并不会管哪个服务器在忙.哪个服务器空闲,完全看心情想连谁就连谁.而且代码中要把每个ip的节点都手动的写出来 , ...

  6. RabbitMQ集群、镜像部署配置

    1   RABBITMQ简介及安装 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python.Ruby..NET.Java.JMS.C.PHP.Act ...

  7. RabbitMQ 集群与高可用配置

    集群概述 通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务给客户端连接,进行消息发送 ...

  8. (转)RabbitMQ 集群与高可用配置

    集群概述 环境 配置步骤 集群概述 通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务 ...

  9. CentOS7安装RabbitMQ集群

    实验环境 RabbitMQ 集群 server1.example.com    IP: 10.10.10.11    Node: diskserver2.example.com    IP: 10.1 ...

随机推荐

  1. System.IO在不存在的路径下创建文件夹和文件的测试

    本文测试System.IO命名空间下的类,在不存在的路径下创建文件夹和文件的效果: 首先测试创建文件夹: System.IO.Directory.CreateDirectory(@"C:\A ...

  2. Linux下redis的安装及配置

    1.去官网下载redis(redis.io) 2.将其解压到根目录下 3.进入解压的目录,然后编译源程序, 如果不是root账户登录的,命令前面需要加sudo make make install PR ...

  3. iOS 封装SDK以及封装时bundle文件的处理

    这篇教程的主要目的是解释怎么样在你的iOS工程中创建并使用一个SDK,俗称.a文件. 环境:xcode 9.0 创建一个静态库工程 打开Xcode,点击File\New\Project, 选择iOS\ ...

  4. Java instanceof运算符

    java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法: res ...

  5. springdata find立即加载 get延迟加载 get返回的是一个动态代理对象 特点是 用的时候才会查询 否则不查询

  6. Nginx 请求的11个阶段

    48 1:当请求进入Nginx后先READ REQUEST HEADERS 读取头部 然后再分配由哪个指令操作 2:Identity 寻找匹配哪个Location  3:Apply Rate Limi ...

  7. BZOJ3498PA2009 Cakes——三元环

    题目描述 N个点m条边,每个点有一个点权a.对于任意一个三元环(j,j,k)(i<j<k),它的贡献为max(ai,aj,ak) 求所有三元环的贡献和.N<100000,,m< ...

  8. Scrapy 框架 配置文件

    配置文件 基本配置 #1.项目名称,默认的USER_AGENT由它来构成,也作为日志记录的日志名 BOT_NAME = 'Amazon' #2.爬虫应用路径 SPIDER_MODULES = ['Am ...

  9. git 操作命令详解

    git 什么是git 开源的分布式版本控制系统, 用于高效的管理大小项目和文件 代码管理工具 防止代码丢失, 做备份 代码版本管控, 设置节点, 多版本切换 建立分支各自开发, 互不影响, 方便合并 ...

  10. purge旧的ubuntu 的linux内核

    https://www.sysgeek.cn/remove-old-kernels-ubuntu-16-04/