在zabbix中實現發送帶有圖片的郵件和微信告警

夫天地者, 萬物之逆旅也;光陰者,百代之過客也。
李白《春夜宴從弟桃花園序》



1 python實如今4.2版本zabbix發送帶有圖片的報警郵件
php

咱們一般收到的報警,都是文字,是把動做中的消息內容當成了正文參數傳給腳本,而後郵件或者微信進行接收,每每只能看到當前值,沒法直觀的獲取到歷史當天該監控項的運行曲線圖,所以根據此需求,使用python編寫腳原本分別對郵件告警和微信告警,進行升級,報警內容中加入了當天的歷史趨勢圖,功夫不負有心人,已成功解鎖,並實踐成功,所以分享出來供你們參考,另外得很是感謝腳本編寫中剛哥大神和王二基友給予的幫助html

1.1 實現思路

  • 首先報警信息裏第一行要有itemid,這是前提,根據信息裏傳入的參數使用正則匹配到itemidpython

  • 使用腳本建立一個zabbix會話,來根據itemid來獲取圖片,並將獲取到的圖片保存到本地web

  • 將傳入的參數信息的text字段轉換成HTML格式,而後將HTML格式的信息和圖片做爲郵件進行發送json

1.2 準備環境

  • 腳本是使用python腳本,運行環境爲python 2.7.5vim

  • 依賴庫:api

    requests安全

1.3 腳本實現

[root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/ #進入zabbix默認的腳本路徑[root@5804703917ad alertscripts]# mkdir graph #建立一個存放圖片的文件夾[root@5804703917ad alertscripts]# chmod 777 graph #給文件夾賦予權限[root@5804703917ad alertscripts]# vim zabbix_email_pic.py #編寫實現腳本#!/usr/bin/python#coding=utf-8from email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImageimport smtplib,sys,os,time,re,requestsfrom smtplib import SMTP
user='Admin' #定義zabbix用戶名password='zabbix' #定義zabbix用戶密碼graph_path='/usr/lib/zabbix/alertscripts/graph' #定義圖片存儲路徑graph_url='http://192.168.73.133/chart.php' #定義圖表的urlloginurl="http://192.168.73.133/index.php" #定義登陸的urlhost='192.168.73.133'to_email=sys.argv[1] #傳入的第一個參數爲收件人郵箱subject=sys.argv[2] #傳入的第二個參數爲郵件主題subject=subject.decode('utf-8')smtp_host = 'smtp.163.com' #定義smtp主機地址from_email = 'xxxx@163.com.cn' #定義發件人地址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":"Sign in", } #定義傳入的data login=session.post(url=loginurl,headers=loginheaders,data=payload) #進行登陸 graph_params={ "from" :"now-10m", "to" : "now", "itemids" : itemid, "width" : "400", } #定義獲取圖片的參數 graph_req=session.get(url=graph_url,params=graph_params) #發送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) #郵箱帳號登陸 server.sendmail(from_email,to_email,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()

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}問題詳情:{ITEM.NAME}:{ITEM.VALUE}當前狀態:{TRIGGER.STATUS}:{ITEM.VALUE}事件ID:{EVENT.ID}



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 腳本實現

[root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/ #進入zabbix默認的腳本路徑[root@5804703917ad alertscripts]# mkdir graph #建立一個存放圖片的文件夾[root@5804703917ad alertscripts]# chmod 777 graph #給文件夾賦予權限[root@5804703917ad alertscripts]# vim zabbix_weixin_pic.py #編寫實現腳本#!/usr/bin/python#coding=utf-8_author__ = 'zhangdongdong'import requests, jsonimport urllib3import smtplib,sys,os,time,re,requestsfrom email.mime.image import MIMEImageif sys.getdefaultencoding() != 'utf-8': reload(sys) sys.setdefaultencoding('utf-8')urllib3.disable_warnings()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
def get_token(self, corpid, secret): # 獲取token url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken" data = {"corpid": corpid, "corpsecret": secret} r = requests.get(url=url, params=data, verify=False) token = r.json()['access_token'] return token
def get_image_url(self, token, path): # 上傳臨時素材圖片,而後返回media_id url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image" % token data = {"media": open(path, 'rb')} r = requests.post(url=url, files=data) dict_data = r.json() return dict_data['media_id'] def get_messages( self,subject,content,path): #定義mpnews類型中的參數字典 data = '' messages = {} body = {} content_html=text_to_html(content) token = self.get_token(corpid, secret) image = self.get_image_url(token, path) content_html += "<br/> <img src='https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s'>" % (token, image) body["title"] = subject body['digest'] = content body['content'] = content_html body['thumb_media_id'] = image data = [] data.append(body) messages['articles'] = data return messages def send_news_message(self, corpid, secret,to_user, agentid,path): #定義發送mpnews類型的數據 token = self.get_token(corpid, secret) messages = self.get_messages( subject, content,path) url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % token data = {"toparty": to_user, # 企業號中的用戶賬號 "agentid": agentid, # 企業號中的應用id "msgtype": "mpnews", "mpnews": messages, "safe": "0"} headers = {'content-type': 'application/json'} data_dict = json.dumps(data, ensure_ascii=False).encode('utf-8') r = requests.post(url=url, headers=headers, data=data_dict) return r.textdef 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_textdef get_itemid(): #獲取報警的itemid itemid=re.search(r'監控ID:(\d+)',sys.argv[3]).group(1) return itemiddef 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":"Sign in", } #定義傳入的data login=session.post(url=loginurl,headers=loginheaders,data=payload) #進行登陸 graph_params={ "from" :"now-10m", "to" : "now", "itemids" : itemid, "width" : "290", #圖片的高寬參數能夠自行調整 "height" : "40", } #定義獲取圖片的參數 graph_req=session.get(url=graph_url,params=graph_params) #發送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 Falseif __name__ == '__main__': user='Admin' #定義zabbix用戶名 password='zabbix' #定義zabbix用戶i密 graph_path='/usr/lib/zabbix/alertscripts/graph/' #定義圖片存儲路徑,圖片須要定時清理 graph_url='http://192.168.73.133/chart.php' #定義圖表的url loginurl="http://192.168.73.133/index.php" #定義登陸的url host='192.168.73.133' itemid=get_itemid() path =get_graph(itemid) to_user = str(sys.argv[1]) subject = str(sys.argv[2]) content = str(sys.argv[3]) corpid= "xxxxx" secret = "xxxxxxx" agentid = "1000002" wechat_img = WechatImage() wechat_img.send_news_message(corpid, secret,to_user, agentid, path)

2.5 定義報警媒介類型

  • 打開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 測試效果

能夠手動觸發一個報警測試效果,手機上就能夠收到帶圖的報警了,點擊消息以後的頁面也能夠看到歷史的圖片


本文分享自微信公衆號 - 運維開發故事(mygsdcsf)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索