深色模式
自动化接警
摘要:自动化接警不是"把告警转发到群里",而是完成播报、认领、建群、记录四件事。本文给出 Alertmanager webhook 的消息格式、一个最小可用转发服务,以及联调时的验证方法。
适用环境
bash
python3 --version
# 机器人服务需要能被 Alertmanager 访问
ss -lntp 2>/dev/null | grep -E '5001|9093'1
2
3
2
3
操作步骤
第 1 步:确认 Alertmanager 推送格式
bash
# Alertmanager 向 webhook 推送的 JSON 包含 alerts 数组
curl -sS -X POST http://127.0.0.1:5001/webhook -H 'Content-Type: application/json' -d '{
"status":"firing",
"commonLabels":{"alertname":"TestAlert","severity":"critical","service":"pay"},
"commonAnnotations":{"summary":"测试告警"},
"alerts":[{"status":"firing","labels":{"alertname":"TestAlert"},"annotations":{"summary":"测试告警"},"startsAt":"2026-10-09T02:00:00Z"}]
}' -w '\nHTTP %{http_code}\n'1
2
3
4
5
6
7
2
3
4
5
6
7
第 2 步:最小转发服务
python
# bot.py:接告警 -> 播报 -> 记录
import json, os, urllib.request
from http.server import BaseHTTPRequestHandler, HTTPServer
WEBHOOK = os.environ["IM_WEBHOOK"]
LOG = "pages.log"
def send(text):
body = json.dumps({"msgtype": "text", "text": {"content": text}}).encode()
req = urllib.request.Request(WEBHOOK, data=body,
headers={"Content-Type": "application/json"})
urllib.request.urlopen(req, timeout=5)
class H(BaseHTTPRequestHandler):
def do_POST(self):
n = int(self.headers.get("Content-Length", 0))
data = json.loads(self.rfile.read(n))
labels = data.get("commonLabels", {})
sev = labels.get("severity", "unknown")
text = f"[Sev-{sev}] {labels.get('alertname')} service={labels.get('service')} status={data.get('status')}"
open(LOG, "a").write(text + "\n")
try:
send(text + " 回复【认领】以 ACK")
except Exception as e:
open(LOG, "a").write(f"send failed: {e}\n")
self.send_response(200); self.end_headers(); self.wfile.write(b"ok")
HTTPServer(("0.0.0.0", 5001), H).serve_forever()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
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
第 3 步:配置 Alertmanager 指向机器人
yaml
receivers:
- name: 'oncall-primary'
webhook_configs:
- url: 'http://bot:5001/webhook'
send_resolved: true
http_config:
follow_redirects: false1
2
3
4
5
6
7
2
3
4
5
6
7
第 4 步:认领(ACK)闭环
bash
# 认领后写入 ack 记录,升级逻辑据此停止
cat > ack.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
id=$1; who=${2:-$USER}
mkdir -p /var/run/ack && echo "$who $(date -u '+%F %T')" > "/var/run/ack/$id"
echo "已认领 $id by $who"
EOF
chmod +x ack.sh && ./ack.sh TestAlert alice1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
第 5 步:自动建事件频道
bash
# Sev1 时自动创建频道并拉入对应值班人
cat > open-channel.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
name="inc-$(date -u '+%Y%m%d-%H%M')"
curl -sS -X POST "${IM_API}/channels.create" \
-H "Authorization: Bearer ${IM_TOKEN}" \
-d "name=$name" | jq -r '.channel.id' | tee /tmp/channel_id
EOF
chmod +x open-channel.sh1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
验证
bash
# 1. 服务存活
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5001/webhook -X POST -d '{}' -H 'Content-Type: application/json'
# 2. 告警已落盘
tail -3 pages.log
# 3. 认领后升级停止
./ack.sh TestAlert alice && ls /var/run/ack/1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
常见坑
机器人单点,挂了就全员失联
机器人进程要有守护(systemd/k8s Deployment)与健康检查,并对机器人本身做告警——由另一个独立通道发出。
只转发 firing 不处理 resolved
send_resolved: false 会让频道里永远挂着已恢复的告警。务必开启 resolved 推送。
webhook 无鉴权暴露在公网
任何人都能伪造告警触发全员出动。加 token 校验或 IP 白名单,服务不直接暴露公网。