告警去重实现

问题

服务挂掉时,监控每 5 分钟检查一次,每次都发微信告警,造成告警轰炸。

方案

用 JSON 文件记录每个服务上次告警时间,30 分钟内同服务不重复发送;服务恢复后清掉记录,下次再挂立即重新告警。

核心逻辑

  1. 读取状态文件 .alert_state.json
  2. 失败的服务如果在 30 分钟内已告警过 → 跳过
  3. 否则发送告警并记录时间
  4. 每次检查后清理已恢复服务的记录

关键代码

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
    yaml
def send_wechat_alert(failed_results: List[dict], webhook_url: str):
"""
发送企业微信机器人告警(Markdown 格式)

Args:
failed_results: 失败的检查项列表
webhook_url: 企业微信机器人 Webhook 地址
"""
if not failed_results or not webhook_url:
return

if not HAS_REQUESTS:
print("[WARN] 缺少 requests 库,无法发送告警")
return

# ── 告警去重:30 分钟内同服务不重复告警 ──
state = load_alert_state() # 读上次告警记录
now = datetime.now() # 当前时间
to_send = [] # 真正要发告警的服务
need_save = False # 状态文件是否需要更新

for r in failed_results:
name = r['name']
last_time_str = state.get(name) # 上次告警时间(字符串),没有就是 None

if last_time_str:
last_time = datetime.strptime(last_time_str, '%Y-%m-%d %H:%M:%S')
minutes_diff = (now - last_time).total_seconds() / 60
if minutes_diff < 30:
print(f" ⏭️ {name} 30分钟内已告警,跳过")
continue # 30分钟内 → 不发,跳过这个服务

# 到这里说明:要么从没告警过,要么已超过30分钟 → 要发
to_send.append(r)
state[name] = now.strftime('%Y-%m-%d %H:%M:%S') # 更新记录
need_save = True

if not to_send: # 所有失败都被去重挡掉 → 什么都不发
print(" ℹ️ 所有失败项均在30分钟内,本次不重复告警")
return

if need_save:
save_alert_state(state) # 保存新状态


# 构造 Markdown 消息
lines = [
"## 🚨 服务健康检查告警",
f"> 检查时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
f"> 失败项数: **{len(to_send)}**",
"",
]
for r in to_send:
lines.append(f"- **{r['name']}** ({r['target']})")
lines.append(f" > {r['error']}")

payload = {
"msgtype": "markdown",
"markdown": {
"content": "\n".join(lines)
}
}

try:
resp = requests.post(webhook_url, json=payload, timeout=5)
if resp.status_code == 200:
print(f"\n📤 企业微信告警已发送({len(to_send)} 项失败)")
else:
print(f"\n⚠️ 告警发送失败,HTTP {resp.status_code}: {resp.text}")
except Exception as e:
print(f"\n⚠️ 告警发送异常: {e}")

验证

连续 3 次故障只收到 1 条告警。


告警去重实现
https://bingsv.github.io/2026/08/04/告警去重实现/
作者
Bingsv
发布于
2026年8月4日
许可协议