aa65f10c52
Audit docs:
- docs/reports/audit-phase-2{a-j}-line-walk.md: per-file line walk findings
- docs/reports/audit-phase-2-findings-matrix.md: 63 findings (52 fixed, 3 partial, 7 accepted)
- docs/reports/2026-05-23-full-audit-report.md: full audit consolidation
- docs/reports/audit-full-vs-phase2-reconciliation.md: cross-reference
- docs/reports/audit-phase-2-walk-closure.md: closure sign-off
Project docs:
- docs/project/phase-2-audit-remediation.md: SSOT for all fixes
- docs/project/alert-push-policy.md: dashboard alert design decisions
- docs/project/production-verification-checklist.md: first-deploy checklist
- docs/project/script-execution.md: script platform design
- docs/project/wsl-integration-test.md: WSL code-only verification guide
- docs/project/line-walk-audit-standard.md: audit methodology
- docs/project/mysql-mcp-setup.md: MCP config guide
Changelogs: 18 entries (2026-05-22 to 2026-05-23)
Project memory: CLAUDE.md, AGENTS.md updated to reflect current state
Deploy: nginx_https.conf template updated
Co-authored-by: Cursor <cursoragent@cursor.com>
4.6 KiB
4.6 KiB
告警推送策略(产品决策)
状态: ✅ 已实现(2026-05-22)
通道分工
| 通道 | 职责 | 实现 |
|---|---|---|
| Telegram | 主动通知(告警/恢复/系统) | send_telegram_*;同机同指标 5 分钟 防抖 |
| 浏览器 Dashboard | 仅展示汇总状态 | 统计卡「告警中」+「运行状态」文案;无声音、无实时告警列表 |
WebSocket /ws/alerts |
触发仪表盘刷新 | 收到事件后 loadDashboard();不弹窗、不响铃 |
第 1 项(已定)
- 浏览器:不需要声音,不需要逐条告警横幅。
- 通知:以 Telegram 为准。
- 浏览器:只看 在线/离线/告警台数 等状态(
/servers/stats+ Redisalerts:*计数)。
第 2 项(已定)
WS 收到消息后 只 loadDashboard(),不 loadSyncs()。「最近同步」靠 30s 定时器 + 手动刷新。
第 3 项(已定)
- 告警 WS 继续
?token=access_token(不做换票)。 - 缓解:强制 HTTPS + Nginx 对
/ws/单独 access_log,不记录 query(见deploy/nginx_https.conf)。
实现清单
| 文件 | 改动 |
|---|---|
web/app/index.html |
运行状态面板;WS 只 loadDashboard();移除声音/告警列表 |
server/api/websocket.py |
注释:浏览器仅刷新 stats,Telegram 防抖 |
deploy/nginx_https.conf |
/ws/ 专用 log_format(无 $args) |
图 5 — 改后运行时(定稿)
flowchart TB
subgraph notify [通知]
TG[Telegram 手机]
end
subgraph dash [浏览器仪表盘]
NUM[告警中 / 在线 / 离线]
SYNC[最近同步 — 30s 或手动刷新]
WS["/ws/alerts 长连"]
end
HB[子机心跳] --> API[中心检测]
API -->|超阈值| TG
API -->|broadcast| WS
WS -->|仅 loadDashboard| NUM
TIMER[每 30s] --> NUM
TIMER --> SYNC
架构图
图 1 — 仪表盘上的两块数据(互不替代)
flowchart TB
subgraph browser [浏览器 仪表盘 index.html]
UI_TOP[上方:统计卡 + 运行状态]
UI_BOT[下方:最近同步 8 条]
end
API_STATS["GET /api/servers/stats"]
API_LOGS["GET /api/servers/logs?limit=8"]
UI_TOP -->|"loadDashboard() ①"| API_STATS
UI_BOT -->|"loadSyncs() ②"| API_LOGS
API_STATS --> REDIS_H[(Redis heartbeat:* + alerts:*)]
API_LOGS --> MYSQL[(MySQL sync_logs)]
图 2 — 告警从子机到 Telegram + 浏览器
sequenceDiagram
participant Agent as 子机 Agent
participant API as 中心 POST /api/agent/heartbeat
participant Redis as Redis
participant TG as Telegram
participant WS as WebSocket 服务
participant Dash as 浏览器仪表盘
Agent->>API: 心跳 system_info
API->>Redis: 写 heartbeat:{id}
alt CPU/内存/磁盘 超阈值
API->>TG: 发消息(5分钟同机同指标防抖)
API->>WS: broadcast alert JSON
WS->>Dash: 推送 type=alert
Dash->>Dash: 仅 loadDashboard() ①
Note over Dash: 更新「告警中」数字
end
图 3 — 浏览器三种「刷新」方式
flowchart LR
subgraph triggers [谁在触发刷新]
T30[每 30 秒定时器]
BTN[点「刷新」按钮]
WS[收到 /ws/alerts 消息]
end
subgraph actions [执行哪些请求]
D[loadDashboard ①]
S[loadSyncs ②]
end
T30 --> D
T30 --> S
BTN --> D
BTN --> S
WS --> D
style WS fill:#1e3a5f
style D fill:#1e3a5f
说明:只有 30 秒定时器和「刷新」会同时做 ①+②;告警 WS 只做 ①。
图 4 — 改前 vs 改后(第 1 项)
flowchart TB
subgraph before [改前:收到一条 WS]
B1[loadDashboard ①]
B2[loadSyncs ②]
B3[弹告警列表 + 声音 + 标题闪]
WS1[WS 消息] --> B1
WS1 --> B2
WS1 --> B3
end
subgraph after [改后:收到一条 WS]
A1[loadDashboard ①]
WS2[WS 消息] --> A1
Note2[Telegram 负责通知]
Note3[页面只显示状态数字]
end
第 5 项(已定)
| 角色 | 职责 |
|---|---|
中心 server/api/agent.py |
唯一判定告警/恢复/Telegram/WS;阈值来自 settings(可 MySQL 覆盖) |
子机 web/agent/agent.py |
不判告警、不推 Telegram;仅用 相同 > 阈值 决定「是否加急发心跳」(避免指标略高但变化<10% 时不上报) |
| 子机配置 | config.json → alert_thresholds(默认 80/80/80,需与中心 settings 手动一致) |
已移除:子机 10 次连续采样、disk 90% 硬编码、无用的 payload.alert 字段。
后续(可选)
- 中心改阈值后,子机
alert_thresholds需运维同步(暂无自动下发)