背景
为了实现监控客户端断开并触发企业微信告警的功能,我们需要编写一个脚本。这个脚本将定期检查客户端的状态,一旦检测到异常断开的情况,就会通过企业微信的API发送一条告警消息给指定的用户或群组。下面是一个基于bash的简单示例方案,其中包括了基本步骤和代码片段。
脚本编写
服务器需要安装jq
yum install jq -y
#!/bin/bash
# ==========================================
# EMQX 客户端状态检查 + 自动踢出 + 企业微信告警
# 作者: 邓斌
# 版本: v1.3
# ==========================================
# === 日志文件配置 ===
RootDir=$(cd $(dirname $0); pwd)
LOGFILE="${RootDir}/check_emqx_clients.log"
exec > >(tee -a "$LOGFILE") 2>&1
# === EMQX API 配置 ===
API="http://127.0.0.1:18083/api/v5/clients"
AUTH="5428c04710234984:Va9Aa8Q2yTUMK1dXV3KCstVxnnM7zorEfVpmu419BbmlA"
# === 企业微信告警 Webhook ===
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx"
# === 定义需要监控的客户端ID ===
TARGET_CLIENTS=("mirayai_sport" "miray-iot-platform")
# === 告警阈值(离线超过5分钟才告警) ===
TIME_THRESHOLD=300 # 5分钟 (单位:秒)
# === 临时文件 ===
TMP_FILE=$(mktemp /tmp/emqx_clients.XXXXXX)
# === 获取 EMQX 客户端列表 ===
curl -s -u "$AUTH" "$API" -o "$TMP_FILE"
if [ $? -ne 0 ]; then
echo "❌ 无法连接到 EMQX API"
exit 1
fi
# === 检查断开的目标客户端 ===
disconnected=""
for client in "${TARGET_CLIENTS[@]}"; do
# 获取客户端的断开时间
disconnected_at=$(jq -r ".data[] | select(.clientid==\"$client\") | .disconnected_at" "$TMP_FILE")
connected=$(jq -r ".data[] | select(.clientid==\"$client\") | .connected" "$TMP_FILE")
# 如果客户端未连接并且断开时间不为null
if [ "$connected" == "false" ] && [ "$disconnected_at" != "null" ]; then
# 计算客户端离线时间
current_time=$(date +%s)
disconnected_time=$(date -d "$disconnected_at" +%s)
offline_duration=$((current_time - disconnected_time))
# 如果离线时间超过 5 分钟,记录该客户端
if [ "$offline_duration" -ge "$TIME_THRESHOLD" ]; then
disconnected="$disconnected $client"
fi
fi
done
# === 构建时间戳 ===
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
if [ -n "$disconnected" ]; then
echo "⚠️ [$timestamp] 检测到以下客户端断开超过 5 分钟:"
echo "$disconnected"
# # === 执行踢出操作 ===
# for id in $disconnected; do
# echo "🚫 踢出客户端: $id"
# curl -s -X DELETE -u "$AUTH" "$API/$id" >/dev/null
# done
# === 发送企业微信告警 ===
content="**EMQX 客户端断开告警**\n\n> 时间:${timestamp}\n> 异常客户端:\n> $(echo "$disconnected" | sed 's/^/> /')\n> 已执行自动踢出"
curl -s "$WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"msgtype\": \"markdown\",
\"markdown\": {
\"content\": \"$content\"
}
}" >/dev/null
else
echo "✅ [$timestamp] 所有目标客户端均在线"
fi
# === 清理临时文件 ===
rm -f "$TMP_FILE"