zabbix小结(十八)zabbix 微信告警

2019年2月18日 发表评论 阅读评论

微信告警早已不是什么新鲜功能,早在分早之前就已可通过公众信进行实现,由于公众号针对的是所有关注的用户推送信息,所以信息私密性不强,所以后来的微信消息基本都是通过企业微信实现的,这点和dingding是类似的,其可以通过一个API 通过post请求发给单个人、分组或者所有人,比较灵活。本篇就简单记录下实现过程。

一、注册企业微信

打开以下链接注册微信企业号:https://work.weixin.qq.com/wework_admin/register_wx?from=myhome 

reg-qywechat

个人信息页面会让输入手机号进行验证。超过200人以上的,需要营业执行进行注册。注册成功会要求下载企业微信,并通过页面链接可以进入管理后台并创建应用。

创建应用

创建页面如下:

zabbix-qy-wechat

二、微信消息发送

微信消息发送第两步,第一步是获取token 信息,第二步是post消息并加上token信息发给api server 。具体如下:

https://work.weixin.qq.com/api/doc#90000/90135/91039  (获取access_token)
https://work.weixin.qq.com/api/doc#90000/90135/90236 (发送应用消息)

请求方式: GET HTTPS
请求地址: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
注:此处标注大写的单词ID和SECRET,为需要替换的变量,根据实际获取值更新。其它接口也采用相同的标注,不再说明。

参数说明:

参数 必须 说明
corpid 企业ID,获取方式参考:术语说明-corpid
corpsecret 应用的凭证密钥,获取方式参考:术语说明-secret

其中corpid 可以在管理后台---- 我的企业,页面的最底部获取。corpsecret 可以从应用程序详细页面找到:

corpsecert

通过该get方式获取acess_token以后,可以通过如下方式送给相应的人:

post-qywechat-message

上面touser、toparty、totag必须要有一个在。

三、脚本调用

这里以python为例吧(其他语言也是一样的):

#!/usr/bin/env python
# encoding: utf-8
import urllib,urllib2
import json
import sys
#import simplejson
reload(sys)
sys.setdefaultencoding('utf8')
def gettoken(corpid,corpsecret):
    gettoken_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + corpid + '&corpsecret=' + corpsecret
    print  gettoken_url
    try:
        token_file = urllib2.urlopen(gettoken_url)
    except urllib2.HTTPError as e:
        print e.code
        print e.read().decode("utf8")
        sys.exit()
    token_data = token_file.read().decode('utf-8')
    token_json = json.loads(token_data)
    token_json.keys()
    token = token_json['access_token']
    return token
def senddata(access_token,user,subject,content):
    send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
    send_values = {
        "touser":user,    #企业号中的用户帐号,在zabbix用户Media中配置,如果配置不正常,将按部门发送。
        "toparty":"",     #企业号中的部门id。
        "msgtype":"text", #消息类型。
        "agentid":"1000002",    #企业号中的应用id。
        "text":{
            "content":subject + '\n' + content
           },
        "safe":"0"
        }
    send_data = json.dumps(send_values, ensure_ascii=False)
#    send_data = simplejson.dumps(send_values, ensure_ascii=False).encode('utf-8')
    send_request = urllib2.Request(send_url, send_data)
    response = json.loads(urllib2.urlopen(send_request).read())
    print str(response)
if __name__ == '__main__':
    user = str(sys.argv[1])     #zabbix传过来的第一个参数
    subject = str(sys.argv[2])  #zabbix传过来的第二个参数
    content = str(sys.argv[3])  #zabbix传过来的第三个参数
    corpid =  'ww9cd'   #CorpID是企业号的标识
    corpsecret = 'N5iLqi8h'  #corpsecretSecret是管理组凭证密钥
    try:
        accesstoken = gettoken(corpid,corpsecret)
        senddata(accesstoken,user,subject,content)
    except Exception as e:
        print 'Exception: ', e

不过这个每次都会去取一次access_token,因为access_token的有效期是7200秒,实际上没必要每次都重新去取,所以也可以优化下该调用方式,将token值存在一个地方,发现调用不成功时,再重新获取token的方式进行操作,更改后的脚本如下:

import requests
import json
import sys
# 企业号及应用相关信息
corp_id = 'xxxxxxx'
corp_secret = 'xxxxxxx'
agent_id = xxxxxx
# 存放access_token文件路径
file_path = '/tmp/access_token.log'
def get_access_token_from_file():
    try:
        f = open(file_path,'r+')
        this_access_token = f.read()
        print('get success %s' % this_access_token)
        f.close()
        return this_access_token
    except Exception as e:
        print(e)
# 获取token函数,文本里记录的token失效时调用
def get_access_token():
    get_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' % (corp_id, corp_secret)
    print(get_token_url)
    r = requests.get(get_token_url)
    request_json = r.json()
    this_access_token = request_json['access_token']
    print(this_access_token)
    r.close()
    # 把获取到的access_token写入文本
    try:
        f = open(file_path,'w+')
        f.write(this_access_token)
        f.close()
    except Exception as e:
        print(e)
    # 返回获取到的access_token值
    return this_access_token
# snedMessage
# 死循环,直到消息成功发送
flag = True
while(flag):
    # 从文本获取access_token
    access_token = get_access_token_from_file()
    try:
        to_user = '@all'
        message = sys.argv[3]
        send_message_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % access_token
        print(send_message_url)
        message_params = {
                            "touser":to_user,
                            "msgtype":"text",
                            "agentid":agent_id,
                            "text":{
                                "content" : message
                            },
                            "safe":0
                        }
        r = requests.post(send_message_url, data=json.dumps(message_params))
        print('post success %s ' % r.text)
        # 判断是否发送成功,如不成功则跑出异常,让其执行异常处理里的函数
        request_json = r.json()
        errmsg = request_json['errmsg']
        if errmsg != 'ok': raise
        # 消息成功发送,停止死循环
        flag = False
    except Exception as e:
        print(e)
        access_token = get_access_token()

可以在不和zabbix结合前,先调用该脚本发几条消息测试下。这里以touser为例,如果要发送给所有人是@all ,只发送给某人,是该用户的账户名该,该名称在通信录里点开该人的详细信息里有,一般都是字母或字母加数字。

四、zabbix部署

连接zabbix server主机,找到server配置文件的AlertScriptsPath行,进入告警脚本存放目录,将上面的脚本存放在该目录 。登陆zabbix web界面,增加告警媒介,如下:

qywechat-media

在配置---action里在操作,如下:

qywechat-sendto

用户和组选择目前帐户里存在的。如果不存在,新增就OK了。




本站的发展离不开您的资助,金额随意,欢迎来赏!

You can donate through PayPal.
My paypal id: itybku@139.com
Paypal page: https://www.paypal.me/361way

分类: 开源软件 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.