Sending email and wechat alarm with pictures in zabbix

Sending email and wechat alarm with pictures in zabbix

1. python implementation sends alarm mails with pictures in zabbix version 4.2

Generally, the alarms we receive are all words, which take the message content in the action as the text parameter and send it to the script, and then the email or wechat receive it. Usually, we can only see the current value and can't get the operation curve of the monitoring item on the historical day intuitively. Therefore, according to this demand, we use python to write a script to upgrade the email alarm and wechat alarm respectively Level, the alarm content has been added with the historical trend chart of the day. The Kung Fu is not inferior to the intentional people. It has been successfully unlocked and successfully practiced. Therefore, it is shared for your reference. In addition, thank you very much for the help of big brother and Wang erjiyou in script writing

1.1 implementation ideas

  • First, the first line of the alarm message should have an itemid. This is the premise. According to the parameters passed in the message, use regular matching to the itemid

  • Use script to create a zabbix session to get pictures according to itemid, and save the pictures to local

  • Convert the text field of the incoming parameter information to HTML format, and then send the information and pictures in HTML format as e-mail

1.2 preparation environment

  • The script uses python script and runs in python 2.7.5

  • Dependency Library:

    requests

1.3 script implementation

[root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/  #Enter the default script path of zabbix
[root@5804703917ad alertscripts]# mkdir graph #Create a folder for pictures
[root@5804703917ad alertscripts]# chmod 777 graph #Give permissions to folders
[root@5804703917ad alertscripts]# vim zabbix_email_pic.py #Write implementation script
#!/usr/bin/python
#coding=utf-8
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import smtplib,sys,os,time,re,requests
from smtplib import SMTP
​
user='Admin'    #Define zabbix user name
password='zabbix'    #Define zabbix user password
graph_path='/usr/lib/zabbix/alertscripts/graph'   #Define picture storage path
graph_url='http://192.168.73.133/chart.php 'ා define the url of the chart
loginurl="http://192.168.73.133/index.php "ා define the login url
host='192.168.73.133'
to_email=sys.argv[1]    #The first parameter passed in is the recipient mailbox
subject=sys.argv[2]  #The second parameter passed in is the message subject
subject=subject.decode('utf-8')
smtp_host = 'smtp.163.com'  #Define smtp host address
from_email = 'xxxx@163.com.cn'     #Define sender address
mail_pass = 'xxx'       #Sender email verification code
​
def get_itemid():
    #Get itemid of alarm
    itemid=re.search(r'Monitor ID:(\d+)',sys.argv[3]).group(1)
    return itemid
​
def get_graph(itemid):
    #Get the chart of the alarm and save it
    session=requests.Session()   #Create a session
    try:
        loginheaders={
        "Host":host,
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
        }
        #Define request headers
​
        payload = {
        "name":user,
        "password":password,
        "autologin":"1",
        "enter":"Sign in",
        }
        #Define incoming data
        login=session.post(url=loginurl,headers=loginheaders,data=payload)
        #Login
        graph_params={
            "from" :"now-10m",
            "to" : "now",
            "itemids" : itemid,
            "width" : "400",
        }
        #Define parameters for getting pictures
        graph_req=session.get(url=graph_url,params=graph_params)
        #Send get request to get picture data
        time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
        graph_name='baojing_'+time_tag+'.png'
        #Save with alarm time as picture name
        graph_name = os.path.join(graph_path, graph_name)
        #Use absolute path to save picture
        with open(graph_name,'wb') as f:
            f.write(graph_req.content)
            #Write the acquired picture data to the file
        return graph_name
​
    except Exception as e:
        print(e)
        return False
def text_to_html(text):
    #Convert the message content text field to HTML format
    d=text.splitlines()
    #Store the message content in the list as a list element per line
    html_text=''
    for i in d:
        i='' + i + '<br>'
        html_text+=i + '\n'
    #Label each element of the list with a line feed of html
    return html_text
​
def send_mail(graph_name):
    #Encapsulate html and pictures into email for sending
    msg = MIMEMultipart('related')  #Create an instance of an embedded resource
​
    with open(graph_name,'rb') as f:
        #Read picture file
        graph=MIMEImage(f.read())  #Read picture assign a picture object
    graph.add_header('Content-ID','imgid1')  #Add Title fields and values to picture objects
    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')  #Create a message body in HTML format
    msg.attach(html)   #Using the attach method to add HTML to the msg instance
    msg.attach(graph)  #Using the attach method to add a picture to the msg instance
    msg['Subject'] = subject
    msg['From'] = from_email
    try:
        server=SMTP(smtp_host,"587")   #Create an smtp object
        server.starttls()    #Enable secure transfer mode
        server.login(from_email,mail_pass)  #Email account login
        server.sendmail(from_email,to_email,msg.as_string())  #Send mail
        server.quit()   #Disconnect 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 define alarm medium type

  • Open the zabbix monitoring web, select the alarm media type in the management menu, create the media type, select the script, fill in the name of the e-mail with graph script just written zabbix? Email? Pic.py, script parameters, and finally add

  • Open the user in the management, click the user who needs to set the email alarm, then add the alarm media in the alarm media, select the type just defined in the pop-up box, fill in the email address you want to send, and finally add

    1.5 define alarm action

  • Click the action in the configuration menu, create the action, and then fill in according to the picture

operation
Default title Zabbix Alert: Server: {HOSTNAME} failed: {TRIGGER.NAME}!
Monitoring ID:{ITEM.ID}
Alarm host: {HOST.NAME}
Alarm host: {HOST.IP}
Alarm time: {EVENT.DATE} {EVENT.TIME}
Alarm level: {TRIGGER.SEVERITY}
Alarm information: {TRIGGER.NAME}
Warning item: {TRIGGER.KEY}
Question details: {ITEM.NAME}:{ITEM.VALUE}
Current status: {TRIGGER.STATUS}:{ITEM.VALUE}
Event ID:{EVENT.ID}
Recovery operation
Zabbix Alert: Server: {HOST.NAME} occurred: {TRIGGER.NAME} recovered!
Monitoring ID:{ITEM.ID}
Alarm host: {HOST.NAME}
Alarm host: {HOST.IP}
Alarm time: {EVENT.DATE} {EVENT.TIME}
Alarm level: {TRIGGER.SEVERITY}
Alarm information: {TRIGGER.NAME}
Warning item: {TRIGGER.KEY}


1.6 final effect

An alarm test effect can be triggered manually

2. Python implements sending wechat alarm with pictures in 4.2 zabbix

2.1 implementation ideas

  • First, create the enterprise public number to get agentId, secret and department id.

  • Then get the itemid according to the alarm information, and use regular matching to the itemid

  • Use script to create a zabbix session to get pictures according to itemid, and save the pictures to local

  • Call the enterprise wechat api interface, upload the pictures as temporary materials, return a media ID, call and use the sending message and pictures, and finally use the mpnews message type to push the pictures and alarm content to wechat

    2.2 preparation environment

  • The script uses python script and runs in python 2.7.5

  • Dependency library pre installation:

    requests

2.3 create enterprise public number to get agentid, secret

For this part, you can see the detailed description of the previous article without figure

2.4 script implementation

[root@5804703917ad zabbix]# cd /usr/lib/zabbix/alertscripts/  #Enter the default script path of zabbix
[root@5804703917ad alertscripts]# mkdir graph #Create a folder for pictures
[root@5804703917ad alertscripts]# chmod 777 graph #Give permissions to folders
[root@5804703917ad alertscripts]# vim zabbix_weixin_pic.py #Write implementation script
#!/usr/bin/python
#coding=utf-8
_author__ = 'zhangdongdong'
import requests, json
import urllib3
import smtplib,sys,os,time,re,requests
from email.mime.image import MIMEImage
if sys.getdefaultencoding() != 'utf-8':
    reload(sys)
    sys.setdefaultencoding('utf-8')
urllib3.disable_warnings()
class WechatImage(object): # According to the enterprise wechat api interface document, define a class and use the mpnews type, 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): # Get 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): # Upload the temporary material picture, and then return to 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): #Define parameter dictionary in mpnews type
        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): #Define data of type mpnews to be sent
        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,                                 # User account in Enterprise
                "agentid": agentid,                             # Application id in enterprise number
                "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.text
