翼度科技»论坛 编程开发 python 查看内容

(保姆级)服务器-Zabbix6.0使用Python脚本实现带图片的邮箱的报警

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
前言

近期在琢磨Zabbix邮箱报警的功能,但是网上的教程通常是4.0或5.0版本Zabbix,并使用Python2.7环境,运行在新版本Zabbix6.0上有颇多问题,为此我基于原先教程修改基于Zabbix6.0并使用Python3+的解决方案。期间遇到不少坑,特此分享。
Zabbix自带报警

Zabbix是自带的邮箱的报警功能有限,比如不能实现诸如邮件插入图片的功能,而可以使用执行脚本功能则可以调用本地程序,调用Python脚本从而实现许多如发送企业微信、钉钉使用的功能。
前端设置

报警媒介

在zabbix中保存脚本文件的目录为/usr/lib/zabbix/alertscripts/,目前4.0\5.0\6.0都通用,将shell脚本文件保存于此可以直接在报警媒介类型调用。

参数需要传递给脚本,对于着Shell脚本中的$1、$2、$3。
  1. {ALERT.SENDTO} //发件人(对应着用户\报警媒介中配置的发件人)
  2. {ALERT.SUBJECT} //主题(对应着主题模版)
  3. {ALERT.MESSAGE} //消息内容(对应着消息模版)
复制代码
发件人

主题\消息内容

报警媒介消息模版

在消息模版中,添加问题发生
  1. // 问题发生
  2. // 主题
  3. 发生故障:服务器:{HOSTNAME}->{TRIGGER.NAME}警告!
  4. // 消息
  5. 监控ID:{ITEM.ID}
  6. 告警主机:{HOST.NAME}
  7. 告警主机:{HOST.IP}
  8. 告警时间:{EVENT.DATE} {EVENT.TIME}
  9. 告警等级:{TRIGGER.SEVERITY}
  10. 告警信息: {TRIGGER.NAME}
  11. 告警项目:{TRIGGER.KEY}
  12. 问题详情:{ITEM.NAME}:{ITEM.VALUE}
  13. 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
  14. 事件ID:{EVENT.ID}
复制代码
添加问题恢复
  1. //问题恢复
  2. // 主题
  3. 问题恢复:服务器:{HOST.NAME}->{TRIGGER.NAME}已恢复!
  4. // 消息
  5. 监控ID:{ITEM.ID}
  6. 告警主机:{HOST.NAME}
  7. 告警主机:{HOST.IP}
  8. 告警时间:{EVENT.DATE} {EVENT.TIME}
  9. 告警等级:{TRIGGER.SEVERITY}
  10. 告警信息: {TRIGGER.NAME}
  11. 告警项目:{TRIGGER.KEY}
  12. 问题详情:{ITEM.NAME}:{ITEM.VALUE}
  13. 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
  14. 事件ID:{EVENT.ID}
复制代码

设置用户报警媒介

在管理\用户\报警媒介
如果有多个收件人,用,分割,我在python中做了定义

设置动作

要想要脚本触发问题后执行还需要设置


脚本实现

涉及到两个脚本
Shell脚本/usr/lib/zabbix/alertscripts/sedmail.zabbix.sh
主要是用于实现连接Python脚本,测试、删除图片
创建/usr/lib/zabbix/alertscripts/graph
Python脚本
主要是实现Zabbix中图片的下载、邮件发送
Shell脚本

新版本的Zabbix6.0貌似不支持直接执行Python脚本,为此我使用一个shell脚本作为中转,且可实现简单的测试、删除图片文件。

/usr/lib/zabbix/alertscripts/sedmail.zabbix.sh
  1. #!/bin/bash
  2. cd `dirname $0`
  3. echo "{ALERT.SENDTO} = $1" > debug.txt
  4. echo "{ALERT.SUBJECT} = $2" >> debug.txt
  5. echo "{ALERT.MESSAGE} = $3" >> debug.txt
  6. python3 sedmail.zabbix.py "$1" "$2" "$3" >> debug.txt
  7. echo "shell success" >> debug.txt
  8. find graph -type f -name "*.png" | xargs rm
复制代码
Python脚本

主要是实现Zabbix中图片的下载、邮件发送,本Python脚本使用Python3环境,如果你需
脚本过程


  • 解析传递过来的主题{ALERT.SENDTO}、主题{ALERT.SUBJECT}、消息{ALERT.MESSAGE}消息中的监控ID:后的数字,即itemid,此项极为重要
  1. itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)
  2. # 如果你改了消息模版记得修改一下search匹配规则
复制代码

  • 登录Zabbix:使用Post登录http://zabbix:8080/index.php
  1. "name":user, # 用户
  2. "password":password, # 密码
  3. "autologin":"1", # 30天内自动登录
  4. "enter":"登录", # 请注意这个对应你语言,如果是英文为login on,可以抓包看看
复制代码


  • 故障的统计图下载,对应着先前的itemid参数,可以使用get请求http://zabbix:8080/chart.php后带的参数
  1. "from" :"now-30m",
  2. "to" : "now",
  3. "itemids[0]" : itemid,# 请注意,Zabbix6.0中是itemid[0],在更老的4.0\5.0使用的itemid
  4. "width" : "300",
  5. #对应的url,以itemid[0]=79672为例
  6. http://zabbix:8080/chart.php?from=now-30m&to=now&itemids%5B0%5D=79672&width=300
复制代码
注意需要在登录的前提下,并且login的headers消息头一致,不然对提示错误
文件会保存在graph_path='/usr/lib/zabbix/alertscripts/graph'如果没有此文件夹需要创建
完整脚本

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

可以直接使用报警媒介的测试功能,对应的传输主题{ALERT.SENDTO}、主题{ALERT.SUBJECT}、消息{ALERT.MESSAGE}消息



来源:https://www.cnblogs.com/alittlemc/p/17984208
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具