Skip to content

feat(live-pulse): 实时脉搏状态条#195

Merged
g1331 merged 12 commits into
masterfrom
feat/live-pulse-bar
May 30, 2026
Merged

feat(live-pulse): 实时脉搏状态条#195
g1331 merged 12 commits into
masterfrom
feat/live-pulse-bar

Conversation

@g1331
Copy link
Copy Markdown
Owner

@g1331 g1331 commented May 30, 2026

@

Summary

在所有管理页常驻一条秒级实时运行状态条(实时脉搏),复用现有进程内发布订阅 + SSE + 三态降级链路。指标为网关增强版:滚动 60 秒窗口的 req/min、错误率、平均延迟、TPM,外加 AutoRouter 作为多上游网关独有的「健康上游数/总数」与「熔断打开数」。

OpenSpec 变更:openspec/changes/live-pulse-bar/

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Tests (adding or updating tests)

Changes

  • 新增滚动窗口聚合器 live-pulse-aggregator.ts:按秒分桶维护最近 60 秒窗口,换算 req/min、错误率(非 2xx 占比)、平均延迟(仅成功请求)、TPM;读写时剔除窗口外样本。
  • 取样接入 request-logger.ts 的请求收口路径(updateRequestLog 设置终态状态码、logRequest 一次性终态),进行中创建不计入。
  • 新增快照拼装服务 live-pulse-service.ts:合并窗口指标与 getAllHealthStatusWithCircuitBreaker 得到的健康/熔断信号(打开、半开不计为关闭);为网关健康加 2 秒共享缓存,避免多页常驻连接放大数据库读取。
  • 新增 SSE 端点 /api/admin/stats/live:管理员鉴权后默认推送 live-pulse 快照(连接即一帧、其后每 2 秒一帧、15 秒心跳、断开清理);?mode=snapshot 返回一次性 JSON 供降级拉取;未授权返回 401 不泄露指标。
  • 前端 use-live-pulse 钩子(SSE 三态 + 断线降级轮询)与 live-pulse-provider,在仪表盘布局层建立单条共享连接,避免逐页重连。
  • 展示组件 live-pulse-bar(完整版/紧凑版,在线指示灯按三态着色,错误率与熔断打开按既有强调样式提示,数字跟随 next-intl 当前语言)。顶栏右侧承载;移动端将返回头部与脉搏合并为单条常驻顶栏。
  • 新增 livePulse 中英文文案。

Test Plan

  • Local tests pass (pnpm test:run) — 151 文件 2507 passed / 1 skipped
  • Type check passes (pnpm exec tsc --noEmit)
  • Lint passes(eslint 通过;pnpm build 成功,新端点已编译)
  • Manual testing completed

Checklist

  • Code follows the project's coding standards
  • Tests have been added where necessary
  • Documentation has been updated (if applicable) — OpenSpec 变更工件
    @

