feat: expose performance collection health (#1671)

This commit is contained in:
Lyon
2026-06-20 09:03:17 +08:00
committed by GitHub
parent 66c5f52939
commit e0127f1044
7 changed files with 524 additions and 13 deletions
+37
View File
@@ -44,7 +44,12 @@ test("web performance summary exposes user-perceived route latency without high-
const json = JSON.stringify(summary);
assert.equal(summary.summary.sampleCount, 4);
assert.equal(summary.namespace, "hwlab-v02");
assert.equal(summary.collectionHealth.schemaVersion, "hwlab-web-performance-collection-health-v1");
assert.equal(summary.collectionHealth.status, "low-sample");
assert.equal(summary.collectionHealth.reason, "low_sample_window");
assert.ok(summary.collectionHealth.diagnostics.some((item) => item.code === "low_sample_window"));
assert.equal(summary.dashboard.schemaVersion, "hwlab-web-performance-dashboard-v1");
assert.equal(summary.dashboard.collectionHealth.status, "low-sample");
assert.ok(summary.dashboard.cards.some((card) => card.id === "samples" && card.value === 4));
assert.ok(summary.dashboard.trends.some((trend) => trend.id === "api-timing" && trend.points.length > 0));
assert.ok(summary.dashboard.topN.some((group) => group.id === "top-api" && group.rows.length > 0));
@@ -55,6 +60,36 @@ test("web performance summary exposes user-perceived route latency without high-
assert.doesNotMatch(json, /trc_secret|sessionId|conversationId|threadId|prompt|api key/iu);
});
test("web performance summary explains empty recent windows when retained samples exist", () => {
let nowMs = 0;
const store = createWebPerformanceStore({
env: { HWLAB_METRICS_NAMESPACE: "hwlab-v03", HWLAB_GITOPS_TARGET: "v03" },
now: () => nowMs
});
nowMs = 1_000;
store.record({
schemaVersion: "hwlab-web-performance-v1",
page: "/workbench",
events: [{ kind: "api", metric: "api_request", route: "/v1/workbench/sessions", method: "GET", status: 200, statusClass: "2xx", outcome: "ok", valueMs: 450, traceId: "trc_old_secret" }]
} as Record<string, unknown>);
nowMs = 20 * 60 * 1000;
const recent = store.summary({ window: "5m" });
const json = JSON.stringify(recent);
assert.equal(recent.summary.sampleCount, 0);
assert.equal(recent.collectionHealth.status, "stale");
assert.equal(recent.collectionHealth.reason, "no_samples_in_window");
assert.equal(recent.collectionHealth.retainedSampleCount, 1);
assert.equal(recent.collectionHealth.lastSampleAt, null);
assert.ok(recent.collectionHealth.lastRetainedSampleAt);
assert.ok(recent.collectionHealth.diagnostics.some((item) => item.code === "no_samples_in_window"));
assert.equal(recent.dashboard.freshness.status, "stale");
assert.equal(recent.dashboard.collectionHealth.reason, "no_samples_in_window");
assert.doesNotMatch(json, /trc_old_secret|traceId|prompt|api key/iu);
});
test("web performance summary filters rows by requested recent window", () => {
let nowMs = 0;
const store = createWebPerformanceStore({
@@ -175,6 +210,8 @@ test("web performance summary exposes Workbench p75 and low-sample diagnostics w
assert.deepEqual(result, { accepted: 4, dropped: 0, received: 4 });
assert.equal(summary.summary.sampleCount, 4);
assert.equal(summary.summary.lowSampleThreshold, 5);
assert.equal(summary.collectionHealth.status, "low-sample");
assert.ok(summary.collectionHealth.sourceFamilyCounts.some((item) => item.sourceFamily === "workbench_journey"));
assert.equal(summary.dashboard.freshness.namespace, "hwlab-v03");
assert.ok(summary.dashboard.trends.some((trend) => trend.id === "workbench-experience" && trend.points.some((point) => point.label === "提交到首个可见结果")));
assert.ok(summary.dashboard.distributions.some((distribution) => distribution.id === "samples" && distribution.buckets.some((bucket) => bucket.label === "低样本")));