运维攻城师程序员

十、企业微信发送Zabbix报警图文信息

2017-08-27  本文已影响220人  armo要多读书

概要

入职之后,邮箱正常的业务邮件没几个,倒是每天被几百封Zabbix的报警邮件充斥,不仅杂乱无章,而且也不是那么愿意去看每封邮件的内容,刚好公司在用企业微信,所以打算把Zabbix的报警信息迁移到企业微信上去,大致思路如下:

实现过程

#!/usr/local/bin/python
# -*- coding:utf-8 -*-
# name image.py
from selenium import webdriver
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def get_item_graph(itemid,flag,eventid):
    temp_name = "/tmp/"+eventid+".png"
        #save_screenshot仅能保存png格式图片,所以文件名定义需要以png结尾
    driver = webdriver.PhantomJS("/usr/local/zabbix-agent-ops/phantomjs-2.1.1/bin/phantomjs",service_log_path=os.path.devnull)
        #使用PhantomJS可以模拟浏览器进行访问
    driver.get("http://127.0.0.1/zabbix/")
    driver.set_window_size(640,480)
    driver.find_element_by_id("name").send_keys("armo")
    driver.find_element_by_id("password").send_keys("123456")
    driver.find_element_by_id("enter").click()
        #模拟访问url,在对应的元素element处输入用户名密码后click登陆
    if flag:
        driver.get("http://127.0.0.1/zabbix/history.php?action=showgraph&fullscreen=1&itemids[]="+itemid)
    else:
        driver.get("http://127.0.0.1/zabbix/history.php?action=showvalues&fullscreen=1&itemids[]="+itemid)
        #flag如果是1,则对应Item有对应的graph获取;如果是0,则获取最新一段时间的值
        driver.save_screenshot(temp_name)
        #将网页内容保存为png图片
    driver.close()
    driver.quit()

if __name__ == "__main__":
    if len(sys.argv) > 1:
        itemid = sys.argv[1]           #脚本传递的第一个参数 Item ID
        flag = sys.argv[2]             #脚本传递的第二个参数 Flag,从zabbix数据库item和graph的对应表查询item是否具有对应的graph,如果有则传递1到脚本,无传递0
        eventid = sys.argv[3]          #脚本传递的第三个参数 告警信息的Event ID,用来命名png图片
    get_item_graph(itemid,flag,eventid)
#!/usr/local/bin/python
#_*_coding:utf-8 _*_
import requests,sys,json
import urllib3
urllib3.disable_warnings()
reload(sys)
sys.setdefaultencoding('utf-8')

#获取Token
def GetToken(Corpid,Secret):
    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

#将获取到的趋势图,上传至企业微信临时素材,返回MediaId发送图文消息是使用
def GetImageUrl(Token,Path):
    Url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image" % Token
    data = {
        "media": open(Path,'r')
        }
    r = requests.post(url=Url,files=data)
    dict = r.json()
    return dict['media_id']

#卡片消息    
def SendCardMessage(Token,User,Agentid,Subject,Content):
    Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % Token
    Data = {
        "touser": User,                                 # 企业号中的用户帐号
        "msgtype": "textcard",                          # 消息类型
        "agentid": Agentid,                             # 企业号中的应用id
        "textcard": {
            "title": Subject,
            "description": Content,
            "url": "http://127.0.0.1/zabbix/",          #点击详情后打开的页面
            "btntxt": "详情"
        },
    "safe": "0"
    }
    r = requests.post(url=Url,data=json.dumps(Data),verify=False)
    return r.text

#图文消息
def SendnewsMessage(Token,User,Agentid,Subject,Content,Image,Itemid):
    Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % Token
    UUrl = "http://127.0.0.1/zabbix/history.php?action=showgraph&fullscreen=1&itemids[]="+Itemid
    Data = {
            "touser": User,                                 # 企业号中的用户帐号
            "msgtype": "mpnews",                            # 消息类型
            "agentid": Agentid,                             # 企业号中的应用id
            "mpnews": {
                    "articles": [
                    {
                            "title": Subject,
                            "thumb_media_id": Image,
                            "content": Content,
                            "content_source_url": UUrl,      #点击阅读原文后,打开趋势图大图,第一次需要登录
                            "digest": Content
                    }
                    ]
            },
            "safe": "0"
    }
    headers = {'content-type': 'application/json'}
    data = json.dumps(Data,ensure_ascii=False).encode('utf-8')
    r = requests.post(url=Url,headers=headers,data=data)
    return r.text

