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. Python项目生成requirements.txt文件及pip升级问题解决及流程

    缘由:新项目使用Python, PC上的python包不全,需要通过requirements.txt文件指定安装所需包 pip安装遇到一些坑 一.直接使用pip包管理工具生成requirements. ...

  2. 分区命令(大于2TB的分区)

    注意:parted命令在恢复误删除的分区时候,容易失败的几点: (1)只划分一个分区.恢复失败 (2)划分了2个分区,但是没有格式化.直接删除一个分区,恢复也会失败. (3)做删除操作时候,如果同时删 ...

  3. cpu负载

    查看cpu负载,我们经常会使用top,或者是uptime命令 但是这只能看到cpu的总体的负载情况.如果我们想看cpu每个核心的负载情况是看不到的. 所以我们可以用mpstat命令 服务器一共32核心 ...

  4. Django_静态资源配置和ajax(九)

    一.静态资源配置 静态资源的相关配置都在项目目录下的 settings.py 文件中进行配置.配置参数如下: # 浏览器访问静态资源时的路径 STATIC_URL = '/static2/' # 存放 ...

  5. RHCSA 第一天

    1.修改主机名: 查看主机名 2.查看日期 使用指定格式输出日期 YY-mm-DD HH:MM:SS 3.将"We are learning RHCSA"输出在屏幕上 4.使用ti ...

  6. 面试突击17:HashMap除了死循环还有什么问题?

    面试合集:https://gitee.com/mydb/interview 本篇的这个问题是一个开放性问题,HashMap 除了死循环之外,还有其他什么问题?总体来说 HashMap 的所有" ...

  7. Servlet监听器统计网站在线人数

    本节我们利用 Servlet 监听器接口,完成一个统计网站在线人数的案例.当一个用户登录后,显示欢迎信息,同时显示出当前在线人数和用户名单.当用户退出登录或 Session 过期时,从在线用户名单中删 ...

  8. 鸿蒙轻内核M核源码分析:LibC实现之Musl LibC

    摘要:本文学习了LiteOS-M内核Musl LibC的实现,特别是文件系统和内存分配释放部分. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十九 Musl LibC>,作者:zhus ...

  9. IDEA2020.1破解

    IDEA2020.1破解 安装 下载idea idea官方下载地址:https://www.jetbrains.com/webstorm/download/other.html 下载破解插件 链接:h ...

  10. dubbo-gateway 高性能dubbo网关

    dubbo-gateway dubbo-gateway 提供了http协议到dubbo协议的转换,但[并非]使用dubbo的[泛化]调用(泛化调用性能比普通调用有10-20%的损耗,通过普通异步的调用 ...