Shell脚本如何测试告警通道有效性

wen 实用脚本 1

本文目录导读:

Shell脚本如何测试告警通道有效性

  1. 核心思路
  2. 常见告警通道测试脚本
  3. 进阶:批量测试所有通道的脚本框架
  4. 最佳实践与注意事项

测试告警通道有效性是运维中非常关键的环节,下面我会提供几种常用的 Shell 脚本方法,涵盖邮件、短信(HTTP API)、钉钉/企业微信机器人以及通用的 Webhook 场景。

核心思路

通用的测试流程如下:

  1. 构造测试消息:定义明确的标题和内容(如 “【测试】告警通道验证 #时间戳”)。
  2. 调用通道接口:执行发送命令(如 curlmail)。
  3. 检查返回结果:根据返回码、HTTP 状态码或响应内容判断成功与否。
  4. 输出测试报告:打印成功/失败状态,方便集成到监控系统(如 Zabbix、Prometheus)。

常见告警通道测试脚本

1 测试邮件告警(SMTP)

大多数 Linux 系统自带 mailsendmail 命令。

#!/bin/bash
# 配置
TO="admin@example.com"
SUBJECT="【告警测试】邮件通道验证 - $(date '+%Y-%m-%d %H:%M:%S')"
BODY="这是一封测试告警邮件,用于验证 SMTP 通道是否正常,请勿回复。"
# 发送邮件(使用 mail 命令)
if echo "$BODY" | mail -s "$SUBJECT" "$TO" 2>/dev/null; then
    echo "[SUCCESS] 邮件告警通道测试通过 -> $TO"
else
    echo "[FAIL] 邮件告警通道测试失败 -> $TO"
    exit 1
fi

注意:如果使用外部 SMTP(如 QQ邮箱、阿里云邮件),可能需要借助 mailx 并配置 /etc/mail.rc,或使用 sendemailcurl(通过 SMTP API)。

2 测试 HTTP 告警(短信、语音、HTTP API)

很多短信/语音服务商(如阿里云、腾讯云、Twilio)提供 HTTP POST 接口,以下是一个通用模板,适用于大多数 RESTful API。

#!/bin/bash
# ---------- 配置 ----------
API_URL="https://api.example.com/send_sms"
API_KEY="your_api_key_here"
PHONE="13800138000"
# 构造 JSON 消息
SIGN_NAME="告警平台"
TEMPLATE_CODE="SMS_123456"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CONTENT="【测试】短信告警通道验证 - $TIMESTAMP"
# 发送 POST 请求
response=$(curl -s -o /dev/null -w "%{http_code}" \
    --connect-timeout 5 --max-time 10 \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d "{
        \"phone\": \"$PHONE\",
        \"signName\": \"$SIGN_NAME\",
        \"templateCode\": \"$TEMPLATE_CODE\",
        \"templateParam\": {\"content\": \"$CONTENT\"}
    }" \
    "$API_URL")
# 判断 HTTP 状态码
if [ "$response" -eq 200 ]; then
    echo "[SUCCESS] HTTP 告警通道测试通过 (HTTP $response)"
else
    echo "[FAIL] HTTP 告警通道测试失败 (HTTP $response)"
    exit 1
fi

3 测试企业微信/钉钉机器人 Webhook

这类机器人使用 Markdown 或文本消息,通过 HTTP POST 发送。

企业微信机器人示例

#!/bin/bash
KEY="your-webhook-key"
WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=$KEY"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CONTENT="**告警通道测试**\n\n- 时间:$TIMESTAMP\n- 状态:测试通过\n- 备注:这是一条由 Shell 脚本发送的验证消息。"
# 发送消息
response=$(curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "{
        \"msgtype\": \"markdown\",
        \"markdown\": {
            \"content\": \"$CONTENT\"
        }
    }")
# 解析返回结果(企业微信返回 {"errcode":0,"errmsg":"ok"})
if echo "$response" | grep -q '"errcode":0'; then
    echo "[SUCCESS] 企业微信告警通道测试通过"