if __name__ == '__main__':
    User = sys.argv[1]                                                            
    Subject = sys.argv[2]                                                       
    Content = sys.argv[3]                                                       
    Path = sys.argv[4]                                                    
    Itemid = sys.argv[5]
    Corpid = "xxxxxxxxxxx"                                    # CorpID是企业号的标识
    Secret = "xxxxxxxxx"                                      # Secret是管理组凭证密钥
    Agentid = "100000x"                                       # 应用ID
    Token = GetToken(Corpid, Secret)
    Image = GetImageUrl(Token,Path) 
    SendnewsMessage(Token,User,Agentid,Subject,Content,Image,Itemid)
#!/bin/bash
# name:wechat.sh

send_to=$1
subject=$2
message=$3

#获取itemid,eventid,PROBLEM或OK状态以命名PNG趋势图
#这块几个grep的格式需要特别注意,需要和zabbix发送过来的message格式相同
itemid=`echo $message | egrep -o "item ID: [0-9]*"| awk '{print $NF}'`
eventid=`echo $message | egrep -o "event ID: [0-9]*"| awk '{print $NF}'`
stat=`echo $message | egrep -o "Trigger status: PROBLEM|Trigger status: OK"| awk '{print $NF}'`
image=/tmp/$eventid"_"$stat".png"
#获取graphid和flag
graphid=`/bin/cat /tmp/zabbix.txt | awk '{ if($2=="'"$itemid"'"){print $1}}'`
if [ ! $graphid ]
then
    flag=0
else
    flag=1
fi

#在zabbix自动执行该脚本时,该脚本调用两个PY脚本,不太清楚原因,直接写脚本绝对路径无法执行,使用
解释器后跟脚本绝对路径也无法执行,但是尝试cd到目录后执行确可以,很蛋疼
cd /usr/local/zabbix/share/zabbix/alertscripts/
#使用image.py生成/tmp/$eventid"_"$stat".png图片后传递给wechat.py才有意义
./image.py "$itemid" "$flag" "$image"
./wechat.py "$send_to" "$subject" "$message" "$image" "$itemid"
#log
echo $image >> /tmp/zabbix_event.log
#!/bin/bash
# 定时任务脚本
# 根据生成的PNG检查时段内未处理的问题,并删除已处理的PNG

cat /tmp/zabbix_event.log | awk -F "_" '{print $1}' | sort | uniq -c | awk '{if($1%2==0){print $2}}' > /tmp/zabbix_rm.log
event=`cat /tmp/zabbix_rm.log`
for i in $event
do
    sed -i '/[$i]/d' /tmp/zabbix_event.log
    rm -rf $i*
done

cat /tmp/zabbix_event.log | awk -F "_" '{print $1}' | awk -F "/" '{print $NF}' > /tmp/zabbix_problem.log
#最后生成的/tmp/zabbix_problem.log中,保存了目前所有PROBLEM的EVENT_ID,将此ID通过第二个脚本提供的方式再发发送消息给微信即可。
#将此脚本添加到Crontab任务定时执行

Zabbix配置简述(脚本放置文件夹为zabbix配置参数AlertScriptsPath定义)

调用第三个脚本,wechat.sh 新增用户调用新增的报警媒介 告警动作 恢复动作

效果展示

图文消息
图文消息

点进去之后


点进去之后

点阅读全文,第一次需要登录,之后打开其他面板的阅读全都都不需要输入密码啦

阅读全文
卡片消息

是不是看着很清爽,低等级的告警,点详情后会跳转到zabbix主页面,卡片上一共可以显示八行消息,可以将需要的信息定义在前八行就可以了

卡片消息
上一篇 下一篇

猜你喜欢

热点阅读