1 python实现在4.2版本zabbix发送带有图片的报警邮件

我们通常收到的报警,都是文字,是把动作中的消息内容当成了正文参数传给脚本,然后邮件或者微信进行接收,往往只能看到当前值,无法直观的获取到历史当天该监控项的运行曲线图,因此根据此需求,使用python编写脚本来分别对邮件告警和微信告警,进行升级,报警内容中加入了当天的历史趋势图,功夫不负有心人,已成功解锁,并实践成功,因此分享出来供大家参考,另外得非常感谢脚本编写中刚哥大神和王二基友给予的帮助

1.1 实现思路

  • 首先报警信息里第一行要有itemid,这是前提,根据信息里传入的参数使用正则匹配到itemid

  • 使用脚本创建一个zabbix会话,来根据itemid来获取图片,并将获取到的图片保存到本地

  • 将传入的参数信息的text字段转换成HTML格式,然后将HTML格式的信息和图片作为邮件进行发送

1.2 准备环境

  • 脚本是使用python脚本,运行环境为python 2.7.5

  • 依赖库:

    requests

1.3 脚本实现

  1 [root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/  #进入zabbix默认的脚本路径
2 [root@5804703917ad alertscripts]# mkdir graph #创建一个存放图片的文件夹
3 [root@5804703917ad alertscripts]# chmod 777 graph #给文件夹赋予权限
4 [root@5804703917ad alertscripts]# vim zabbix_email_pic.py #编写实现脚本
5 #!/usr/bin/python
6 #coding=utf-8
7 from email.mime.text import MIMEText
8 from email.mime.multipart import MIMEMultipart
9 from email.mime.image import MIMEImage
10 import smtplib,sys,os,time,re,requests
11 from smtplib import SMTP
12 ​
13 user='Admin' #定义zabbix用户名
14 password='zabbix' #定义zabbix用户密码
15 graph_path='/usr/lib/zabbix/alertscripts/graph' #定义图片存储路径
16 graph_url='http://192.168.73.133/chart.php' #定义图表的url
17 loginurl="http://192.168.73.133/index.php" #定义登录的url
18 host='192.168.73.133'
19 to_email=sys.argv[1] #传入的第一个参数为收件人邮箱
20 subject=sys.argv[2] #传入的第二个参数为邮件主题
21 subject=subject.decode('utf-8')
22 smtp_host = 'smtp.163.com' #定义smtp主机地址
23 from_email = 'xxxx@163.com.cn' #定义发件人地址
24 mail_pass = 'xxx' #发件人邮箱校验码
25 ​
26 def get_itemid():
27 #获取报警的itemid
28 itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)
29 return itemid
30 ​
31 def get_graph(itemid):
32 #获取报警的图表并保存
33 session=requests.Session() #创建一个session会话
34 try:
35 loginheaders={
36 "Host":host,
37 "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
38 }
39 #定义请求消息头
40 ​
41 payload = {
42 "name":user,
43 "password":password,
44 "autologin":"1",
45 "enter":"Sign in",
46 }
47 #定义传入的data
48 login=session.post(url=loginurl,headers=loginheaders,data=payload)
49 #进行登录
50 graph_params={
51 "from" :"now-10m",
52 "to" : "now",
53 "itemids" : itemid,
54 "width" : "400",
55 }
56 #定义获取图片的参数
57 graph_req=session.get(url=graph_url,params=graph_params)
58 #发送get请求获取图片数据
59 time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
60 graph_name='baojing_'+time_tag+'.png'
61 #用报警时间来作为图片名进行保存
62 graph_name = os.path.join(graph_path, graph_name)
63 #使用绝对路径保存图片
64 with open(graph_name,'wb') as f:
65 f.write(graph_req.content)
66 #将获取到的图片数据写入到文件中去
67 return graph_name
68 ​
69 except Exception as e:
70 print(e)
71 return False
72 def text_to_html(text):
73 #将邮件内容text字段转换成HTML格式
74 d=text.splitlines()
75 #将邮件内容以每行作为一个列表元素存储在列表中
76 html_text=''
77 for i in d:
78 i='' + i + '<br>'
79 html_text+=i + '\n'
80 #为列表的每个元素后加上html的换行标签
81 return html_text
82 ​
83 def send_mail(graph_name):
84 #将html和图片封装成邮件进行发送
85 msg = MIMEMultipart('related') #创建内嵌资源的实例
86 ​
87 with open(graph_name,'rb') as f:
88 #读取图片文件
89 graph=MIMEImage(f.read()) #读取图片赋值一个图片对象
90 graph.add_header('Content-ID','imgid1') #为图片对象添加标题字段和值
91 text=text_to_html(sys.argv[3])
92 html="""
93 <html>
94 <body>
95 %s <br><img src="cid:imgid1">
96 </body>
97 </html>
98 """ % text
99 html=MIMEText(html,'html','utf-8') #创建HTML格式的邮件体
100 msg.attach(html) #使用attach方法将HTML添加到msg实例中
101 msg.attach(graph) #使用attach方法将图片添加到msg实例中
102 msg['Subject'] = subject
103 msg['From'] = from_email
104 try:
105 server=SMTP(smtp_host,"587") #创建一个smtp对象
106 server.starttls() #启用安全传输模式
107 server.login(from_email,mail_pass) #邮箱账号登录
108 server.sendmail(from_email,to_email,msg.as_string()) #发送邮件
109 server.quit() #断开smtp连接
110 except smtplib.SMTPException as a:
111 print(a)
112 ​
113 def run():
114 itemid=get_itemid()
115 graph_name=get_graph(itemid)
116 send_mail(graph_name)
117 ​
118 if __name__ =='__main__':
119 run()

