zabbix添加钉钉告警机器人使用bash和python两种脚本
查看脚本目录
vi /etc/zabbix/zabbix_server.conf# 脚本存放路径
AlertScriptsPath=/usr/lib/zabbix/alertscripts
编写脚本(二选一)
bash脚本
- 编写脚本
cd /usr/lib/zabbix/alertscripts
vi zabbix_dingding_robot.sh
- 脚本zabbix_dingding_robot.sh
#!/bin/bash
# Author: xzlAwin
# Email: xzlawin@163.com
# Date: 2024.07.23
# 描述: zabbix使用钉钉机器人告警脚本# 脚本运行时,获取参数
to=$1
subject=$2
text=$3# 加签验证密钥
secret="填写自己密钥"
# Webhook
webhook="https://oapi.dingtalk.com/robot/send?access_token=填写自己的token"# 获取当前时间戳,单位ms
timestamp=$(date +%s%3N)
echo $timestamp# 正确的格式
stringToSign="$timestamp
$secret"# 使用openssl进行HMAC-SHA256签名
# 注意:echo -e 用于解释转义字符(如\n),但某些版本的echo可能需要-E选项
# 使用echo或printf确保字符串中的换行符正确传递
hmacsha256=$(echo -n "$stringToSign" | openssl dgst -sha256 -hmac "$secret" -binary | base64)# 输出hmacsha256加密
echo "hmacsha256: $hmacsha256"# shell没有encodeURIComponent函数,AI生成
encodeURIComponent() {# 使用printf和一些字符转义来模拟encodeURIComponent# 这里只处理了一些基本的转义,并不是完全符合encodeURIComponent的标准local string="${1}"local strlen=${#string}local i=0local output=""while [[ $i -lt $strlen ]]; doc=${string:$i:1}if [[ "$c" = "-" || "$c" = "_" || "$c" = "." || "$c" = "~" ]]; thenoutput+="${c}"elif [[ "$c" = "/" ]]; thenoutput+="%2F"elif [[ "$c" = "?" ]]; thenoutput+="%3F"elif [[ "$c" = ":" ]]; thenoutput+="%3A"elif [[ "$c" = "#" ]]; thenoutput+="%23"elif [[ "$c" = "%" ]]; thenoutput+="%25"elif [[ "$c" = "&" ]]; thenoutput+="%26"elif [[ "$c" = "+" ]]; thenoutput+="%2B"elif [[ "$c" = "=" ]]; thenoutput+="%3D"elif [[ "$c" = "{" ]]; thenoutput+="%7B"elif [[ "$c" = "}" ]]; thenoutput+="%7D"elif [[ "$c" = "\\" ]]; thenoutput+="%5C"elif [[ "$c" = " " ]]; thenoutput+="%20"elseprintf -v ord "%d" "'$c"if [[ $ord -ge 48 && $ord -le 57 ]] || # 0-9[[ $ord -ge 65 && $ord -le 90 ]] || # A-Z[[ $ord -ge 97 && $ord -le 122 ]]; then # a-zoutput+="${c}"elseprintf -v o "%02x" "'$c"output+="%${o}"fifii=$((i+1))doneecho -n "${output}"
}# 调用encodeURIComponent函数,获得签名
sign=$(encodeURIComponent $hmacsha256)
# 输出签名
echo "${sign}"url="$webhook×tamp=$timestamp&sign=$sign"
# 输出完整的url
echo $url# 调用钉钉消息通知接口
curl $url -H 'Content-Type: application/json' \
-H 'Content-Type: application/json' \
-H 'Charset: utf-8' \
-d '
{"msgtype": "text","text": {"content": "'"$text"'"},"at":{"atMobiles": [ "'"$1"'" ],"isAtAll": false}
}'
python脚本
- 编写脚本
cd /usr/lib/zabbix/alertscripts
vi zabbix_dingding_robot.sh
- 脚本zabbix_dingding_robot.sh
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Author: xzlAwin
# Email: xzlawin@163.com
# Date: 2024.07.23
# 描述: zabbix使用钉钉机器人告警脚本import sys
import time
import hmac
import hashlib
import base64
import urllib.parse
import requests
import json# 脚本运行时,获取参数
to=sys.argv[1]
subject=sys.argv[2]
text=sys.argv[3]# 加签验证密钥
secret="填写自己的密钥"
# Webhook
webhook="https://oapi.dingtalk.com/robot/send?access_token=填写自己的token"def func_sign():# 获取当前时间戳,单位mstimestamp = str(round(time.time() * 1000))print(timestamp)# 字符串转换utf-8编码secret_enc = secret.encode('utf-8')string_to_sign = '{}\n{}'.format(timestamp, secret)string_to_sign_enc = string_to_sign.encode('utf-8')# hmacsha256加密hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))print(sign)url=webhook+'×tamp='+str(timestamp)+'&sign='+signreturn urldef func_sendMessage(url):headers = {"Content-Type": "application/json","Charset": "UTF-8"}message = {"msgtype": "text", # 有text, "markdown"、link、整体跳转ActionCard 、独立跳转ActionCard、FeedCard类型等"text": {"content": text # 消息内容},"at": {"atMobiles": [to,],"isAtAll": False # 是否是发送群中全体成员}}data = json.dumps(message)response = requests.post(url=url, data=data, headers=headers)res_json = response.json()print(response.json())print(type(response.json))errcode = res_json['errcode']errmsg = res_json['errmsg']if errcode == 0:print('消息发送成功!')else:print('消息发送失败!',errcode, errmsg)exit(3)if __name__ == '__main__':url = func_sign()func_sendMessage(url)
- 将脚本zabbix_dingding_robot.sh复制到目录 /usr/lib/zabbix/alertscripts
# zabbix脚本存放目录
cd /usr/lib/zabbix/alertscripts
chmod +x zabbix_dingding_robot.sh
# 或者
chmod +x zabbix_dingding_robot.py
登录钉钉,创建内部群和钉钉机器人
### 创建报警媒体类型
- 创建报警媒体类型,[管理] → [报警媒介类型] → [创建媒介类型]
# 脚本参数
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}
给用户添加授权
- 给用户添加授权,[管理] → [用户] → [报警媒介]
创建动作
- 创建动作,[配置] → [动作] → [创建动作]
- 报警参数
# 默认标题
故障{TRIGGER.STATUS},服务器:{HOSTNAME1}发生:{TRIGGER.NAME}故障!
# 消息内容
告警主机: {HOSTNAME}
告警 IP: {HOST.IP}
告警时间: {EVENT.DATE} {EVENT.TIME}
告警等级: {TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目: {TRIGGER.KEY1}
问题详情: {ITEM.NAME}:{ITEM.VALUE}
当前状态: {TRIGGER.STATUS}:{ITEM.VALUE1}
事件ID : {EVENT.ID}
- 恢复参数
# 默认标题
恢复{TRIGGER.STATUS},服务器:{HOSTNAME1}发生:{TRIGGER.NAME}已恢复!
# 消息内容
告警主机: {HOSTNAME}
告警 IP: {HOST.IP}
告警时间: {EVENT.DATE} {EVENT.TIME}
告警等级: {TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目: {TRIGGER.KEY1}
问题详情: {ITEM.NAME}:{ITEM.VALUE}
当前状态: {TRIGGER.STATUS}:{ITEM.VALUE1}
事件 ID: {EVENT.ID}
- 确认操作
# 默认标题
已确认: {TRIGGER.NAME}
# 消息内容
用户: {USER.FULLNAME}
确认时间: {ACK.DATE} {ACK.TIME}
确认消息: {ACK.MESSAGE}
当前问题状态: {EVENT.STATUS}
测试
- 钉钉告警发送成功