feat(monitor): F4 自定义监控仪表盘 — mock 桩改真实 CRUD + PromQL 查询渲染
后端: - 新增 model/custom_dashboard.go (monitor_custom_dashboards 表) - 新增 controller/custom_dashboard.go (CRUD + 设默认, 6 路由) - routes.go 注册 /custom-dashboards 路由组 - database.go AutoMigrate 注册 CustomDashboard 前端: - grafana.ts: dashboardApi 从 mock 返回空改为真实 HTTP 调用 - metrics.ts: prometheusProxyApi 新增 query/queryRange 方法 - GrafanaPanelContent.tsx: 从随机 mock 数据改为执行 PromQL 查询 + Recharts LineChart 渲染 graph 类型 + SVG gauge 渲染 gauge 类型 + 数值卡片渲染 stat 类型 + 表格渲染 table 类型 + 30s 自动刷新 + loading/error 状态 + 自动发现默认 Prometheus 数据源 - GrafanaDashboard.tsx: 传递 datasourceUrl 到 GrafanaPanelContent 验证: go build✅ npm build✅ 17/17 集成测试通过 E2E CRUD 全通过
This commit is contained in:
1 parent
7af10097c9
commit
f725ca7cac
11 files changed
+670
-53
No files matched your search
+70
@@ -450,6 +450,76 @@ grep -r 'kubernetes-clusters/.*\(pods\|deployments\|services\|ingresses\|nodes\|
|
||||
|
||||
---
|
||||
|
||||
## P1-F4: 自定义监控仪表盘
|
||||
|
||||
### 验证用例
|
||||
|
||||
```bash
|
||||
TOKEN=$(python3 -c "
|
||||
import urllib.request, json
|
||||
login_data = json.dumps({'username': 'admin', 'password': '123456'}).encode()
|
||||
req = urllib.request.Request('http://127.0.0.1:8080/api/v1/auth/login', data=login_data, method='POST')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
resp = urllib.request.urlopen(req)
|
||||
print(json.loads(resp.read())['data']['token'])
|
||||
")
|
||||
|
||||
# U1: 创建仪表盘
|
||||
curl -s -X POST "http://127.0.0.1:8080/api/v1/custom-dashboards" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"测试","panels":"[]","is_default":true}' | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['code']==200; print('✅ create')"
|
||||
# 期望: code=200
|
||||
|
||||
# U2: 列表
|
||||
curl -s "http://127.0.0.1:8080/api/v1/custom-dashboards" \
|
||||
-H "Authorization: Bearer $TOKEN" | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['data']['total']>=1; print('✅ list')"
|
||||
# 期望: total >= 1
|
||||
|
||||
# U3: 更新(添加面板)
|
||||
DASH_ID=$(curl -s "http://127.0.0.1:8080/api/v1/custom-dashboards" -H "Authorization: Bearer $TOKEN" | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['list'][0]['id'])")
|
||||
curl -s -X PUT "http://127.0.0.1:8080/api/v1/custom-dashboards/$DASH_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
||||
-d '{"panels":"[{\"id\":\"1\",\"title\":\"CPU\",\"type\":\"graph\",\"query\":\"up\",\"width\":6,\"height\":4}]"}' | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['code']==200; print('✅ update')"
|
||||
|
||||
# U4: 删除
|
||||
curl -s -X DELETE "http://127.0.0.1:8080/api/v1/custom-dashboards/$DASH_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['code']==200; print('✅ delete')"
|
||||
|
||||
# U5: 前端 dashboardApi 不再是 mock
|
||||
grep -c 'http.get\|http.post\|http.put\|http.delete' /srv/aiops/frontend/src/api/monitor/grafana.ts
|
||||
# 期望: >= 5 (真实 HTTP 调用)
|
||||
|
||||
# U6: GrafanaPanelContent 使用 prometheusProxyApi(非 mock)
|
||||
grep -c 'prometheusProxyApi' /srv/aiops/frontend/src/components/monitor/dashboard/GrafanaPanelContent.tsx
|
||||
# 期望: >= 2
|
||||
|
||||
# U7: go build
|
||||
cd /srv/aiops/backend && go build ./...
|
||||
# 期望: 零错误
|
||||
|
||||
# U8: npm build
|
||||
cd /srv/aiops/frontend && npm run build 2>&1 | tail -1
|
||||
# 期望: built in Ns
|
||||
|
||||
# U9: 集成回归
|
||||
python3 tests/integration_test.py --host 127.0.0.1 --port 8080 | tail -3
|
||||
# 期望: 17/17 passed
|
||||
```
|
||||
|
||||
### 通过标准
|
||||
- [x] U1: 创建仪表盘返回 200
|
||||
- [x] U2: 列表包含创建的仪表盘
|
||||
- [x] U3: 更新仪表盘(添加面板)成功
|
||||
- [x] U4: 删除仪表盘成功
|
||||
- [x] U5: `dashboardApi` 全部方法为真实 HTTP 调用(非 mock 返回空)
|
||||
- [x] U6: `GrafanaPanelContent` 使用 `prometheusProxyApi.query` / `queryRange` 执行 PromQL
|
||||
- [x] U7: `go build` 零错误
|
||||
- [x] U8: `npm run build` 零错误(✓ built in 18.01s)
|
||||
- [x] U9: 17/17 集成回归测试通过
|
||||
|
||||
---
|
||||
|
||||
## 回归测试基线(每次改动后必跑)
|
||||
|
||||
```bash
|
||||
|
||||
Reference in new issue
Block a user