From e549450a66b5c16ce61b773d85d229d9de5c42f6 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 22 Jun 2026 04:01:48 +0000 Subject: [PATCH] fix(observability): keep probe and otel summaries bounded --- scripts/src/hwlab-node-impl.ts | 24 +++++++++-------- scripts/src/platform-infra-observability.ts | 29 ++++++++++++++++++--- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/scripts/src/hwlab-node-impl.ts b/scripts/src/hwlab-node-impl.ts index b4e66c54..e551f834 100644 --- a/scripts/src/hwlab-node-impl.ts +++ b/scripts/src/hwlab-node-impl.ts @@ -7601,6 +7601,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec "const tail = (text, limit = 1200) => String(text || '').slice(-limit);", "const takeHead = (value, limit) => Array.isArray(value) ? value.slice(0, limit) : [];", "const takeTail = (value, limit) => Array.isArray(value) ? value.slice(-limit) : [];", + "const firstArray = (...values) => { for (const value of values) if (Array.isArray(value)) return value; return []; };", "const clip = (value, limit = 160) => value === null || value === undefined ? null : String(value).slice(0, limit);", "const stdoutJson = readJson(stdoutPath);", "const reportJson = readJson(reportJsonPath);", @@ -7624,7 +7625,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec " roundItems: takeTail(srcMetrics.roundItems, 8).map(slimRound),", " rounds: Array.isArray(srcMetrics.rounds) ? takeTail(srcMetrics.rounds, 8).map(slimRound) : srcMetrics.rounds,", " turnColumns: takeTail(srcMetrics.turnColumns, 8).map(slimTurnColumn),", - " turnTimingRows: srcMetrics.turnTimingRows ?? null,", + " turnTimingRows: Array.isArray(srcMetrics.turnTimingRows) ? srcMetrics.turnTimingRows.length : (srcMetrics.turnTimingRows ?? null),", " turnTimingNonMonotonicCount: srcMetrics.turnTimingNonMonotonicCount ?? null,", " turnTimingTotalElapsedDecreaseCount: srcMetrics.turnTimingTotalElapsedDecreaseCount ?? null,", " turnTimingTerminalElapsedGrowthCount: srcMetrics.turnTimingTerminalElapsedGrowthCount ?? null,", @@ -7644,7 +7645,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec "const srcPromptNetwork = objectOrNull(source?.promptNetwork);", "const promptNetwork = srcPromptNetwork ? { promptSegments: srcPromptNetwork.promptSegments ?? null } : null;", "const compact = source ? {", - " ok: analyzerExit === 0 && source.ok !== false,", + " ok: analyzerExit === 0,", " counts: source.counts ?? null,", " analysisWindow: objectOrNull(source.analysisWindow),", " archiveSummary: objectOrNull(source.archiveSummary),", @@ -7653,15 +7654,16 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec " pagePerformance,", " promptNetwork,", " pagePerformanceSlowApi: takeHead(sourceSlowApi, 4).map(slimSlowApi),", - " findings: takeHead(source.findings, 6).map(slimFinding),", - " httpErrorGroups: takeHead(source.httpErrorGroups, 4).map(slimNetworkGroup),", - " requestFailedGroups: takeHead(source.requestFailedGroups, 5).map(slimNetworkGroup),", - " domDiagnosticGroups: takeHead(source.domDiagnosticGroups, 3).map(slimDomGroup),", - " domDiagnosticSamples: takeHead(source.domDiagnosticSamples, 5).map(slimDomSample),", - " consoleAlertGroups: takeHead(source.consoleAlertGroups, 5).map(slimConsoleGroup),", - " consoleAlertSamples: takeHead(source.consoleAlertSamples, 5).map(slimConsoleSample),", - " runnerErrors: takeTail(source.runnerErrors, 8).map(slimRunnerError),", - " turnTimingRecentUpdateJumps: takeHead(source.turnTimingRecentUpdateJumps, 5).map(slimJump),", + " findings: takeHead(firstArray(source.findings, fullSource?.findings), 6).map(slimFinding),", + " httpErrorGroups: takeHead(firstArray(source.httpErrorGroups, fullSource?.httpErrorGroups), 4).map(slimNetworkGroup),", + " requestFailedGroups: takeHead(firstArray(source.requestFailedGroups, fullSource?.requestFailedGroups), 5).map(slimNetworkGroup),", + " domDiagnosticGroups: takeHead(firstArray(source.domDiagnosticGroups, fullSource?.domDiagnosticGroups), 3).map(slimDomGroup),", + " domDiagnosticSamples: takeHead(firstArray(source.domDiagnosticSamples, fullSource?.domDiagnosticSamples), 5).map(slimDomSample),", + " consoleAlertGroups: takeHead(firstArray(source.consoleAlertGroups, fullSource?.consoleAlertGroups), 5).map(slimConsoleGroup),", + " consoleAlertSamples: takeHead(firstArray(source.consoleAlertSamples, fullSource?.consoleAlertSamples), 5).map(slimConsoleSample),", + " runnerErrors: takeTail(firstArray(source.runnerErrors, fullSource?.runnerErrors), 8).map(slimRunnerError),", + " turnTimingRecentUpdateJumps: takeHead(firstArray(source.turnTimingRecentUpdateJumps, srcMetrics?.turnTimingRecentUpdateJumps, fullSource?.turnTimingRecentUpdateJumps), 5).map(slimJump),", + " turnTimingElapsedZeroResets: takeHead(firstArray(source.turnTimingElapsedZeroResets, srcMetrics?.turnTimingElapsedZeroResets, fullSource?.turnTimingElapsedZeroResets), 5).map(slimJump),", " reportJsonPath: source.reportJsonPath || reportJsonPath,", " reportJsonSha256: source.reportJsonSha256 || sha256(reportJsonPath),", " reportMdPath: source.reportMdPath || reportMdPath,", diff --git a/scripts/src/platform-infra-observability.ts b/scripts/src/platform-infra-observability.ts index 3d0aadc8..db676555 100644 --- a/scripts/src/platform-infra-observability.ts +++ b/scripts/src/platform-infra-observability.ts @@ -750,9 +750,10 @@ async function search(config: UniDeskConfig, options: SearchOptions): Promise 0 ? `{ ${filters.join(" && ")} }` : null; } function businessTraceIdFromSearchText(value: string | null): string | null { @@ -827,7 +828,7 @@ function renderTraceTable(input: { return [ shortenEnd(textValue(span.name), 48), shortenEnd(textValue(span.service), 28), - spanDetail(span, 140), + spanDetail(span, 360), ]; }); const countRows = asArray(input.result.spanNameCounts).slice(0, 8).map((item) => { @@ -1039,6 +1040,7 @@ function uniqueSpanRecords(values: unknown[]): Record[] { function spanDetail(span: Record, maxLength: number): string { const attrs = asPlainRecord(span.attributes); const parts = [ + valuePart("durationMs", span.durationMs), attrPart(attrs, "failureKind"), attrPart(attrs, "errorSummary"), attrPart(attrs, "error.message"), @@ -1059,11 +1061,30 @@ function spanDetail(span: Record, maxLength: number): string { attrPart(attrs, "commandFingerprint"), attrPart(attrs, "http.route"), attrPart(attrs, "http.response.status_code"), + attrPart(attrs, "db.system"), + attrPart(attrs, "db.operation.name"), + attrPart(attrs, "db.sql.table"), + attrPart(attrs, "db.query.arg_count"), + attrPart(attrs, "db.index.expected"), + attrPart(attrs, "db.pool.max_open"), + attrPart(attrs, "db.pool.open_connections"), + attrPart(attrs, "db.pool.in_use"), + attrPart(attrs, "db.pool.idle"), + attrPart(attrs, "db.pool.wait_count"), + attrPart(attrs, "db.pool.wait_duration_ms"), + attrPart(attrs, "error.code"), + attrPart(attrs, "error.category"), + attrPart(attrs, "error.layer"), ].filter((item) => item !== null) as string[]; if (parts.length === 0) return "-"; return shortenEnd(parts.join(" "), maxLength); } +function valuePart(key: string, value: unknown): string | null { + if (value === null || value === undefined || value === "") return null; + return `${key}=${textValue(value)}`; +} + function attrPart(attrs: Record | null, key: string): string | null { if (attrs === null) return null; const value = attrs[key];