如何利用zabbix进行自定义监控,相信看过我文章的同学已经摸清了套路。但是在丰富监控的同时,我们也发现告警越来越多,尤其是发生大面积网络中断时,一时间上百台机器同时发送告警,就造成了告警风暴,那怎么让这类告警只发送一次呢?
首先梳理下告警流程:
告警基本是有监控项数据收集——>告警触发——>发送用户,几个基本环节。从图中可以看出告警触发后,又细分了动作-用户-媒介-脚本几部分,主要的作用是通过动作判断哪类告警是需要收敛的,在关联用户、媒介、脚本,通过脚本处理,最终合并为一个告警邮件发送到收件人
脚本的逻辑思路是:将告警风暴推入redis缓存,经过压缩合并后再发送。具体的代码如下:
推入redis脚本
#!/usr/bin/env python
#coding:utf-8
import redis
import sys
subject=sys.argv[1]
r = redis.StrictRedis(host='127.0.0.1', port=6379)
r.set(subject,subject)
告警合并和发送脚本
#!/usr/bin/env python
#coding:utf-8
import MySQLdb
import redis
import os,sys
import datetime,time
import re
#在zabbix 可以找到告警收敛的动作ID(actionid)
actionid=XXX
#连接redis,并读取所有事件id
r = redis.StrictRedis(host='127.0.0.1', port=6379)
sendtime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
usermail='/home/app/mysh/tomaillist.txt'
mailtitle='测试告警收敛'
problemfile='/tmp/problemtmp.txt'
okfile='/tmp/oktmp.txt'
#定义通过actionid和subject获取数据库告警具体信息,并返回
def alerts_eventid(actionid,subject):
try:
conn=MySQLdb.connect(host='127.0.0.1',user='zabbix',passwd='zabbix',db='zabbix',port=3306)
cursor = conn.cursor()
cursor.execute("SET NAMES utf8");
sql ="SELECT * FROM alerts where actionid = '%s' and subject = '%s' ;" % (actionid,subject)
cursor.execute(sql)
data = cursor.fetchall()
cursor.close()
conn.close()
for rowin data:
message = row[8]
return message
except MySQLdb.Error, e:
"Mysql Error %d: %s" % (e.args[0], e.args[1])
def classification(subjectlist):
for subjectin subjectlist:
if 'PROBLEM' in subject:
a=alerts_eventid(str(actionid),subject)
with open(problemfile, 'a+')as f:
f.write(str(a))
else:
a = alerts_eventid(str(actionid), subject)
with open(okfile, 'a+')as f:
f.write(str(a))
def sendmail(filename):
for linein open(usermail):
line = line.strip('\r\n')
print '发送给',line
os.system("cat %s | sed s/'\r'//g | mail -s %s %s" % (filename,mailtitle,line))
if os.path.exists(filename):
os.remove(filename)
if __name__ =="__main__":
subjectlist=r.keys()
for iin subjectlist:
r.delete(i)
if subjectlist:
classification(subjectlist)
if os.path.exists(problemfile):
print sendtime,'发送告警邮件\n'
sendmail(problemfile)
elif os.path.exists(okfile):
print sendtime,'发送恢复邮件\n'
sendmail(okfile)
else:
print sendtime,'无告警邮件\n'
CentOS自带python2.7,安装几个依赖框架即可。最后定制个定时任务crontab -e
*/2 * * * * python sendalert.py >> send.log
每两分钟收集一次,若有告警风暴,只收一个告警,不用再收几百条告警了。
网友评论