1.4 定义报警媒介类型

  • 打开zabbix监控web,在管理菜单中选择报警媒介类型,创建媒体类型,选择脚本,填写刚才编写的邮件带图脚本名称zabbix_email_pic.py,脚本参数,最后添加

  • 打开管理中的用户,点击需要设置邮件告警的用户,然后在报警媒介中添加报警媒介,在弹框中选择刚才定义的类型,然后填写想要发送的邮箱地址,最后添加

    1.5 定义告警动作

  • 点击配置菜单中的动作,创建动作,然后根据图片进行填写

操作
默认标题 Zabbix告警:服务器:{HOSTNAME}发生: {TRIGGER.NAME}故障!
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}
恢复操作
Zabbix告警:服务器:{HOST.NAME}发生: {TRIGGER.NAME}已恢复!
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}


1.6 最终效果

可以手动触发一个报警测试效果

2 python实现在4.2版本zabbix发送带有图片的微信告警

2.1 实现思路

  • 首先创建企业公众号获取agentId,secret和部门id

  • 然后根据报警信息获取itemid,使用正则匹配到itemid

  • 使用脚本创建一个zabbix会话,来根据itemid来获取图片,并将获取到的图片保存到本地

  • 调用企业微信api接口,把图片当成临时素材上传,返回一个media_id,给发送消息和图片调用使用,最后使用mpnews消息类型把图片和报警内容进行推送到微信上

    2.2 准备环境

  • 脚本是使用python脚本,运行环境为python 2.7.5

  • 依赖库提前安装:

    requests

2.3 创建企业公众号获取agentid,secret

这部分内容,可以查看前面不带图的文章有详细描述

