Merge pull request #633 from pikasTech/fix/webprobe-analyze-visibility-1811-20260621
fix: improve web-probe observe analyze visibility
This commit is contained in:
@@ -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 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 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 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 = [
|
const lines = [
|
||||||
`hwlab nodes web-probe observe analyze (${webObserveText(value.status)})`,
|
`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),
|
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:",
|
"Runtime alerts:",
|
||||||
webObserveTable(["HTTP_ERR", "REQUEST_FAILED", "DOM_DIAG", "CONSOLE_ALERT", "PROMPT_SEGMENTS", "PROMPT_NETWORK"], [[
|
webObserveTable(["HTTP_ERR", "REQUEST_FAILED", "DOM_DIAG", "CONSOLE_ALERT", "PROMPT_SEGMENTS", "PROMPT_NETWORK"], [[
|
||||||
webObserveText(runtimeAlerts?.httpErrorCount),
|
webObserveText(runtimeAlerts?.httpErrorCount),
|
||||||
@@ -7569,12 +7625,10 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
|||||||
]) : [["-", "-", "-", "-", "-"]]),
|
]) : [["-", "-", "-", "-", "-"]]),
|
||||||
"",
|
"",
|
||||||
"DOM diagnostics:",
|
"DOM diagnostics:",
|
||||||
webObserveTable(["COUNT", "FIRST", "LAST", "TEXT"], domDiagnostics.length > 0 ? domDiagnostics.map((item) => [
|
webObserveTable(domDiagnostics.length > 0 ? ["COUNT", "FIRST", "LAST", "TEXT"] : ["SEQ", "TS", "META", "TEXT"], domDiagnosticRows.length > 0 ? domDiagnosticRows : [["-", "-", "-", "-"]]),
|
||||||
webObserveText(item.count),
|
"",
|
||||||
webObserveShort(webObserveText(item.firstAt), 24),
|
"Console alerts:",
|
||||||
webObserveShort(webObserveText(item.lastAt), 24),
|
webObserveTable(consoleAlertGroups.length > 0 ? ["COUNT", "TYPE", "STATUS", "PATH", "LAST", "TRACES"] : ["TS", "TYPE", "STATUS", "PATH", "TRACE", "TEXT"], consoleAlertRows.length > 0 ? consoleAlertRows : [["-", "-", "-", "-", "-", "-"]]),
|
||||||
webObserveShort(webObserveText(item.text), 96),
|
|
||||||
]) : [["-", "-", "-", "-"]]),
|
|
||||||
"",
|
"",
|
||||||
"Findings:",
|
"Findings:",
|
||||||
webObserveTable(["KIND", "SEVERITY", "COUNT", "SUMMARY"], findings.length > 0 ? findings.map((item) => [
|
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) : [],
|
traceIds: Array.isArray(item.traceIds) ? item.traceIds.slice(0, 4) : [],
|
||||||
text: String(item.preview ?? item.normalizedPreview ?? item.text ?? "").slice(0, 160),
|
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 })),
|
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) })),
|
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,
|
valuesRedacted: true,
|
||||||
@@ -2097,7 +2144,7 @@ function groupNetworkAlerts(events) {
|
|||||||
|
|
||||||
function isDiagnosticText(text) {
|
function isDiagnosticText(text) {
|
||||||
const value = String(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) {
|
function isTerminalTraceText(text) {
|
||||||
@@ -2121,7 +2168,7 @@ function buildSampleMetrics(samples, control) {
|
|||||||
const promptIndex = Number.isFinite(tsMs) ? latestPromptIndex(promptTimes, tsMs) : 0;
|
const promptIndex = Number.isFinite(tsMs) ? latestPromptIndex(promptTimes, tsMs) : 0;
|
||||||
const totalElapsedValues = texts.flatMap(parseTotalElapsedSeconds).filter(Number.isFinite);
|
const totalElapsedValues = texts.flatMap(parseTotalElapsedSeconds).filter(Number.isFinite);
|
||||||
const recentUpdateValues = texts.flatMap(parseRecentUpdateSeconds).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 terminalTexts = texts.filter(isTerminalTraceText).slice(0, 5);
|
||||||
const finalResultTexts = texts.filter(isFinalResultText).slice(0, 5);
|
const finalResultTexts = texts.filter(isFinalResultText).slice(0, 5);
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user