fix: DevTools 仪表盘平均请求延迟显示进程运行时间而非实际请求耗时
- performance.js: 新增 recordLatency/getAverageLatency, 用 HTTP 请求环缓冲区替换 pidusage elapsed - index.js: 新增 Express 中间件追踪每个请求耗时 - index.html: 移除前端 elapsed-based fallback 计算 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1286,15 +1286,8 @@ async function updatePerformanceDashboard(perfData) {
|
||||
const cpuLevel = avgCpu > 80 ? 'cpu-high' : avgCpu > 50 ? 'cpu-mid' : 'cpu-low';
|
||||
const memLevel = totalMem > 1024 ? 'mem-high' : totalMem > 512 ? 'mem-mid' : 'mem-low';
|
||||
|
||||
// 计算平均延迟 (基于活跃连接和服务数估算,或使用 perf 数据中的 elapsed)
|
||||
// 计算平均延迟 (从 API 获取实际请求耗时)
|
||||
let avgLatency = '—';
|
||||
let totalElapsed = 0, elapsedCount = 0;
|
||||
for (const [, p] of entries) {
|
||||
if (p.elapsed && p.elapsed > 0) { totalElapsed += p.elapsed; elapsedCount++; }
|
||||
}
|
||||
if (elapsedCount > 0) {
|
||||
avgLatency = Math.round(totalElapsed / elapsedCount) + 'ms';
|
||||
}
|
||||
|
||||
// 获取趋势数据 (从性能仪表盘 API)
|
||||
let trendCpu = '→', trendMem = '→';
|
||||
|
||||
@@ -33,6 +33,15 @@ const __dirname = path.dirname(__filename);
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
// 请求延时追踪 — 记录每个 HTTP 请求的实际耗时
|
||||
app.use((req, res, next) => {
|
||||
const start = Date.now();
|
||||
res.on('finish', () => {
|
||||
performanceMonitor.recordLatency(Date.now() - start);
|
||||
});
|
||||
next();
|
||||
});
|
||||
|
||||
// 静态文件 - Web控制台
|
||||
app.use(express.static(path.join(__dirname, '../public')));
|
||||
|
||||
|
||||
@@ -13,11 +13,30 @@ class PerformanceMonitor {
|
||||
this.history = new Map();
|
||||
this.interval = null;
|
||||
|
||||
// Ring buffer for actual HTTP request latencies (ms)
|
||||
this.latencyBuffer = [];
|
||||
this.maxLatencySamples = 500;
|
||||
|
||||
for (const id of Object.keys(SERVICES)) {
|
||||
this.history.set(id, []);
|
||||
}
|
||||
}
|
||||
|
||||
/** Record an HTTP request duration (ms). Called by middleware. */
|
||||
recordLatency(durationMs) {
|
||||
this.latencyBuffer.push(durationMs);
|
||||
if (this.latencyBuffer.length > this.maxLatencySamples) {
|
||||
this.latencyBuffer.splice(0, this.latencyBuffer.length - this.maxLatencySamples);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get average request latency from recent samples. Returns null if no data. */
|
||||
getAverageLatency() {
|
||||
if (this.latencyBuffer.length === 0) return null;
|
||||
const sum = this.latencyBuffer.reduce((a, b) => a + b, 0);
|
||||
return Math.round(sum / this.latencyBuffer.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始定期采样 (每3秒)
|
||||
*/
|
||||
@@ -123,15 +142,8 @@ class PerformanceMonitor {
|
||||
const avgCpu = entries.length > 0 ? Math.round(totalCpu / entries.length * 10) / 10 : 0;
|
||||
const totalMemRounded = Math.round(totalMem * 100) / 100;
|
||||
|
||||
// 计算平均延迟 (基于各服务进程的 elapsed 时间)
|
||||
let avgLatencyMs = null;
|
||||
let totalElapsed = 0, elapsedCount = 0;
|
||||
for (const [, p] of entries) {
|
||||
if (p.elapsed && p.elapsed > 0) { totalElapsed += p.elapsed; elapsedCount++; }
|
||||
}
|
||||
if (elapsedCount > 0) {
|
||||
avgLatencyMs = Math.round(totalElapsed / elapsedCount);
|
||||
}
|
||||
// 计算平均请求延迟 (基于实际 HTTP 请求耗时,非进程 uptime)
|
||||
const avgLatencyMs = this.getAverageLatency();
|
||||
|
||||
// 获取最近历史用于趋势判断
|
||||
const recentHistory = this.getAllHistory();
|
||||
|
||||
@@ -37,3 +37,7 @@
|
||||
- [Phase 2 - 人格与交互深化](2026-05-23-phase2-personality-interaction.md) — 情感状态机 + 主动消息决策增强 + 离线自主思考 (16 文件)
|
||||
- [Phase 3 - 插件与工具系统](2026-05-23-phase3-plugin-tool-system.md) — Plugin SDK + Plugin Manager + 13 内置插件 + 工具分级 (40 文件)
|
||||
- [Phase 4 - 多平台接入](2026-05-23-phase4-multi-platform.md) — 统一消息模型 + QQ/Telegram/Webhook 适配器 + 身份权限系统 (18 文件)
|
||||
|
||||
## 2026-05-24
|
||||
|
||||
- [Phase 6 - 多模型配置系统 + 视觉集成](2026-05-24-phase6-model-config-vision.md) — ModelSelector 路由 + LLM 调用日志 + Vision/OCR 集成 + Bug 修复 (9 文件)
|
||||
|
||||
Reference in New Issue
Block a user