一个系统运维的打怪升级之路

Zabbix + Python/Bash脚本实现使用企业微信发送监控报警

2019-03-27
316次查阅
2019/6/14

企业微信注册地址:https://work.weixin.qq.com/
微信API文档地址:https://work.weixin.qq.com/api/doc#90000/90003/90487

1、再企业微信后台上先自建一个应用“ZABBIX报警”,获取AgentIdSecret

ZABBIX报警

再点击“我的企业”获取企业ID。

2、再zabbix服务器安装python3运行环境:

# 让python支持https
yum install openssl-devel -y

# 安装python3
wget https://www.python.org/ftp/python/3.5.7/Python-3.5.7.tgz
tar zxvf Python-3.5.7.tgz
./configure
make && make install

# 安装 requests 库
pip3 install requests

3、python报警脚本

把报警脚本放到 zabbix_server 相应的目录下,文件名为:wechat.py (需加可执行权限),报警脚本代码如下(替换下面的 'xxxxx' 部分) :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import json
import sys
import os
import time


# 企业号及应用相关信息
CORP_ID = 'wwe12bxxxxxxxxxxx'
CORP_SECRET = 'tgICJlyH2-IbxxxxxxxxxxxxxxxMQNGUx4zg'
AGENT_ID = 1xxxx02

# access_token 请求地址
ACCESS_TOKEN_REQUEST_URL = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'

# 发送应用消息请求地址
SEND_MESSAGES_REQUEST_URL = 'https://qyapi.weixin.qq.com/cgi-bin/message/send'

# 存储 access_token 文件
ACCESS_TOKEN_FILE = 'access_token.txt'


# 获取 access_token,并写入文件
def get_access_token():
    get_token_url = '{}?corpid={}&corpsecret={}'.format(ACCESS_TOKEN_REQUEST_URL,
                                                        CORP_ID,
                                                        CORP_SECRET)
    r = requests.get(get_token_url)
    r = r.json()
    access_token = r['access_token']
    with open(ACCESS_TOKEN_FILE, 'w') as f:
        f.write(access_token)
    return access_token


# 从文件获取 access_token
def get_access_token_from_file():
    if os.path.exists(ACCESS_TOKEN_FILE):
        with open(ACCESS_TOKEN_FILE, 'r') as f:
            access_token = f.read()
    else:
        access_token = get_access_token()
    return access_token


# 发送应用消息
def main():
    access_token = get_access_token_from_file()
    i = 0
    while i < 3:
        try:
            #message = sys.argv[3]
            message = '来自python的测试消息'
            send_message_url = '{}?access_token={}'.format(SEND_MESSAGES_REQUEST_URL,
                                                           access_token)
            message_params = {"touser": "@all",
                              "msgtype": "text",
                              "agentid": AGENT_ID,
                              "text": {"content": message},
                              "safe": 0
                              }
            r = requests.post(send_message_url, json=message_params, timeout=5)
            r = r.json()
            if r['errmsg'] == 'ok':
                break
            else:
                access_token = get_access_token()
        except Exception as e:
            print(e)
        i += 1
        time.sleep(2)


if __name__ == '__main__':
    main()

附一个bash版本的脚本、功能相同:

#!/usr/bin/env bash
# create by sunkai/1987.name
# Zabbix 企业微信报警脚本
# 需要安装 jq 命令
# yum install jq   /  apt-get install jq

#set -x

# 企业号及应用相关信息
CORP_ID='wwexxxxxxxxxxxxx7eeb'
CORP_SECRET='tgICJlxxxxxxxxxxxxxxxxxxQNGUx4zg'
AGENT_ID=1xxxx02

# access_token 请求地址
ACCESS_TOKEN_URL="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${CORP_ID}&corpsecret=${CORP_SECRET}"

# 发送应用消息请求地址
SEND_MESSAGES_REQUEST_URL='https://qyapi.weixin.qq.com/cgi-bin/message/send'

# 存储 access_token 文件
ACCESS_TOKEN_FILE='access_token.txt'

# 命令路径
CURL='/usr/bin/curl'
JQ='/usr/bin/jq'

# 获取 access_token,并写入文件
get_access_token()
{
    access_token=$($CURL -s -G $ACCESS_TOKEN_URL | $JQ '.access_token' | tr -d \")
    echo $access_token > $ACCESS_TOKEN_FILE
}

# 在文件中获取 access_token
get_access_token_from_file()
{
    if [ -e $ACCESS_TOKEN_FILE ]; then
        access_token=$(cat $ACCESS_TOKEN_FILE)
    else
        get_access_token
    fi
}


message=$3
message_params="{\"touser\":\"@all\",\"msgtype\":\"text\",\"agentid\":$agent_id,\"text\":{\"content\":\"$message\"},\"safe\":0}"


# 发送应用消息
main()
{
    get_access_token_from_file
    for (( i=1; i<3; i++ )); do
        send_message_url="${SEND_MESSAGES_REQUEST_URL}?access_token=$access_token"
        $CURL -sS -H "Content-Type:application/json" \
              -X POST --data $message_params $send_message_url &> $$
        errmsg=$($JQ '.errmsg' $$ | tr -d \")
        if [ "$errmsg" = "ok" ]; then
            break
        else
            get_access_token
        fi
        sleep 1
    done
    rm -f $$
}

main

4、配置zabbix报警

点击“管理 -- 报警媒介类型 -- 创建媒体类型”:

创建媒介类型

参数解释如下:

  • {ALTER.SENDTO} 发送给谁,该参数在邮件告警中有作用,但微信告警中没有。
  • {ALTER.SUBJECT} 告警标题,该参数在邮件告警中有作用,但微信告警中没有。
  • {ALTER.MESSAGE} 告警内容,在微信告警中有用 。

点击“配置 -- 动作 -- 创建动作”:

创建动作
操作
恢复操作

操作消息内容:

故障发生:{TRIGGER.NAME}
故障主机:{HOSTNAME1}
IP地址:{HOST.CONN} 
告警时间:{EVENT.DATE}{EVENT.TIME} 
告警等级:{TRIGGER.SEVERITY} 
告警信息:{TRIGGER.NAME} 
告警项目:{TRIGGER.KEY1} 
问题详情:{ITEM.NAME} : {ITEM.VALUE} 
当前状态:{TRIGGER.STATUS} : {ITEM.VALUE1} 
事件ID:{EVENT.ID}

恢复操作消息内容:

故障恢复:{HOSTNAME1} 已恢复!
IP地址:{HOST.CONN} 
告警时间:{EVENT.DATE}{EVENT.TIME} 
告警等级:{TRIGGER.SEVERITY} 
告警信息:{TRIGGER.NAME} 
告警项目:{TRIGGER.KEY1} 
问题详情:{ITEM.NAME} : {ITEM.VALUE} 
当前状态:{TRIGGER.STATUS} : {ITEM.VALUE1} 
事件ID:{EVENT.ID}

参考:https://www.zabbix.com/documentation/4.0/zh/manual/config/notifications/action/operation/macros

点击“管理 -- 用户(报警媒介)-- 添加”:

报警媒介

至此全部配置完毕,测试效果:

报警效果

评论

想说点什么?