else
    echo "[FAIL] 企业微信告警通道测试失败: $response"
    exit 1
fi

钉钉机器人示例(Webhook 结构略有不同):

#!/bin/bash
ACCESS_TOKEN="your-access-token"
SECRET="your-secret"  # 如果开启加签
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=$ACCESS_TOKEN"
# 如果使用加签,需要生成签名
if [ -n "$SECRET" ]; then
    TIMESTAMP_T=$(date +%s%3N)
    SIGN=$(echo -n "$TIMESTAMP_T\n$SECRET" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)
    WEBHOOK_URL="$WEBHOOK_URL&timestamp=$TIMESTAMP_T&sign=$SIGN"
fi
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CONTENT="## 告警通道测试\n\n- **时间**:$TIMESTAMP\n- **状态**:✅ 测试通过"
response=$(curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "{
        \"msgtype\": \"markdown\",
        \"markdown\": {
            \"title\": \"告警通道测试\",
            \"text\": \"$CONTENT\"
        }
    }")
# 钉钉返回 {"errcode":0,"errmsg":"ok"}
if echo "$response" | grep -q '"errcode":0'; then
    echo "[SUCCESS] 钉钉告警通道测试通过"
else
    echo "[FAIL] 钉钉告警通道测试失败: $response"
    exit 1
fi

4 测试通用的 Webhook(如 Slack、PagerDuty)

以 Slack Incoming Webhook 为例:

#!/bin/bash
WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/xxxxxxxxxxxx"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
MESSAGE="[告警测试] Slack Webhook 通道验证 - $TIMESTAMP"
response=$(curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "{
        \"text\": \"$MESSAGE\",
        \"username\": \"告警机器人\",
        \"icon_emoji\": \":warning:\"
    }")
# Slack 成功返回 "ok"
if [ "$response" = "ok" ]; then
    echo "[SUCCESS] Slack Webhook 测试通过"
else
    echo "[FAIL] Slack Webhook 测试失败: $response"
    exit 1
fi

进阶:批量测试所有通道的脚本框架

如果你有多个通道需要同时测试,可以使用如下框架一次性检查所有通道。

#!/bin/bash
# 测试结果数组
results=()
# 函数:邮件通道
test_email() {
    if echo "测试告警邮件" | mail -s "告警测试" admin@example.com; then
        results+=("[PASS] 邮件通道")
    else
        results+=("[FAIL] 邮件通道")
    fi
}
# 函数:企业微信机器人
test_wecom() {
    # ... 实现同 2.3 节 ...
    results+=("[PASS] 企业微信通道")
}
# 主测试流程
echo "========== 告警通道批量测试 =========="
test_email
test_wecom
# ... 添加更多通道 ...
# 输出报告
echo ""
echo "========== 测试结果汇总 =========="
for result in "${results[@]}"; do
    echo "$result"
done

最佳实践与注意事项

要点 建议
幂等性 发送消息时加上唯一标识(时间戳、UUID),避免重复消息干扰监控。
超时控制 使用 curl --connect-timeout 5 --max-time 10 防止阻塞。
退出码 失败时 exit 1,方便被 Cron 或监控系统捕获。
日志记录 将脚本输出重定向到日志文件:./test_alert.sh >> /var/log/alert_test.log 2>&1
敏感信息 API Key、Secret 不要硬编码在脚本中,应通过环境变量或配置文件注入。
最小化干扰 在非生产环境执行,或使用特殊的测试接收地址(如邮件发到测试邮箱而非真实告警群)。

通过 Shell 脚本测试告警通道的核心能力在于 发送请求 → 检查返回状态,你可以根据实际使用的通道类型(邮件、HTTP API、Webhook)选择对应的脚本,将测试脚本集成到 Cron 或监控系统(如 Prometheus Blackbox Exporter 的 tcp/http 探测)中,可以实现周期性的自动化检活。

抱歉,评论功能暂时关闭!