def text_to_html(text): #Convert the message content text field to HTML format
    d=text.splitlines()
    #Store the message content in the list as a list element per line
    html_text=''
    for i in d:
        i='' + i + '<br>'
        html_text+=i + '\n'
    #Label each element of the list with a line feed of html
    return html_text
def get_itemid():
    #Get itemid of alarm
    itemid=re.search(r'Monitor ID:(\d+)',sys.argv[3]).group(1)
    return itemid
def get_graph(itemid):
    #Get the chart of the alarm and save it
    session=requests.Session()   #Create a session
    try:
        loginheaders={
        "Host":host,
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
        }
        #Define request headers
​
        payload = {
        "name":user,
        "password":password,
        "autologin":"1",
        "enter":"Sign in",
        }
        #Define incoming data
        login=session.post(url=loginurl,headers=loginheaders,data=payload)
        #Login
        graph_params={
            "from" :"now-10m",
            "to" : "now",
            "itemids" : itemid,
            "width" : "290", #The height and width of the picture can be adjusted by yourself
            "height" : "40",
        }
        #Define parameters for getting pictures
        graph_req=session.get(url=graph_url,params=graph_params)
        #Send get request to get picture data
        time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
        graph_name='baojing_'+time_tag+'.png'
        #Save with alarm time as picture name
        graph_name = os.path.join(graph_path, graph_name)
        #Use absolute path to save picture
        with open(graph_name,'wb') as f:
            f.write(graph_req.content)
            #Write the acquired picture data to the file
        return graph_name
    except Exception as e:
        print(e)
        return False