2.4 脚本实现

  1 [root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/  #进入zabbix默认的脚本路径
2 [root@5804703917ad alertscripts]# mkdir graph #创建一个存放图片的文件夹
3 [root@5804703917ad alertscripts]# chmod 777 graph #给文件夹赋予权限
4 [root@5804703917ad alertscripts]# vim zabbix_weixin_pic.py #编写实现脚本
5 #!/usr/bin/python
6 #coding=utf-8
7 _author__ = 'zhangdongdong'
8 import requests, json
9 import urllib3
10 import smtplib,sys,os,time,re,requests
11 from email.mime.image import MIMEImage
12 if sys.getdefaultencoding() != 'utf-8':
13 reload(sys)
14 sys.setdefaultencoding('utf-8')
15 urllib3.disable_warnings()
16 class WechatImage(object): # 根据企业微信api接口文档,定义一个类,使用mpnews类型,https://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
17 ​
18 def get_token(self, corpid, secret): # 获取token
19 url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
20 data = {"corpid": corpid,
21 "corpsecret": secret}
22 r = requests.get(url=url, params=data, verify=False)
23 token = r.json()['access_token']
24 return token
25 ​
26 def get_image_url(self, token, path): # 上传临时素材图片,然后返回media_id
27 url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image" % token
28 data = {"media": open(path, 'rb')}
29 r = requests.post(url=url, files=data)
30 dict_data = r.json()
31 return dict_data['media_id']
32 def get_messages( self,subject,content,path): #定义mpnews类型中的参数字典
33 data = ''
34 messages = {}
35 body = {}
36 content_html=text_to_html(content)
37 token = self.get_token(corpid, secret)
38 image = self.get_image_url(token, path)
39 content_html += "<br/> <img src='https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s'>" % (token, image)
40 body["title"] = subject
41 body['digest'] = content
42 body['content'] = content_html
43 body['thumb_media_id'] = image
44 data = []
45 data.append(body)
46 messages['articles'] = data
47 return messages
48 def send_news_message(self, corpid, secret,to_user, agentid,path): #定义发送mpnews类型的数据
49 token = self.get_token(corpid, secret)
50 messages = self.get_messages( subject, content,path)
51 url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % token
52 data = {"toparty": to_user, # 企业号中的用户帐号
53 "agentid": agentid, # 企业号中的应用id
54 "msgtype": "mpnews",
55 "mpnews": messages,
56 "safe": "0"}
57 headers = {'content-type': 'application/json'}
58 data_dict = json.dumps(data, ensure_ascii=False).encode('utf-8')
59 r = requests.post(url=url, headers=headers, data=data_dict)
60 return r.text
61 def text_to_html(text): #将邮件内容text字段转换成HTML格式
62 d=text.splitlines()
63 #将邮件内容以每行作为一个列表元素存储在列表中
64 html_text=''
65 for i in d:
66 i='' + i + '<br>'
67 html_text+=i + '\n'
68 #为列表的每个元素后加上html的换行标签
69 return html_text
70 def get_itemid():
71 #获取报警的itemid
72 itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)
73 return itemid
74 def get_graph(itemid):
75 #获取报警的图表并保存
76 session=requests.Session() #创建一个session会话
77 try:
78 loginheaders={
79 "Host":host,
80 "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
81 }
82 #定义请求消息头
83 ​
84 payload = {
85 "name":user,
86 "password":password,
87 "autologin":"1",
88 "enter":"Sign in",
89 }
90 #定义传入的data
91 login=session.post(url=loginurl,headers=loginheaders,data=payload)
92 #进行登录
93 graph_params={
94 "from" :"now-10m",
95 "to" : "now",
96 "itemids" : itemid,
97 "width" : "290", #图片的高宽参数可以自行调整
98 "height" : "40",
99 }
100 #定义获取图片的参数
101 graph_req=session.get(url=graph_url,params=graph_params)
102 #发送get请求获取图片数据
103 time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
104 graph_name='baojing_'+time_tag+'.png'
105 #用报警时间来作为图片名进行保存
106 graph_name = os.path.join(graph_path, graph_name)
107 #使用绝对路径保存图片
108 with open(graph_name,'wb') as f:
109 f.write(graph_req.content)
110 #将获取到的图片数据写入到文件中去
111 return graph_name
112 except Exception as e:
113 print(e)
114 return False
115 if __name__ == '__main__':
116 user='Admin' #定义zabbix用户名
117 password='zabbix' #定义zabbix用户i密
118 graph_path='/usr/lib/zabbix/alertscripts/graph/' #定义图片存储路径,图片需要定时清理
119 graph_url='http://192.168.73.133/chart.php' #定义图表的url
120 loginurl="http://192.168.73.133/index.php" #定义登录的url
121 host='192.168.73.133'
122 itemid=get_itemid()
123 path =get_graph(itemid)
124 to_user = str(sys.argv[1])
125 subject = str(sys.argv[2])
126 content = str(sys.argv[3])
127 corpid= "xxxxx"
128 secret = "xxxxxxx"
129 agentid = "1000002"
130 wechat_img = WechatImage()
131 wechat_img.send_news_message(corpid, secret,to_user, agentid, path)
 
  • 打开zabbix监控web,在管理菜单中选择报警媒介类型,创建媒体类型,选择脚本,填写刚才编写的微信带图脚本名称zabbix_weixin_pic.py,脚本参数,最后添加

  • 打开管理中的用户,点击需要设置邮件告警的用户,然后在报警媒介中添加报警媒介,在弹框中选择刚才定义的类型,然后填写企业微信中创建的部门id,最后添加

    2.6 定义告警动作

  • 点击配置菜单中的动作,创建动作,然后根据图片进行填写

操作
默认标题 Zabbix告警:服务器:{HOSTNAME}发生: {TRIGGER.NAME}故障!
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}
恢复操作
Zabbix告警:服务器:{HOST.NAME}发生: {TRIGGER.NAME}已恢复!
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}



2.7 测试效果

可以手动触发一个报警测试效果,手机上就可以收到带图的报警了,点击消息之后的页面也可以看到历史的图片

欢迎填加微信公众号,大家共同交流,共同进步

