166 lines
4.6 KiB
Markdown
166 lines
4.6 KiB
Markdown
# 告警推送策略(产品决策)
|
||
|
||
**状态**: ✅ 已实现(2026-05-22)
|
||
|
||
## 通道分工
|
||
|
||
| 通道 | 职责 | 实现 |
|
||
|------|------|------|
|
||
| **Telegram** | 主动通知(告警/恢复/系统) | `send_telegram_*`;同机同指标 **5 分钟** 防抖 |
|
||
| **浏览器 Dashboard** | 仅展示汇总状态 | 统计卡「告警中」+「运行状态」文案;**无声音、无实时告警列表** |
|
||
| **WebSocket `/ws/alerts`** | 触发仪表盘刷新 | 收到事件后 `loadDashboard()`;不弹窗、不响铃 |
|
||
|
||
## 第 1 项(已定)
|
||
|
||
- 浏览器:**不需要声音**,不需要逐条告警横幅。
|
||
- 通知:**以 Telegram 为准**。
|
||
- 浏览器:只看 **在线/离线/告警台数** 等状态(`/servers/stats` + Redis `alerts:*` 计数)。
|
||
|
||
## 第 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 — 改后运行时(定稿)
|
||
|
||
```mermaid
|
||
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 — 仪表盘上的两块数据(互不替代)
|
||
|
||
```mermaid
|
||
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 + 浏览器
|
||
|
||
```mermaid
|
||
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 — 浏览器三种「刷新」方式
|
||
|
||
```mermaid
|
||
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 项)
|
||
|
||
```mermaid
|
||
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` 需运维同步(暂无自动下发)
|