美文网首页
ZABBIX之旅(5.0版以上)

ZABBIX之旅(5.0版以上)

作者: 刘_小_二 | 来源:发表于2021-03-31 12:05 被阅读0次

    【背景说明】运维系统使用时Zabbix工具,需添加微信公众号、微信企业号进行异常数据提醒的消息推送功能。

    【系统环境】

    Linux系统、Python3、Pip
    

    【应用工具】

    Mac Pro ---- FinalShell
    

    一、企业微信信息推送

    为什么选用微信企业号?

        因为微信企业号需要先在企业通信录新建该员工,该员工才能关注该企业号,这样就能实现告警信息的私密性。如果使用公众号,则只要所有关注了该公众号的人都能收到告警消息,容易造成信息泄露。而且员工数少于200人的企业号是不用钱的,也没有任何申请限制。
    

    实现步骤

    1. 注册微信企业号

       打开以下链接注册微信企业号:https://work.weixin.qq.com/wework_admin/register_wx?from=myhome选择没有营业执照继续注册(限员工数200人以下),如下图所示,如果是正规大企业使用,请正常注册。
      
    image

    填上企业名称即可注册完成,后面还需要指定企业号管理员,按步骤绑定好管理员微信即可。

    1. 在企业号上创建告警应用

    该告警应用的角色如下:Zabbix_server ---------> 告警应用 --------> 运维人员微信号

    在企业号上创建一个应用,如下图所示:

    image

    填好相关资料,应用即可创建完成,如上图本文创建的应用叫Zabbix告警

    企业号上的重要信息

    这里重点提一下企业号里几点重要的信息,等会在脚本中会用到

    • corpid

      企业号的ID号,获得地方如下图所示:

      image

      应用的安全码和agentid,获得地方如下图所示:

    image

    至此,可获取到重要的参数 - 企业号应用信息:

    crop_id、corp_secret、agent_id

    Zabbix报警脚本

    外部脚本存放路径(默认):

    /usr/share/zabbix/alertscripts/
    

    可修改外部脚本存放路径地址文件

    vim /etc/zabbix/zabbix_server.conf
    

    大概在第500行代码左右可以查看到。

    python脚本代码如下(替换下面的‘xxxxx’部分)

    #!/usr/bin python3
    
    import requests
    import json
    import sys
    # 企业号及应用相关信息
    corp_id = 'xxxxxxx'
    corp_secret = 'xxxxxxx'
    agent_id = xxxxxxx
    # 存放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()
    
    

    注释:当前发送对象为‘@all’,可修改启动参数进行,获取对应的对象(企业微信的用户ID)后进行发送。

    在上传服务器指定文件夹后,可在服务器环境中运行python对脚本进行检验。(xxxx.py为微信脚本)

    python3 xxxx.py '参数1' '参数2'
    

    日志输出为:

    python3 gzh_wechat.py 'openidxxxxxxxxxxxxxxx'
    get success 43_fhNx5B49qQOjvTr-7fY8JBFerQG6n164H45WT1NDccGlEdIvSPIsG1CnsZ377E2VEMlA7D4k55iaawzzip7YIISlly3KcZXnt_gfV6J6kZOS60gnz1HxQ0fI3QgIrRxuvhTxYp7ebA1d0yBlLSIaAFAHOE
    https://qyapi.weixin.qq.com/cgi-bin/message/template/send?access_token=43_fhNx5B49qQOjvTr-7fY8JBFerQG6n164H45WT1NDccGlEdIvSPIsG1CnsZ377E2VEMlA7D4k55iaawzzip7YIISlly3KcZXnt_gfV6J6kZOS60gnz1HxQ0fI3QgIrRxuvhTxYp7ebA1d0yBlLSIaAFAHOE
    post success {"errcode":0,"errmsg":"ok","msgid":1803177490043944963}
    

    配置ZABBIX - 管理 - 报警媒介类型 - 创建媒体类型

    image

    上图Script parameters表示调用脚本时向脚本传入什么参数,参数解释如下

    {ALTER.SENDTO} # 发送给谁,该参数在邮件告警中有作用,但微信告警中没有

    {ALTER.SUBJECT} # 告警标题,该参数在邮件告警中有作用,但微信告警中没有

    {ALTER.MESSAGE} # 告警内容,在微信告警中有用

    • 修改告警内容格式

    修改告警内容样式,让告警内容看得更舒服(在微信告警中告警标题是没用的,发送给谁也是基本上没有用)

    如下图所示:

    image

    企业号通信录

    把所有要接收告警的人都添加到企业号通信录里面,逻辑是(先在通信录里创建该成员,再邀请该成员加入,或让他扫码加入)

    如下图所示:

    image

    到此企业微信通知Over。

    二、微信公众号消息推送(python)

    提前准备内容

    app_id、app_secret(微信公众号管理后台获取)

    template_id(微信公众号管理后台 - 模板Id),及模板内容参数。

    实现步骤

    具体配置内容于相同企业微信相同,具体步骤如上;

    代码脚本

    #!/usr/bin/python3
    
    import requests
    import json
    import sys
    # 企业号及应用相关信息
    app_id = 'xxxxxxxx'
    app_secret = 'xxxxxxxxxxxxxxxx'
    # 存放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://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s' % (app_id, app_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()
        to_user = sys.argv[1]
        subject = sys.argv[2]
        message = sys.argv[3]
        try:
            send_message_url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s' % access_token
            print(send_message_url)
            message_params = {
                                "touser": to_user,
                                "template_id":"-CUCjl5B1CEb_QxZFZABZ2erzz_kbLoJFiIhi3PcWaQ",
                                "data":{
                                    "first" : {
                                        "value":subject,
                                        "color":"#173177"
                                    },
                                    "keyword1" : {
                                        "value":message,
                                        "color":"#173177"
                                    },
                                    "keyword2" : {
                                        "value":"39.8元",
                                        "color":"#173177"
                                    },
                                    "remark":{
                                        "value":"欢迎再次购买!",
                                        "color":"#173177"
                                    }
                                }
                            }
            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()
    
    

    重点说明

    1.上传应用服务器中文件夹,脚本位置如下:

    image-20210331102107672.png

    2.文件上传后需给脚步文件操作权限,当前我勾选了所有权限:

    image-20210331102257020.png

    或者输入

    chmon u+x xxxx.py
    

    (如果给予权限后,依然提示权限问题一调要重启服务器)

    重启命令:
    reboot
    

    3.脚本代码中特别需要注意,在安装python后要找到配置python环境的启动文件,我当前的是

    /usr/bin/python3
    

    (该路径会运用到python脚本的启动项)

    如果找不到可以使用如下语句检索:

    whereis python3
    

    4.在复制脚本到指定位置后,且安装了Python后,一定要执行如下语句,安装脚本所需依赖:

    pip3 install requests
    
    python3 --version
    pip3 --version
    

    3.微信公众号消息推送(shell)

    提前准备内容

    app_id、app_secret(微信公众号管理后台获取)

    template_id(微信公众号管理后台 - 模板Id),及模板内容参数。

    实现步骤

    具体配置内容于相同企业微信相同,具体步骤如上;

    代码脚本

    #!/bin/sh
    # 微信消息发送脚本 
    
    #全局配置--
    #微信公众号appID
    appID=xxxxxx
    
    #微信公众号appsecret
    appsecret=xxxxxxx
    
    #微信公众号发送消息模板
    tpl_id=-xxxxxxxxxxxx
    #消息模板:
    #   {{first.DATA}} 
    #   代办事项:{{keyword1.DATA}} 
    #   提醒时间:{{keyword2.DATA}}
    #
    #   {{remark.DATA}}
    
    #获取微信公众号AccessToken,并缓存到本地 函数
    getAccessToken(){
        if [ -f "/var/log/zabbix/.wechat_accesstoken" ]; then
            access_token=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $1}'`
            expires_in=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $2}'`
            time=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $3}'`
                if [ -z $access_token ] || [ -z $expires_in ] || [ -z $time ]; then
                rm -f /var/log/zabbix/.wechat_accesstoken
                getAccessToken 
            fi
        else
            content=$(curl "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appID&secret=$appsecret")
    #       echo "get content: $content"
            access_token=`echo $content | awk -F "\"" '{print $4}'`
            expires_in=`echo $content | awk -F "\"" '{print $7}' | cut -d"}" -f1|cut -c2-`
            echo "access_token = $access_token" >> /var/log/zabbix/.wechat_accesstoken_log
    #       echo "expires_in = $expires_in"
            time=$(date +%s)
            echo "$access_token:$expires_in:$time" > /var/log/zabbix/.wechat_accesstoken
    
            if [ -z $access_token ] || [ -z $expires_in ] || [ -z $time ]; then
                        echo "not get access_token" >> /var/log/zabbix/.wechat_accesstoken_log
                        exit 0
            fi
            fi
    
        remain=$[$(date +%s) - $time]
        echo "remain:$remain">> /var/log/zabbix/.wechat_accesstoken_log
        limit=$[$expires_in - 7020]
        echo "limit:$limit">> /var/log/zabbix/.wechat_accesstoken_log
        if [ $remain -gt $limit ]; then
            rm -f /var/log/zabbix/.wechat_accesstoken
            getAccessToken
        fi
    }
    #发送消息函数
    sendMessage(){
        #消息json体
        message=`cat << EOF
        {
        "touser":"$openid",
        "template_id":"$tpl_id",
        "url":"$url",
        "data":{
                "first": {
                        "value":"$first",
                        "color":"#FF0000"
                },
                "keyword1":{
                        "value":"$keyword1",
                        "color":"#173177"
                },      
                "keyword2": {
                        "value":"$keyword2",
                        "color":"#173177"
                },
                "remark":{
                        "value":"$remark",
                        "color":"#FF0000"
                }
        }
         }
    EOF
    `
      info=`curl -X POST -H "Content-Type: application/json"  https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$access_token -d "$message"`
      echo "info:$info">> /var/log/zabbix/.wechat_accesstoken_log
    }
    
    #帮助信息函数
    #usage(){
    #    cat <<EOF
    #usage: $0 [-u openids -s summary -n name -t time -d detail -l link] [-h]
    #    u   wechat user openid , multiple comma separated
    #    s   message summary
    #    n   project name
    #    t   alarm time
    #    d   message detail
    #    l   link address
    #    h   output this help and exit
    #EOF
    #}
    
    
    #获取脚本执行参数
    #while getopts ":u:s:n:t:d:h:l:" op; do
    #    case $op in
    #        u)openids="$OPTARG";;
    #        s)first="$OPTARG";;
    #        n)name="$OPTARG";;
    #        t)date="$OPTARG";;
    #        d)remark="$OPTARG";;
    #        l)url="$OPTARG";;
    #        *)
    #        usage
    #        exit 0
    #        ;;
    #    esac
    #done
    
    #判断条件满足发送消息
    if [[ -n $1 && -n $2 && -n $3  && -n $4 ]]; then
        url=$2
        first=$3
        keyword1=$4
        keyword2=$5
        remark=$6
        echo `date +"%Y-%m-%d %H:%M:%S"` >> /var/log/zabbix/.wechat_accesstoken_log
        echo "send message : $url $openid $first $keyword1 $keyword2 $remark" >> /var/log/zabbix/.wechat_accesstoken_log 
        getAccessToken
       
        OLD_IFS="$IFS"
        IFS=","
        arr=($1)
        IFS="$OLD_IFS"
        for openid in ${arr[@]}
        do
            sendMessage
        done
        exit $?
    else
        echo `date +"%Y-%m-%d %H:%M:%S"` >> /var/log/zabbix/.wechat_accesstoken_log
        echo "error." >> /var/log/zabbix/.wechat_accesstoken_log
    #    usage
        exit 1
    fi
    

    2.配置脚本触发器及动作

    具体配置流程:

    1.用户篇

    1.1管理 -> 用户 -> 创建用户

    添加用户.png

    1.2为用户添加报警媒介

    添加报警媒介.png 赋值报警媒介.png

    1.3给予用户权限(一定市Super admin,用户类型:Super admin)

    用户权限.png

    2.触发器(配置 - 主机 - 触发器)

    2.1 选择主机 - 点击列表中触发器 - 点击创建触发器

    触发器001.png

    2.2 添加触发器

    触发器002.png
    注意:

    表达式的编写;

    问题事件生成模式:1.单个(只触发响应一下动作操作及脚本);2.多重(一定时间会重复响应动作操作及脚本)

    允许手动关闭(否则后期在关闭是无法进行手动操作,需选中);

    点击已启用/已关闭可以直接切换状态;

    3.动作篇(配置 - 动作)

    3.1 添加动作(可添加多个动作进行“或”,“与”,“非”的操作排列)

    添加动作-1.png

    3.2 动作 - 操作

    添加动作-操作步骤01.png 添加动作-操作步骤02.png

    故障{TRIGGER.STATUS},服务器:{HOSTNAME1}发生: {TRIGGER.NAME}故障!

    告警主机:{HOSTNAME1}

    告警时间:{EVENT.DATE} {EVENT.TIME}

    告警等级:{TRIGGER.SEVERITY}

    告警信息: {TRIGGER.NAME}

    告警项目:{TRIGGER.KEY1}

    问题详情:{ITEM.NAME}:{ITEM.VALUE}

    当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}

    事件 ID:{EVENT.ID}

    动作操作-003.png

    服务器:{HOST.NAME}: {TRIGGER.NAME}已恢复!

    告警主机:{HOST.NAME}

    告警地址:{HOST.IP}

    监控项目:{ITEM.NAME}

    监控取值:{ITEM.LASTVALUE}

    告警等级:{TRIGGER.SEVERITY}

    当前状态:{TRIGGER.STATUS}

    告警信息:{TRIGGER.NAME}

    告警时间:{EVENT.DATE} {EVENT.TIME}

    恢复时间:{EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME}

    持续时间:{EVENT.AGE}

    事件ID:{EVENT.ID}

    最后添加完千万不要忘记更新。

    参考文献:zabbix4.2配置微信告警脚本教程 https://idc.wanyunshuju.com/zab/1028.html

    相关文章

      网友评论

          本文标题:ZABBIX之旅(5.0版以上)

          本文链接:https://www.haomeiwen.com/subject/pxvohltx.html