Files

85 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
实现 Gateway 健康监控(P0-1)。后端 Hermes CLI 封装 + API + 前端页面。
## 第一部分: Hermes CLI 服务(真实数据源)
创建 backend/app/services/hermes_cli.py:
- 封装 `hermes gateway status` CLI 调用
- 用 subprocess.run 执行,解析 JSON 输出
- 出错时返回空数据 + 日志告警,不抛异常
- 函数: gateway_status_all() -> list[GatewayInfo]
- 数据类型: id, name, status(online/offline/warn), downtime_minutes, restarts_today, last_event
## 第二部分: Gateway API
创建 backend/app/api/gateway.py,全部 require_auth
### GET /api/v1/gateway/status
返回全部 Profile 的 Gateway 状态列表,支持:
- query param `?status=online|offline|warn` 筛选
- 每行: name, status(🟢/🔴/🟡), downtime, restarts_today, last_event, profile_type
- 数据来源: hermes_cli.gateway_status_all()
### GET /api/v1/gateway/events
返回最近 24h 异常事件:
```json
[
{"time": "2026-07-22T18:45", "profile": "monitor", "type": "heartbeat_timeout", "detail": "连续 3 次心跳无响应"},
{"time": "2026-07-22T14:20", "profile": "feishu-gw", "type": "feishu_disconnect", "detail": "WebSocket 断开 8 分钟"},
{"time": "2026-07-22T10:30", "profile": "gateway-monitor", "type": "restart", "detail": "Gateway 重启"}
]
```
数据来源: hermes CLI 日志或系统日志解析。暂用占位数据(TODO 标注)。
### POST /api/v1/gateway/{profile}/start, /stop, /restart
Gateway 启停操作:
- 执行 `hermes gateway start/stop/restart --profile {profile}`
- 需要 operator 或 owner 角色(require_role("owner","operator"))
- 返回操作结果 + 写入审计日志
- 操作前二次确认(前端处理)
## 第三部分: 前端 Gateway 页面
修改 frontend/src/pages/GatewayPage.tsx:
### 顶部: 异常事件时间线
- Timeline 组件,24h 横向展示
- 事件类型: 🔴心跳超时 🟠飞书断连 🔵Gateway 重启
- Hover 显示详情 tooltip
### 筛选栏
- 状态筛选: 全部/在线/离线/异常
- 蜂型筛选: 全部/工蜂/蜂王
- 筛选器即时生效(前端过滤,不重新请求)
### 状态表
- Table 组件,10s 轮询 (usePolling hook)
- 列: Profile 名, 状态 Badge, 掉线时长, 今日重启, 最近异常, 操作
- 异常行标红: Gateway 连续重启≥3次 或 掉线≥30分钟
- 操作按钮: 启动/停止/重启 (二次确认 Modal)
### 四态覆盖
- Loading: Skeleton (table 形状)
- Empty: "全部 Gateway 正常运行 🎉"
- Error: 错误 + 重试
- Normal: 数据展示
### usePolling hook
创建 frontend/src/hooks/usePolling.ts:
```typescript
import { useEffect, useRef } from 'react'
export function usePolling(callback: () => void, intervalMs: number, enabled: boolean = true) {
const savedCallback = useRef(callback)
useEffect(() => { savedCallback.current = callback }, [callback])
useEffect(() => {
if (!enabled) return
savedCallback.current() // 立即执行一次
const id = setInterval(() => savedCallback.current(), intervalMs)
return () => clearInterval(id)
}, [intervalMs, enabled])
}
```
注册路由: main.py 添加 `from app.api import gateway; app.include_router(gateway.router, prefix="/api/v1")`
完成后提交。