if __name__ == '__main__':
    user='Admin'    #Define zabbix user name
    password='zabbix'    #Def i ne zabbix user ID
    graph_path='/usr/lib/zabbix/alertscripts/graph/'   #Define the image storage path. Images need to be cleaned regularly
    graph_url='http://192.168.73.133/chart.php 'ා define the url of the chart
    loginurl="http://192.168.73.133/index.php "ා define the login 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)

  • Open the zabbix monitoring web, select the alarm media type in the management menu, create the media type, select the script, fill in the name of the wechat map script just written zabbix  Weixin  pic.py, script parameters, and finally add

  • Open the user in the management, click the user who needs to set the email alarm, then add the alarm media in the alarm media, select the type just defined in the pop-up box, fill in the Department id created in the enterprise wechat, and finally add

    2.6 define alarm action

    • Click the action in the configuration menu, create the action, and then fill in according to the picture
    operation
    Default title Zabbix Alert: Server: {HOSTNAME} failed: {TRIGGER.NAME}!
    Monitoring ID:{ITEM.ID}
    Alarm host: {HOST.NAME}
    Alarm host: {HOST.IP}
    Alarm time: {EVENT.DATE} {EVENT.TIME}
    Alarm level: {TRIGGER.SEVERITY}
    Alarm information: {TRIGGER.NAME}
    Warning item: {TRIGGER.KEY}
    Question details: {ITEM.NAME}:{ITEM.VALUE}
    Current status: {TRIGGER.STATUS}:{ITEM.VALUE}
    Event ID:{EVENT.ID}
    Recovery operation
    Zabbix Alert: Server: {HOST.NAME} occurred: {TRIGGER.NAME} recovered!
    Monitoring ID:{ITEM.ID}
    Alarm host: {HOST.NAME}
    Alarm host: {HOST.IP}
    Alarm time: {EVENT.DATE} {EVENT.TIME}
    Alarm level: {TRIGGER.SEVERITY}
    Alarm information: {TRIGGER.NAME}
    Warning item: {TRIGGER.KEY}
    Question details: {ITEM.NAME}:{ITEM.VALUE}
    Current status: {TRIGGER.STATUS}:{ITEM.VALUE}
    Event ID:{EVENT.ID}
    


2.7 test effect

You can manually trigger an alarm test effect, and the phone will receive an alarm with a picture. Click the page after the message to see the historical picture

Tags: Operation & Maintenance Zabbix Session Python PHP

Posted on Wed, 12 Feb 2020 21:58:55 -0500 by vexx