g1331 added 8 commits May 30, 2026 11:05
实时脉搏状态条:在所有管理页顶栏常驻一条秒级运行状态条,
复用既有进程内 pub/sub + SSE + 三态降级链路。指标为网关增强版
(滚动 60 秒 req/min、错误率、平均延迟、TPM,外加健康上游数/总数
与熔断打开数)。含 proposal/design/specs/tasks 四件工件。
按秒分桶维护最近 60 秒滚动窗口,导出 recordPulseSample 与
getPulseWindowSnapshot,换算 req/min、错误率(非 2xx 占比)、
平均延迟(仅成功请求)、TPM;读写时剔除窗口外样本。含单元测试。
在 request-logger 的请求收口路径(updateRequestLog 设置终态状态码、
logRequest 一次性终态)取样,进行中创建不计入。新增 live-pulse-service:
合并滚动窗口快照与 getAllHealthStatusWithCircuitBreaker 得到的健康上游数/
总数与熔断打开数,产出 LivePulseSnapshot;打开/半开不计为关闭。含单元测试。
新增 /api/admin/stats/live:管理员鉴权后默认以 SSE 推送 live-pulse
快照(连接即一帧、其后每 2 秒一帧、15 秒心跳、断开清理);?mode=snapshot
返回一次性 JSON 快照供前端降级拉取;未授权返回 401 不泄露指标。
拼装快照时为网关健康加 2 秒共享缓存,避免多页常驻连接放大数据库读取。
新增 use-live-pulse 钩子(SSE 三态 + 断线降级轮询)与 live-pulse-provider,
在仪表盘布局层建立单条共享连接,避免逐页重连。新增 live-pulse-bar 展示组件
(完整版 / 紧凑版,在线指示灯按三态着色,错误率与熔断打开按既有强调样式提示,
数字跟随 next-intl 当前语言)。顶栏右侧承载状态条,移动端以紧凑窄条常驻。
补充 livePulse 中英文文案与组件单元测试。
将移动端返回头部与脉搏窄条合并为同一条 sticky 顶栏(左返回按钮按需显示、
右侧紧凑脉搏),避免两个 sticky top-0 叠加;所有移动端管理页常驻可见在线
指示与 req/min、错误率,不挤压标题与导航。
为 dashboard-layout 测试补 next-intl useFormatter mock(布局现含脉搏条)。
完整 vitest 151 文件 2507 passed / 1 skipped,next build 成功,
openspec validate --strict 通过。
分支已推送、PR #195 已开启,按仓库习惯不自行合并。
@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

❌ Patch coverage is 68.22917% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.01%. Comparing base (b171d02) to head (f8ac1e6).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #195      +/-   ##
==========================================
- Coverage   74.09%   74.01%   -0.09%     
==========================================
  Files         147      152       +5     
  Lines       11115    11307     +192     
  Branches     3847     3896      +49     
==========================================
+ Hits         8236     8369     +133     
- Misses       1677     1723      +46     
- Partials     1202     1215      +13     
Flag Coverage Δ
verify 74.01% <68.22%> (-0.09%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

g1331 added 4 commits May 30, 2026 11:51
实时脉搏条做进仪表盘布局后,每个仪表盘页都会打开 /api/admin/stats/live。
两个纯 mock 的 E2E(logs 路由诊断、billing 分级)原先只 mock 了 logs 接口,
新连接会打到真实 dev 服务器并保持长连接,dev 模式下首次还要现编译该路由,
给单测试服务器增加负载与主线程抖动,偶发把日志页交互拖到超时。

按既有逐 spec mock 习惯,为两个 spec 各加 mockLivePulse 并在 beforeEach 注册,
将 stats/live(SSE 与 ?mode=snapshot 降级)统一以零值快照 fulfill,使测试与
真实服务器隔离。
中等:
- 取样以请求 createdAt(真实发生时间)作为窗口时间戳,使陈旧请求 reconcile
  收口(statusCode 520)落在 60 秒窗口外被剔除,不再污染当前 req/min 与错误率。
- 新增 /api/admin/stats/live 路由鉴权单元测试:无凭据/无效凭据返回 401 且不
  泄露指标,合法 ?mode=snapshot 返回 200 快照。

低/nit:
- 网关健康查询失败时以短 TTL 缓存零值,避免 DB 故障期间每连接重复打库(含测试)。
- 聚合器补「恰好 60 秒边界样本应保留」用例。
- 顶栏标题加 min-w-0/truncate、脉搏条加 shrink-0,修 md 断点挤压。
- 错误率超阈值除红色外增加警示图标与字重,避免仅靠颜色传达(a11y)。
- connecting 指示灯改用灰色,与设计稿一致。
- connecting 状态使用专属 tooltip 文案,不再误用"实时接收中"。
- 降级轮询在 await response.json() 后重新校验 cancelled。
- 错误率与平均延迟改用 next-intl format.number,与其他指标格式化方式一致。
将实时脉搏条从顶栏右侧改为水平居中,贴合参照设计。桌面与移动端顶栏
均改用三栏网格(左标题/返回、中脉搏、右留白配平),标题过长时截断,
脉搏条始终保持在正中。
实现完成并通过审查与全量校验,归档变更并将 delta spec 同步到主 specs。
@g1331 g1331 merged commit 972265e into master May 30, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant