写点什么

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

  • 2024-01-25
    福建
  • 本文字数:3753 字

    阅读完需:约 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


{ALERT.SENDTO} //发件人(对应着用户\报警媒介中配置的发件人){ALERT.SUBJECT} //主题(对应着主题模版){ALERT.MESSAGE} //消息内容(对应着消息模版)
复制代码


发件人



主题\消息内容



报警媒介消息模版


在消息模版中,添加问题发生


// 问题发生// 主题发生故障:服务器:{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}
复制代码


添加问题恢复


//问题恢复// 主题问题恢复:服务器:{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}
复制代码



设置用户报警媒介


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



设置动作


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




脚本实现


涉及到两个脚本


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


Shell 脚本


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



/usr/lib/zabbix/alertscripts/sedmail.zabbix.sh


#!/bin/bashcd `dirname $0`echo "{ALERT.SENDTO} = $1" > debug.txtecho "{ALERT.SUBJECT} = $2" >> debug.txtecho "{ALERT.MESSAGE} = $3" >> debug.txtpython3 sedmail.zabbix.py "$1" "$2" "$3" >> debug.txtecho "shell success" >> debug.txtfind graph -type f -name "*.png" | xargs rm
复制代码


Python 脚本


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


脚本过程


  1. 解析传递过来的主题{ALERT.SENDTO}主题{ALERT.SUBJECT}消息{ALERT.MESSAGE}消息中的监控ID:后的数字,即 itemid,此项极为重要


itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)# 如果你改了消息模版记得修改一下search匹配规则
复制代码


  1. 登录 Zabbix:使用 Post 登录 http://zabbix:8080/index.php


 "name":user, # 用户 "password":password, # 密码 "autologin":"1", # 30天内自动登录 "enter":"登录", # 请注意这个对应你语言,如果是英文为login on,可以抓包看看
复制代码



  1. 故障的统计图下载,对应着先前的itemid参数,可以使用 get 请求http://zabbix:8080/chart.php后带的参数


 "from" :"now-30m", "to" : "now", "itemids[0]" : itemid,# 请注意,Zabbix6.0中是itemid[0],在更老的4.0\5.0使用的itemid "width" : "300", #对应的url,以itemid[0]=79672为例 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


#!/usr/bin/python3#coding=utf-8from email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImageimport smtplib,sys,os,time,re,requests,loggingfrom smtplib import SMTP
user='Admin' #定义zabbix用户名password='password' #定义zabbix用户密码graph_path='/usr/lib/zabbix/alertscripts/graph' #定义图片存储路径graph_url='http://127.0.0.1:8080/chart.php' #定义图表的urlloginurl="http://127.0.0.1:8080/index.php" #定义登录的urlhost='127.0.0.1'to_email=sys.argv[1].split(',') #传入的第一个参数为收件人邮箱subject=sys.argv[2] #传入的第二个参数为邮件主题subject=subject.encode('utf-8').decode('utf-8')smtp_host = 'smtp.xxx.net' #定义smtp主机地址from_email = 'alittlemc@xxx.com' #定义发件人地址mail_pass = 'xxx' #发件人邮箱校验码\密码
def get_itemid(): #获取报警的itemid itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1) return itemid
def get_graph(itemid): #获取报警的图表并保存 session=requests.Session() #创建一个session会话 try: loginheaders={ "Host":host, "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" } #定义请求消息头
payload = { "name":user, "password":password, "autologin":"1", "enter":"登录", } #定义传入的data login=session.post(url=loginurl,headers=loginheaders,data=payload) # print(login.text) #进行登录 graph_params={ "from" :"now-30m", "to" : "now", "itemids[0]" : itemid, "width" : "300", } # print(itemid) # http://zabbix:8080/chart.php?from=now-1m&to=now&itemids%5B0%5D=79672
#定义获取图片的参数 graph_req=session.get(url=graph_url,params=graph_params,headers=loginheaders) #发送get请求获取图片数据 time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime()) graph_name='baojing_'+time_tag+'.png' #用报警时间来作为图片名进行保存 graph_name = os.path.join(graph_path, graph_name) #使用绝对路径保存图片 with open(graph_name,'wb') as f: f.write(graph_req.content) #将获取到的图片数据写入到文件中去 return graph_name
except Exception as e: # print(e) return Falsedef text_to_html(text): #将邮件内容text字段转换成HTML格式 d=text.splitlines() #将邮件内容以每行作为一个列表元素存储在列表中 html_text='' for i in d: i='' + i + '<br>' html_text+=i + '\n' #为列表的每个元素后加上html的换行标签 return html_text
def send_mail(graph_name): #将html和图片封装成邮件进行发送 msg = MIMEMultipart('related') #创建内嵌资源的实例
with open(graph_name,'rb') as f: #读取图片文件 graph=MIMEImage(f.read()) #读取图片赋值一个图片对象 graph.add_header('Content-ID','imgid1') #为图片对象添加标题字段和值 text=text_to_html(sys.argv[3]) html=""" <html> <body> %s <br><img src="cid:imgid1"> </body> </html> """ % text html=MIMEText(html,'html','utf-8') #创建HTML格式的邮件体 msg.attach(html) #使用attach方法将HTML添加到msg实例中 msg.attach(graph) #使用attach方法将图片添加到msg实例中 msg['Subject'] = subject msg['From'] = from_email try: server=SMTP(smtp_host,"587") #创建一个smtp对象 server.starttls() #启用安全传输模式 server.login(from_email,mail_pass) #邮箱账号登录 for x in to_email: server.sendmail(from_email,x,msg.as_string()) #发送邮件 server.quit() #断开smtp连接 except smtplib.SMTPException as a: print(a)
def run(): itemid=get_itemid() graph_name=get_graph(itemid) send_mail(graph_name)
if __name__ =='__main__': run() print('success',sys.argv[1],sys.argv[2],sys.argv[3])
复制代码


测试


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




文章转载自:alittlemc

原文链接:https://www.cnblogs.com/alittlemc/p/17984208

体验地址:http://www.jnpfsoft.com/?from=001

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
(保姆级)服务器-Zabbix6.0使用Python脚本实现带图片的邮箱的报警_Python_不在线第一只蜗牛_InfoQ写作社区