feat: add v02 web performance dashboard

This commit is contained in:
Codex Agent
2026-06-05 12:00:16 +08:00
parent 69385290d6
commit f5be1c0361
15 changed files with 461 additions and 8 deletions
+29
View File
@@ -24,6 +24,29 @@ test("web performance store aggregates browser-perceived durations as Prometheus
assert.doesNotMatch(text, /trc_secret|sessionId|conversationId|threadId|prompt|api key/iu);
});
test("web performance summary exposes user-perceived route latency without high-cardinality data", () => {
const store = createWebPerformanceStore({ env: { HWLAB_METRICS_NAMESPACE: "hwlab-v02", HWLAB_GITOPS_TARGET: "v02" } });
store.record({
schemaVersion: "hwlab-web-performance-v1",
page: "/workspace",
events: [
{ kind: "api", metric: "api_request", route: "/v1/agent/chat/result/trc_secret", method: "GET", status: 200, statusClass: "2xx", outcome: "ok", valueMs: 420 },
{ kind: "api", metric: "api_request", route: "/v1/agent/chat/result/trc_secret", method: "GET", status: 0, statusClass: "network", outcome: "timeout", valueMs: 2600 },
{ kind: "long_task", metric: "long_task", route: "/workspace", valueMs: 260 },
{ kind: "web_vital", metric: "lcp", route: "/workspace", valueMs: 3100 }
]
});
const summary = store.summary();
const json = JSON.stringify(summary);
assert.equal(summary.summary.sampleCount, 4);
assert.equal(summary.namespace, "hwlab-v02");
assert.ok(summary.apiRoutes.some((row) => row.route === "/v1/agent/chat/result/:id" && row.metric === "api_request" && row.p95 >= 2.5));
assert.ok(summary.problems.some((row) => row.problem === "timeout" && row.tone === "blocked"));
assert.ok(summary.longTasks.some((row) => row.metric === "long_task" && row.problem === "slow-long_task" && row.tone !== "ok"));
assert.doesNotMatch(json, /trc_secret|sessionId|conversationId|threadId|prompt|api key/iu);
});
test("web performance route templates keep metrics low-cardinality", () => {
assert.equal(webPerformanceRouteTemplate("/v1/workbench/workspace/cnv_abcdef/select-conversation?traceId=trc_secret"), "/v1/workbench/workspace/:id/select-conversation");
assert.equal(webPerformanceRouteTemplate("#/skills"), "/skills");
@@ -53,6 +76,12 @@ test("cloud api ingests WebUI performance samples and exposes metrics only on lo
const publicHost = await fetch(`${baseUrl}/v1/web-performance/metrics`, { headers: { host: "74.48.78.17:19667" } });
assert.equal(publicHost.status, 404);
const summary = await fetch(`${baseUrl}/v1/web-performance/summary`);
const body = await summary.json();
assert.equal(summary.status, 200);
assert.equal(body.route, "/v1/web-performance/summary");
assert.equal(body.summary.sampleCount, 1);
} finally {
await new Promise<void>((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
}