ZABBIX之旅(5.0版以上)

2021-03-31  本文已影响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告警

企业号上的重要信息

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

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

上一篇下一篇

猜你喜欢

热点阅读