在zabbix中实现发送带有图片的邮件和微信告警的更多相关文章

  1. 接口测试基础——第3篇smtplib发送带图片的邮件

    smtplib发送邮件最后一篇,发送带图片的邮件: 大家可以去廖雪峰的网站看一下,下面的代码就是我跟着博客写的,哈哈,大家即使不明白为什么,也要多写两遍,记在心里,如果有不明白的地方可以留言,船长会第 ...

  2. zabbix 告警实践分享 一键实现zabbix 电话、邮件、微信告警

    众所周知Zabbix 是一款用来监控IT基础设施的监控套件,同时也具有很多方便运维人员使用的优秀功能,如:支持多条件告警,支持多种告警方式,支持多组模板.支持模板继承,因此在众多的开源运维监控软件中独 ...

  3. Android在发送带有附件的邮件

    准备好工作了-下载最新的版本号JMail https://java.net/projects/javamail/pages/Home#Download_JavaMail_1.5.2_Release h ...

  4. 【代码片段】Python发送带图片的邮件

    # coding=utf-8 import smtplib from email.mime.text import MIMEText from email.mime.multipart import ...

  5. Java Mail 发送带有附件的邮件

    1.小编用的是163邮箱发送邮件,所以要先登录163邮箱开启POP3/SMTP/IMAP服务方法: 2.下载所需的java-mail 包 https://maven.java.net/content/ ...

  6. Python模块探秘 Smtplib发送带有各种附件的邮件

    这两天对Python的邮件模块比较感兴趣,于是就查了查资料.同时在实际的编码过程中也遇到了各种各样的问题.下面我就来分享一下我与smtplib的故事. 前提条件 我的上一篇博文里面讲解了,发送邮件必须 ...

  7. java带图片的邮件发送方法实现

    package sendEmail; import java.util.Properties; import javax.activation.DataHandler; import javax.ac ...

  8. Spring 发送内嵌图片的邮件 遇到的问题

    问题1:spring 发送带图片的html格式的邮件? 解决方法1:直接在发送内容里面添加 <img src="http://www.rgagnon.com/images/jht.gi ...

  9. 在Linux命令行下发送html格式的邮件

    在Linux利用formail+sendmail来发送带图片的邮件 formail接收html格式的文件作为邮件的内容,这样就可以解决发送带图片邮件的问题了,因为html中可以插入图片,只要给出的im ...

随机推荐

  1. Java面向对象程序设计作业目录(作业笔记)

    持续更新中............. 我的大学笔记>>> 第1章 面向对象 >>> 1.1.5 编写Java程序,创建Dota游戏中的防御塔类,通过两个坐属性显示防 ...

  2. Java面向对象笔记 • 【第3章 继承与多态】

    全部章节   >>>> 本章目录 3.1 包 3.1.1 自定义包 3.1.2 包的导入 3.1.3 包的访问权限 3.1.4 实践练习 3.2 继承 3.2.1 继承概述 3 ...

  3. python 脚本或者flask 注册成为windows服务

    分享下脚本注册成为win服务 这个借鉴了其他大佬得 具体是谁忘记了有机会推荐 今天也是找了之前得改出来得 首先安装三个模块 最后一个是定时任务如果不需要可以不装 pip install psutil ...

  4. Kylin启动步骤

    Kylin本身的启动命令比较简单, 但是由于Kylin依赖的其他组件比较多, 所以把完整的启动步骤整理一下. 1.确保集群时间同步 首先查看集群中的时间是否同步 date 如果时间不一致,需要使用如下 ...

  5. Hadoop开启Kerberos安全模式

    Hadoop开启Kerberos安全模式, 基于已经安装好的Hadoop的2.7.1环境, 在此基础上开启Kerberos安全模式. 1.安装规划 已经安装好Hadoop的环境 10.43.159.7 ...

  6. SQL怎么求多列的和?

    日常比较常使用的SQL,查询各科的总分,并求出总分大于240的学生名字和总分,如图,要求出linux.Mysql.Java三科的总分,并查处总分大于240的学生姓名和总分 可能你会想到sum,但是su ...

  7. Python中单下划线与双下划线用法总结

    看mentor的脚本时,遇到self._item.callspec.getparam('')语句,理解起来比较困难,找到一篇文章,记录的比较详细,特别记录一下,以备复习. 附链接地址:http://w ...

  8. Selenium_环境安装(1)

    Selenium是一个用于Web应用程序自动化测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样. Selenium基本上支持主流的浏览器,包括IE,Mozilla Firef ...

  9. postgresql使用pg_dump工具进行数据库迁移

    一.使用管理员身份打开cmd,切换到postgresqlp安装目录下的bin目录 必须要以管理员身份打开cmd,否则报拒绝访问 二.把生成的文件上传到服务器上,同样cd 到postgresql的安装b ...

  10. 下载并搭建maven环境

    1.下载maven 1.在官网下载maven  http://maven.apache.org/download.cgi 2.将下载maven解压.复制路径. 2.搭建maven环境 1.新建M2_H ...