Merge pull request #633 from pikasTech/fix/webprobe-analyze-visibility-1811-20260621

fix: improve web-probe observe analyze visibility
This commit is contained in:
Lyon
2026-06-22 06:44:28 +08:00
committed by GitHub
2 changed files with 109 additions and 8 deletions
+60 -6
View File
@@ -7486,6 +7486,59 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
const slowApis = Array.isArray(analysis?.pagePerformanceSlowApi) ? analysis.pagePerformanceSlowApi.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const findings = Array.isArray(analysis?.findings) ? analysis.findings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const domDiagnostics = Array.isArray(analysis?.domDiagnosticGroups) ? analysis.domDiagnosticGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 5) : [];
const domDiagnosticSamples = Array.isArray(analysis?.domDiagnosticSamples) ? analysis.domDiagnosticSamples.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const consoleAlertGroups = Array.isArray(analysis?.consoleAlertGroups) ? analysis.consoleAlertGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const consoleAlertSamples = Array.isArray(analysis?.consoleAlertSamples) ? analysis.consoleAlertSamples.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const recentUpdateJumps = Array.isArray(analysis?.turnTimingRecentUpdateJumps) ? analysis.turnTimingRecentUpdateJumps.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
const domDiagnosticRows = domDiagnostics.length > 0
? domDiagnostics.map((item) => [
webObserveText(item.count),
webObserveShort(webObserveText(item.firstAt), 24),
webObserveShort(webObserveText(item.lastAt), 24),
webObserveShort(webObserveText(item.text), 96),
])
: domDiagnosticSamples.map((item) => [
webObserveText(item.seq),
webObserveShort(webObserveText(item.ts), 24),
webObserveShort([
webObserveText(item.source),
webObserveText(item.diagnosticCode),
item.traceId ? `trace=${webObserveText(item.traceId)}` : "",
item.httpStatus !== undefined && item.httpStatus !== null ? `http=${webObserveText(item.httpStatus)}` : "",
item.idleSeconds !== undefined && item.idleSeconds !== null ? `idle=${webObserveText(item.idleSeconds)}` : "",
item.waitingFor ? `waitingFor=${webObserveText(item.waitingFor)}` : "",
item.lastEventLabel ? `lastEvent=${webObserveText(item.lastEventLabel)}` : "",
].filter((part) => part !== "" && part !== "-").join(" "), 64),
webObserveShort(webObserveText(item.text), 96),
]);
const consoleAlertRows = consoleAlertGroups.length > 0
? consoleAlertGroups.map((item) => [
webObserveText(item.count),
webObserveShort(webObserveText(item.type), 14),
webObserveText(item.status),
webObserveShort(webObserveText(item.path), 52),
webObserveShort(webObserveText(item.lastAt ?? item.firstAt), 24),
webObserveShort(webObserveArray(item.traceIds).join(",") || "-", 28),
])
: consoleAlertSamples.map((item) => [
webObserveShort(webObserveText(item.ts), 24),
webObserveShort(webObserveText(item.type), 14),
webObserveText(item.status),
webObserveShort(webObserveText(item.path), 52),
webObserveShort(webObserveText(item.traceId), 28),
webObserveShort(webObserveText(item.text), 72),
]);
const recentUpdateJumpRows = recentUpdateJumps.map((item) => [
webObserveShort(webObserveText(item.columnLabel), 14),
webObserveText(item.promptIndex),
webObserveText(item.fromSeq),
webObserveText(item.toSeq),
`${webObserveText(item.fromValue)}->${webObserveText(item.toValue)}`,
webObserveText(item.delta),
webObserveText(item.sampleDeltaSeconds),
webObserveText(item.allowedIncreaseSeconds),
webObserveShort(webObserveText(item.traceId), 24),
]);
const lines = [
`hwlab nodes web-probe observe analyze (${webObserveText(value.status)})`,
"",
@@ -7549,6 +7602,9 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
webObserveShort(webObserveText(item.source), 24),
]) : [["-", "-", "-", "-", "-", "-"]]),
"",
"Recent update jumps:",
webObserveTable(["TURN", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "SAMPLE_S", "ALLOWED", "TRACE"], recentUpdateJumpRows.length > 0 ? recentUpdateJumpRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
"",
"Runtime alerts:",
webObserveTable(["HTTP_ERR", "REQUEST_FAILED", "DOM_DIAG", "CONSOLE_ALERT", "PROMPT_SEGMENTS", "PROMPT_NETWORK"], [[
webObserveText(runtimeAlerts?.httpErrorCount),
@@ -7569,12 +7625,10 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
]) : [["-", "-", "-", "-", "-"]]),
"",
"DOM diagnostics:",
webObserveTable(["COUNT", "FIRST", "LAST", "TEXT"], domDiagnostics.length > 0 ? domDiagnostics.map((item) => [
webObserveText(item.count),
webObserveShort(webObserveText(item.firstAt), 24),
webObserveShort(webObserveText(item.lastAt), 24),
webObserveShort(webObserveText(item.text), 96),
]) : [["-", "-", "-", "-"]]),
webObserveTable(domDiagnostics.length > 0 ? ["COUNT", "FIRST", "LAST", "TEXT"] : ["SEQ", "TS", "META", "TEXT"], domDiagnosticRows.length > 0 ? domDiagnosticRows : [["-", "-", "-", "-"]]),
"",
"Console alerts:",
webObserveTable(consoleAlertGroups.length > 0 ? ["COUNT", "TYPE", "STATUS", "PATH", "LAST", "TRACES"] : ["TS", "TYPE", "STATUS", "PATH", "TRACE", "TEXT"], consoleAlertRows.length > 0 ? consoleAlertRows : [["-", "-", "-", "-", "-", "-"]]),
"",
"Findings:",
webObserveTable(["KIND", "SEVERITY", "COUNT", "SUMMARY"], findings.length > 0 ? findings.map((item) => [
@@ -1167,6 +1167,53 @@ console.log(JSON.stringify({
traceIds: Array.isArray(item.traceIds) ? item.traceIds.slice(0, 4) : [],
text: String(item.preview ?? item.normalizedPreview ?? item.text ?? "").slice(0, 160),
})),
domDiagnosticSamples: runtimeAlerts.domDiagnostics.slice(-8).map((item) => ({
seq: item.seq ?? null,
ts: item.ts ?? null,
promptIndex: item.promptIndex ?? null,
source: item.source ?? null,
diagnosticCode: item.diagnosticCode ?? null,
traceId: item.traceId ?? null,
httpStatus: item.httpStatus ?? null,
idleSeconds: item.idleSeconds ?? null,
waitingFor: item.waitingFor ?? null,
lastEventLabel: item.lastEventLabel ?? null,
text: String(item.preview ?? item.text ?? "").slice(0, 180),
})),
consoleAlertGroups: runtimeAlerts.consoleAlertsByPath.slice(0, 8).map((item) => ({
type: item.type ?? null,
status: item.status ?? null,
path: item.urlPath ?? null,
count: item.count,
firstAt: item.firstAt ?? null,
lastAt: item.lastAt ?? null,
promptIndexes: Array.isArray(item.promptIndexes) ? item.promptIndexes.slice(0, 6) : [],
traceIds: Array.isArray(item.traceIds) ? item.traceIds.slice(0, 4) : [],
})),
consoleAlertSamples: runtimeAlerts.consoleAlerts.slice(-8).map((item) => ({
ts: item.ts ?? null,
promptIndex: item.promptIndex ?? null,
type: item.type ?? null,
status: item.status ?? null,
path: item.urlPath ?? null,
traceId: item.traceId ?? null,
text: String(item.preview ?? item.text ?? "").slice(0, 180),
})),
turnTimingRecentUpdateJumps: sampleMetrics.turnTimingRecentUpdateSawtoothJumps.slice(0, 8).map((item) => ({
columnLabel: item.columnLabel ?? item.columnId ?? null,
promptIndex: item.promptIndex ?? null,
traceId: item.traceId ?? null,
fromSeq: item.fromSeq ?? null,
toSeq: item.toSeq ?? null,
fromTs: item.fromTs ?? null,
toTs: item.toTs ?? null,
fromValue: item.fromValue ?? null,
toValue: item.toValue ?? null,
delta: item.delta ?? null,
sampleDeltaSeconds: item.sampleDeltaSeconds ?? null,
allowedIncreaseSeconds: item.allowedIncreaseSeconds ?? null,
excessiveIncreaseSeconds: item.excessiveIncreaseSeconds ?? null,
})),
pagePerformanceSlowApi: pagePerformance.sameOriginApiByPath.filter((item) => item.overFiveSecondCount > 0).slice(0, 5).map((item) => ({ path: item.path, route: item.route, sampleCount: item.sampleCount, p95Ms: item.p95Ms, maxMs: item.maxMs, overFiveSecondCount: item.overFiveSecondCount })),
findings: findings.slice(0, 8).map((item) => ({ kind: item.id ?? item.kind ?? item.code, severity: item.severity, count: item.count ?? item.sampleCount ?? null, summary: String(item.summary ?? item.message ?? "").slice(0, 180) })),
valuesRedacted: true,
@@ -2097,7 +2144,7 @@ function groupNetworkAlerts(events) {
function isDiagnosticText(text) {
const value = String(text || "");
return /Failed to (?:fetch|load resource)|request failed|net::ERR_[A-Z0-9_:-]+|server responded with a status of [45][0-9]{2}|HTTP\s+[45][0-9]{2}|trace_id=|workbench turn\s*超过|无新活动|idle\s+\d+s|waitingFor=|lastEventLabel=|无法连接上游|(?:报警|告警|警告|错误|异常|超时)[:]|timeout[:=]|error[:=]|failed[:=]|warning[:=]|provider-unavailable|agentrun:error|AgentRun error|projection-resume|durable projection store|realtime-gap|\b50[234]\b/iu.test(value);
return /Failed to (?:fetch|load resource)|request failed|net::ERR_[A-Z0-9_:-]+|server responded with a status of [45][0-9]{2}|HTTP\s+[45][0-9]{2}\b|trace_id=|workbench turn\s*超过|turn\s*超过|无新活动|idle\s+\d+s|waitingFor=|lastEventLabel=|无法连接上游|代理暂时无法连接上游|provider-unavailable|agentrun:error|AgentRun error|projection-resume|sync-failed|durable projection store|realtime-gap|Trace 更新超时|加载失败|请求失败|请求已失败/iu.test(value);
}
function isTerminalTraceText(text) {
@@ -2121,7 +2168,7 @@ function buildSampleMetrics(samples, control) {
const promptIndex = Number.isFinite(tsMs) ? latestPromptIndex(promptTimes, tsMs) : 0;
const totalElapsedValues = texts.flatMap(parseTotalElapsedSeconds).filter(Number.isFinite);
const recentUpdateValues = texts.flatMap(parseRecentUpdateSeconds).filter(Number.isFinite);
const diagnosticTexts = texts.filter((text) => /Failed to fetch|realtime-gap|durable projection store|turn 超过|无法连接|projection-resume|503|timeout|error/iu.test(text)).slice(0, 5);
const diagnosticTexts = texts.filter(isDiagnosticText).slice(0, 5);
const terminalTexts = texts.filter(isTerminalTraceText).slice(0, 5);
const finalResultTexts = texts.filter(isFinalResultText).slice(0, 5);
return {