环境

  • CentOS7,docker-ce 20.0

  • 启动 zabbix5 容器

    1
    2
    3
    4
    
    docker run -d \
        --net host \
        --name zabbix \
        harbor.colben.cn/general/alpine-zabbix
    
  • 打开浏览器,访问 http://ip/zabbix/,打开 zabbix web 安装界面

  • 不要做任何修改,一直下一步,直到打开 zabbix 登陆页面,默认 Admin/zabbix

部署脚本

  • 进入 zabbix 容器中

  • 安装 jq 命令

  • 修改 /etc/zabbix/zabbix_server.conf,配置告警脚本加载位置

    1
    
    AlertScriptsPath=/var/log/zabbix/alertscripts
    
  • 创建 /var/log/zabbix/alertscripts/wechat.sh,内容如下

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    
    set -euo pipefail
    export LANG=en_US.UTF-8
    trap Quit EXIT
    
    # 企业 ID
    CORP_ID='ww11112222aaaabbbb'
    # 应用 Secret
    CORP_SECRET='ABCDefghIJKLmnopQRSTuvwxYZ0000111122223333U'
    # 应用 ID
    AGENT_ID='1000002'
    # 多个用户之间用"| 间隔
    TO_USER='@all'
    # 部门 ID
    TO_PARTY='1'
    # token 文件存放位置
    TOKEN_FILE='/tmp/wechat_token'
    
    function Print {
        echo -e "$(date +'[%F %T] INFO') $*"
    }
    
    function Warn {
        echo -e "$(date +'[%F %T] WARN') $*"
    }
    
    function Error {
        echo -e "$(date +'[%F %T] ERRRO') $*"
        exit 1
    }
    
    function Quit {
        [ 0 -ne $? ] && rm -f $TOKEN_FILE && Error Failed to alert!
        [ -z "${END:-}" ] && echo && Error Interrupted manually!
        Print Succeeded to alert.
    }
    
    function RequestToken {
        Warn Request token ...
        date +%s > $TOKEN_FILE
        local response=$(curl -sSL \
            "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$CORP_ID&corpsecret=$CORP_SECRET")
        local errcode=$(echo "$response" | jq -erM .errcode)
        local errmsg=$(echo "$response" | jq -erM .errmsg)
        [ 0 -ne $errcode -a 'ok' != "$errmsg" ] && Error Request token failed: $errcode, $errmsg!
        echo $response | jq -erM .access_token >> $TOKEN_FILE
    }
    
    function GetToken {
        [ ! -e $TOKEN_FILE ] && RequestToken && return
        Warn Get token from localfile ...
        local now=$(date +%s)
        local token="$(sed -n 2p $TOKEN_FILE)"
        local token_time=$(sed -n 1p $TOKEN_FILE)
        if [ $((now-token_time)) -gt 7200 ]; then
            Warn Local token expired ...
            RequestToken
        fi
    }
    
    function SendMsg {
        Warn Send message: $1 ...
        local token=$(sed -n 2p $TOKEN_FILE)
        local response=$(curl -sSL -X POST \
            -H "Content-Type: application/json" \
            "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$token" \
            -d @- <<-EOF
    {
      "touser": "$TO_USER",
      "toparty": "$TO_PARTY",
      "msgtype": "text",
      "agentid": "$AGENT_ID",
      "text": {
        "content": "$1\n$2"
      },
      "safe": 0
    }
    EOF
    )
        local errcode=$(echo "$response" | jq -erM .errcode)
        local errmsg="$(echo "$response" | jq -erM .errmsg)"
        [ 0 -eq $errcode -o 'ok' = "$errmsg" ] || Error Send msg failed: $errcode, $errmsg!
    }
    
    # Start here
    GetToken
    SendMsg "$1" "$2"
    END=1
    
  • 重启 zabbix 容器

  • 测试脚本,如果企业微信能收到信息则表示脚本正常

    1
    
    /var/log/zabbix/alertscripts/wechat.sh test_subject test_content
    

配置 zabbix

  • 浏览器登陆 zabbix
  • 单击"管理"-“报警媒介类型”-“创建媒体类型”,输入如下信息
    • 名称: 企业微信
    • 类型: 脚本
    • 脚本名称: wechat.py
    • 脚本参数:
      • {ALERT.SUBJECT}
      • {ALERT.MESSAGE}
    • 其它默认,单击"添加"
  • 单击"管理"-“用户”-“Admin”-“报警媒介”-“添加”,输入如下信息
    • 类型: 企业微信
    • 收件人: 这一项用不到了,随便写 …
    • 其它默认,单击"添加"
  • 单击"配置"-“动作”-“Report problems to Zabbix administrators”
    • 在"动作"标签页下,选中"已启用"
    • 在"操作"标签页下,输入如下信息
      • 默认标题:
        1
        
        XXXX系统 {HOST.NAME} 故障: {TRIGGER.NAME}
        
      • 消息内容:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        
        服务器: {HOST.NAME}\n
        故障时间: {EVENT.DATE} {EVENT.TIME}\n
        故障名称: {TRIGGER.NAME}\n
        故障状态: {TRIGGER.STATUS}\n
        故障等级: {TRIGGER.SEVERITY}\n
        故障编号: ID: {EVENT.ID}\n
        监控项: {ITEM.NAME1} ({HOST.NAME1}:{ITEM.KEY1})\n
        监控值:\n
        {ITEM.VALUE1}
        
      • 单击"操作"框中的"编辑",打开"操作细节"框,输入如下信息
        • 操作类型: 发送消息
        • 发送到用户: “添加” Admin 用户
        • 仅送到: 企业微信
        • 其他默认,单击"更新"
    • 在"恢复操作"标签页下,输入如下信息
      • 默认标题:
        1
        
        XXXX系统 {HOST.NAME} 恢复: {TRIGGER.NAME}
        
      • 消息内容:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        
        服务器: {HOST.NAME}\n
        恢复时间: {EVENT.DATE} {EVENT.TIME}\n
        故障名称: {TRIGGER.NAME}\n
        故障状态: {TRIGGER.STATUS}\n
        故障等级: {TRIGGER.SEVERITY}\n
        故障编号: ID: {EVENT.ID}\n
        监控项: {ITEM.NAME1} ({HOST.NAME1}:{ITEM.KEY1})\n
        监控值:\n
        {ITEM.VALUE1}
        
      • 单击"操作"框中的步骤1的"编辑",打开"操作细节"框,输入如下信息
        • 操作类型: 发送消息
        • 发送到用户: “添加” Admin 用户
        • 仅送到: 企业微信
        • 其他默认,单击"更新"
    • 忽略"更新操作"
    • 其他默认,单击"更新"