fix: improve web-probe trace drilldown visibility (#734)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -8326,7 +8326,7 @@ function renderWebObserveCollectTable(value: Record<string, unknown>): string {
|
||||
]]),
|
||||
"",
|
||||
"Finding samples:",
|
||||
webObserveTable(["SEQ", "TS", "KIND", "CONTROL", "OBSERVER", "SESSION", "PATH", "DETAIL"], jsonFindingSamples.length > 0 ? jsonFindingSamples.map((item) => [
|
||||
webObserveTable(["SEQ", "TS", "KIND", "CONTROL", "OBSERVER", "SESSION", "PATH", "TRACE", "DETAIL"], jsonFindingSamples.length > 0 ? jsonFindingSamples.map((item) => [
|
||||
webObserveText(item.seq ?? item.sampleSeq ?? item.fromSeq),
|
||||
webObserveShort(webObserveText(item.ts ?? item.sampleTs ?? item.fromTs), 24),
|
||||
webObserveShort(webObserveText(item.diffKind ?? item.kind ?? item.type ?? item.metric ?? item.anomaly), 28),
|
||||
@@ -8334,15 +8334,16 @@ function renderWebObserveCollectTable(value: Record<string, unknown>): string {
|
||||
webObserveShort(webObserveText(item.observer ?? item.observerValue ?? item.afterValue), 28),
|
||||
webObserveShort(webObserveText(item.sessionId ?? item.routeSessionId ?? item.activeSessionId), 36),
|
||||
webObserveShort(webObserveText(item.path ?? item.urlPath ?? item.url), 48),
|
||||
webObserveShort(webObserveText(item.trace ?? item.traceId ?? item.controlTraceId ?? item.observerTraceId), 48),
|
||||
webObserveShort(webObserveText(item.detail ?? item.summary ?? item.message ?? item.preview), 96),
|
||||
]) : [["-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
]) : [["-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
);
|
||||
}
|
||||
if (jsonlTail.length > 0) {
|
||||
lines.push(
|
||||
"JSONL tail:",
|
||||
webObserveTable(["TS", "ROLE", "TYPE", "COMMAND", "MSG", "TRACE", "LOAD", "ATTEMPTS", "READY", "DOM", "PATH", "MESSAGE"], jsonlTail.map((item) => {
|
||||
webObserveTable(["TS", "ROLE", "TYPE", "COMMAND", "MSG", "TRACE", "TRACE_IDS", "MSG_STATUS", "LOAD", "ATTEMPTS", "READY", "DOM", "PATH", "MESSAGE"], jsonlTail.map((item) => {
|
||||
const error = record(item.error);
|
||||
const attempts = Array.isArray(error.attempts) ? error.attempts : [];
|
||||
const lastAttempt = attempts.length > 0 ? record(attempts[attempts.length - 1]) : {};
|
||||
@@ -8362,6 +8363,8 @@ function renderWebObserveCollectTable(value: Record<string, unknown>): string {
|
||||
webObserveShort(webObserveText(item.commandId), 28),
|
||||
webObserveText(item.messageCount),
|
||||
webObserveText(item.traceRowCount ?? item.traceEventCount),
|
||||
webObserveShort(webObserveText(item.traceIds), 48),
|
||||
webObserveShort(webObserveText(item.messageStatuses), 48),
|
||||
webObserveText(item.loadingCount),
|
||||
webObserveText(attempts.length),
|
||||
webObserveShort(webObserveText(readiness.reason), 24),
|
||||
@@ -8470,6 +8473,9 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
"const slimLoadingSegment = (item) => { const v = objectOrNull(item) || {}; return { firstAt: v.firstAt ?? null, lastAt: v.lastAt ?? null, endedAt: v.endedAt ?? null, firstSeq: v.firstSeq ?? null, lastSeq: v.lastSeq ?? null, durationSeconds: v.durationSeconds ?? null, upperBoundSeconds: v.upperBoundSeconds ?? null, endedGapSeconds: v.endedGapSeconds ?? null, sampleCount: v.sampleCount ?? null, maxCount: v.maxCount ?? null, ownerCount: v.ownerCount ?? null, ongoing: v.ongoing === true, owners: Array.isArray(v.owners) ? v.owners.slice(0, 6).map((owner) => ({ ownerKind: clip(owner?.ownerKind, 32), ownerLabel: clip(owner?.ownerLabel, 120), count: owner?.count ?? null })) : [] }; };",
|
||||
"const slimLoadingMetrics = (value) => { const v = objectOrNull(value); if (!v) return null; return { summary: objectOrNull(v.summary), longestSegments: takeHead(v.longestSegments ?? v.segments, 8).map(slimLoadingSegment), owners: takeHead(v.owners, 8).map(slimLoadingOwner), timeline: takeTail(v.timeline, 12).map((item) => { const row = objectOrNull(item) || {}; return { seq: row.seq ?? null, ts: row.ts ?? null, promptIndex: row.promptIndex ?? null, loadingCount: row.loadingCount ?? null, ownerCount: row.ownerCount ?? null, owners: Array.isArray(row.owners) ? row.owners.slice(0, 6).map((owner) => ({ ownerKind: clip(owner?.ownerKind, 32), ownerLabel: clip(owner?.ownerLabel, 120), count: owner?.count ?? null })) : [] }; }), valuesRedacted: true }; };",
|
||||
"const srcMetrics = objectOrNull(source?.sampleMetrics);",
|
||||
"const fullRecentWindow = objectOrNull(fullSource?.windows?.recent);",
|
||||
"const fullRecentMetrics = objectOrNull(fullRecentWindow?.sampleMetrics);",
|
||||
"const fullArchiveMetrics = objectOrNull(fullSource?.sampleMetrics);",
|
||||
"const metrics = srcMetrics ? {",
|
||||
" sampleCount: srcMetrics.sampleCount ?? null,",
|
||||
" loadingSampleCount: srcMetrics.loadingSampleCount ?? null,",
|
||||
@@ -8481,18 +8487,19 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
" loadingCurrentContinuousSeconds: srcMetrics.loadingCurrentContinuousSeconds ?? null,",
|
||||
" loadingOverFiveSecondSegmentCount: srcMetrics.loadingOverFiveSecondSegmentCount ?? null,",
|
||||
" loading: slimLoadingMetrics(srcMetrics.loading),",
|
||||
" 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: Array.isArray(srcMetrics.turnTimingRows) ? srcMetrics.turnTimingRows.length : (srcMetrics.turnTimingRows ?? null),",
|
||||
" turnTimingNonMonotonicCount: srcMetrics.turnTimingNonMonotonicCount ?? null,",
|
||||
" turnTimingTotalElapsedDecreaseCount: srcMetrics.turnTimingTotalElapsedDecreaseCount ?? null,",
|
||||
" turnTimingTotalElapsedForwardJumpCount: srcMetrics.turnTimingTotalElapsedForwardJumpCount ?? null,",
|
||||
" turnTimingTotalElapsedForwardJumpMaxSeconds: srcMetrics.turnTimingTotalElapsedForwardJumpMaxSeconds ?? null,",
|
||||
" turnTimingTerminalElapsedGrowthCount: srcMetrics.turnTimingTerminalElapsedGrowthCount ?? null,",
|
||||
" turnTimingRecentUpdateJumpCount: srcMetrics.turnTimingRecentUpdateJumpCount ?? null,",
|
||||
" turnTimingRecentUpdateSawtoothJumpCount: srcMetrics.turnTimingRecentUpdateSawtoothJumpCount ?? null,",
|
||||
" turnTimingRecentUpdateMaxIncreaseSeconds: srcMetrics.turnTimingRecentUpdateMaxIncreaseSeconds ?? null,",
|
||||
" roundItems: takeTail(firstNonEmptyArray(srcMetrics.roundItems, srcMetrics.rounds, fullRecentMetrics?.rounds, fullArchiveMetrics?.rounds), 8).map(slimRound),",
|
||||
" rounds: takeTail(firstNonEmptyArray(srcMetrics.roundItems, srcMetrics.rounds, fullRecentMetrics?.rounds, fullArchiveMetrics?.rounds), 8).map(slimRound),",
|
||||
" turnColumns: takeTail(firstNonEmptyArray(srcMetrics.turnColumns, fullRecentMetrics?.turnColumns, fullArchiveMetrics?.turnColumns), 8).map(slimTurnColumn),",
|
||||
" turnTimingRows: srcMetrics.turnTimingRows ?? fullRecentMetrics?.summary?.turnTimingRows ?? fullRecentMetrics?.turnTimingRows?.length ?? fullArchiveMetrics?.summary?.turnTimingRows ?? fullArchiveMetrics?.turnTimingRows?.length ?? null,",
|
||||
" turnTimingNonMonotonicCount: srcMetrics.turnTimingNonMonotonicCount ?? fullRecentMetrics?.summary?.turnTimingNonMonotonicCount ?? fullRecentMetrics?.turnTimingNonMonotonic?.length ?? fullArchiveMetrics?.summary?.turnTimingNonMonotonicCount ?? fullArchiveMetrics?.turnTimingNonMonotonic?.length ?? null,",
|
||||
" turnTimingTotalElapsedDecreaseCount: srcMetrics.turnTimingTotalElapsedDecreaseCount ?? fullRecentMetrics?.summary?.turnTimingTotalElapsedDecreaseCount ?? fullArchiveMetrics?.summary?.turnTimingTotalElapsedDecreaseCount ?? null,",
|
||||
" turnTimingTotalElapsedZeroResetCount: srcMetrics.turnTimingTotalElapsedZeroResetCount ?? fullRecentMetrics?.summary?.turnTimingTotalElapsedZeroResetCount ?? fullRecentMetrics?.turnTimingElapsedZeroResets?.length ?? fullArchiveMetrics?.summary?.turnTimingTotalElapsedZeroResetCount ?? fullArchiveMetrics?.turnTimingElapsedZeroResets?.length ?? null,",
|
||||
" turnTimingTotalElapsedForwardJumpCount: srcMetrics.turnTimingTotalElapsedForwardJumpCount ?? fullRecentMetrics?.summary?.turnTimingTotalElapsedForwardJumpCount ?? fullRecentMetrics?.turnTimingTotalElapsedForwardJumps?.length ?? fullArchiveMetrics?.summary?.turnTimingTotalElapsedForwardJumpCount ?? fullArchiveMetrics?.turnTimingTotalElapsedForwardJumps?.length ?? null,",
|
||||
" turnTimingTotalElapsedForwardJumpMaxSeconds: srcMetrics.turnTimingTotalElapsedForwardJumpMaxSeconds ?? fullRecentMetrics?.summary?.turnTimingTotalElapsedForwardJumpMaxSeconds ?? fullArchiveMetrics?.summary?.turnTimingTotalElapsedForwardJumpMaxSeconds ?? null,",
|
||||
" turnTimingTerminalElapsedGrowthCount: srcMetrics.turnTimingTerminalElapsedGrowthCount ?? fullRecentMetrics?.summary?.turnTimingTerminalElapsedGrowthCount ?? fullRecentMetrics?.turnTimingTerminalElapsedGrowth?.length ?? fullArchiveMetrics?.summary?.turnTimingTerminalElapsedGrowthCount ?? fullArchiveMetrics?.turnTimingTerminalElapsedGrowth?.length ?? null,",
|
||||
" turnTimingRecentUpdateJumpCount: srcMetrics.turnTimingRecentUpdateJumpCount ?? fullRecentMetrics?.summary?.turnTimingRecentUpdateJumpCount ?? fullRecentMetrics?.summary?.turnTimingRecentUpdateSawtoothJumpCount ?? fullArchiveMetrics?.summary?.turnTimingRecentUpdateJumpCount ?? fullArchiveMetrics?.summary?.turnTimingRecentUpdateSawtoothJumpCount ?? null,",
|
||||
" turnTimingRecentUpdateSawtoothJumpCount: srcMetrics.turnTimingRecentUpdateSawtoothJumpCount ?? fullRecentMetrics?.summary?.turnTimingRecentUpdateSawtoothJumpCount ?? fullArchiveMetrics?.summary?.turnTimingRecentUpdateSawtoothJumpCount ?? null,",
|
||||
" turnTimingRecentUpdateMaxIncreaseSeconds: srcMetrics.turnTimingRecentUpdateMaxIncreaseSeconds ?? fullRecentMetrics?.summary?.turnTimingRecentUpdateMaxIncreaseSeconds ?? fullArchiveMetrics?.summary?.turnTimingRecentUpdateMaxIncreaseSeconds ?? null,",
|
||||
" promptSegments: srcMetrics.promptSegments ?? null",
|
||||
"} : null;",
|
||||
"const srcRuntimeAlerts = objectOrNull(source?.runtimeAlerts);",
|
||||
@@ -8500,7 +8507,6 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
"const srcPagePerformance = objectOrNull(source?.pagePerformance);",
|
||||
"const srcPagePerformanceSummary = objectOrNull(srcPagePerformance?.summary);",
|
||||
"const pagePerformance = srcPagePerformance ? { sameOriginApiPaths: srcPagePerformance.sameOriginApiPaths ?? srcPagePerformanceSummary?.sameOriginApiPathCount ?? null, longLivedStreamPathCount: srcPagePerformance.longLivedStreamPathCount ?? srcPagePerformanceSummary?.longLivedStreamPathCount ?? null, longLivedStreamOpenOverFiveSecondSampleCount: srcPagePerformance.longLivedStreamOpenOverFiveSecondSampleCount ?? srcPagePerformanceSummary?.longLivedStreamOpenOverFiveSecondSampleCount ?? null, slowPathCount: srcPagePerformance.slowPathCount ?? srcPagePerformanceSummary?.slowPathCount ?? null, slowSampleCount: srcPagePerformance.slowSampleCount ?? srcPagePerformanceSummary?.slowSampleCount ?? null, worstP95Ms: srcPagePerformance.worstP95Ms ?? srcPagePerformanceSummary?.worstP95Ms ?? null } : null;",
|
||||
"const fullRecentWindow = objectOrNull(fullSource?.windows?.recent);",
|
||||
"const fullPagePerformance = objectOrNull(fullRecentWindow?.pagePerformance) || objectOrNull(fullSource?.pagePerformance);",
|
||||
"const fullArchivePagePerformance = objectOrNull(fullSource?.pagePerformance);",
|
||||
"const isLongLivedApi = (item) => item?.isLongLivedStream === true || item?.routeKind === 'same-origin-api-stream' || item?.budgetMetric === 'streamOpenMs';",
|
||||
@@ -9977,18 +9983,51 @@ const slimFinding=(item)=>{
|
||||
const firstArray=(...values)=>values.find((value)=>Array.isArray(value))||[];
|
||||
const compactMetric=(value)=>value===undefined||value===null?undefined:(typeof value==='object'?short(JSON.stringify(slimObject(value,8)),160):short(value,160));
|
||||
const compactProjectionPair=(messageCount,traceCount)=>messageCount===undefined&&traceCount===undefined?undefined:'msg='+String(messageCount??'-')+' trace='+String(traceCount??'-');
|
||||
const firstNestedRef=(value)=>value&&typeof value==='object'?(value.control&&typeof value.control==='object'?value.control:(value.observer&&typeof value.observer==='object'?value.observer:null)):null;
|
||||
const compactTraceList=(value)=>{
|
||||
if(Array.isArray(value)) return value.length>0?value.slice(0,4).map((item)=>String(item)).join(','):undefined;
|
||||
if(value===undefined||value===null||value==='') return undefined;
|
||||
return String(value);
|
||||
};
|
||||
const traceIdsFromRows=(rows)=>{
|
||||
if(!Array.isArray(rows)) return undefined;
|
||||
const ids=[];
|
||||
for(const row of rows){
|
||||
if(!row||typeof row!=='object') continue;
|
||||
const value=row.traceId??row.businessTraceId??row.id;
|
||||
if(value&&!ids.includes(String(value))) ids.push(String(value));
|
||||
if(ids.length>=4) break;
|
||||
}
|
||||
return ids.length>0?ids:undefined;
|
||||
};
|
||||
const messageStatusesFromRows=(rows)=>{
|
||||
if(!Array.isArray(rows)) return undefined;
|
||||
const values=[];
|
||||
for(const row of rows){
|
||||
if(!row||typeof row!=='object') continue;
|
||||
const status=row.status??row.dataStatus??row.messageStatus;
|
||||
const trace=row.traceId??row.businessTraceId;
|
||||
const text=[status,trace].filter(Boolean).join(':');
|
||||
if(text&&!values.includes(text)) values.push(String(text));
|
||||
if(values.length>=4) break;
|
||||
}
|
||||
return values.length>0?values:undefined;
|
||||
};
|
||||
const slimFindingSample=(value)=>{
|
||||
if(!value||typeof value!=='object') return null;
|
||||
const refValue=firstNestedRef(value)||{};
|
||||
const controlCount=compactProjectionPair(value.controlMessageCount,value.controlTraceRowCount)??value.controlValue??value.beforeMessageCount??value.beforeValue;
|
||||
const observerCount=compactProjectionPair(value.observerMessageCount,value.observerTraceRowCount)??value.observerValue??value.afterMessageCount??value.afterValue;
|
||||
const trace=compactTraceList(value.traceIds)??compactTraceList(value.missingTraceIdsInObserver)??compactTraceList(value.controlTraceIds)??compactTraceList(value.observerTraceIds)??value.traceId??refValue.traceId;
|
||||
return {
|
||||
seq:value.seq??value.sampleSeq??value.fromSeq??value.controlSeq??null,
|
||||
ts:short(value.ts??value.sampleTs??value.fromTs??value.controlTs,32),
|
||||
seq:value.seq??value.sampleSeq??value.fromSeq??value.controlSeq??refValue.seq??null,
|
||||
ts:short(value.ts??value.sampleTs??value.fromTs??value.controlTs??refValue.ts,32),
|
||||
diffKind:short(value.diffKind??value.kind??value.type??value.metric??value.anomaly,48),
|
||||
control:compactMetric(controlCount),
|
||||
observer:compactMetric(observerCount),
|
||||
sessionId:short(value.sessionId??value.routeSessionId??value.activeSessionId??value.controlSessionId??value.observerSessionId,64),
|
||||
path:short(value.path??value.urlPath??value.url??value.controlPath??value.observerPath,120),
|
||||
sessionId:short(value.sessionId??value.routeSessionId??value.activeSessionId??value.controlSessionId??value.observerSessionId??refValue.routeSessionId??refValue.activeSessionId,64),
|
||||
path:short(value.path??value.urlPath??value.url??value.controlPath??value.observerPath??refValue.url,120),
|
||||
trace:short(trace,120),
|
||||
detail:short(value.detail??(value.messageTextDigestDiff?'messageDigest '+String(value.controlMessageDigest??'-')+' != '+String(value.observerMessageDigest??'-'):undefined)??value.summary??value.message??value.preview??value.expectedPattern,180),
|
||||
valuesRedacted:true
|
||||
};
|
||||
@@ -10019,6 +10058,8 @@ const slimJsonl=(value)=>{
|
||||
routeSessionId:short(value.routeSessionId||snapshot?.routeSessionId,48),
|
||||
activeSessionId:short(value.activeSessionId||snapshot?.activeSessionId,48),
|
||||
messageCount:value.messageCount??(Array.isArray(value.messages)?value.messages.length:undefined)??snapshot?.messageCount,
|
||||
messageStatuses:short(compactTraceList(messageStatusesFromRows(value.messages)),160),
|
||||
traceIds:short(compactTraceList(value.traceIds??traceIdsFromRows(value.traceRows)),160),
|
||||
traceEventCount:value.traceEventCount??snapshot?.traceEventCount,
|
||||
traceRowCount:value.traceRowCount??(Array.isArray(value.traceRows)?value.traceRows.length:undefined)??snapshot?.traceRowCount,
|
||||
loadingCount:value.loadingCount??(Array.isArray(value.loadings)?value.loadings.length:undefined)??snapshot?.loadingCount,
|
||||
|
||||
@@ -4777,6 +4777,8 @@ function detectCrossPageProjectionDiffs(samples) {
|
||||
diffKind: traceVisibilityDivergent ? "trace-visibility" : "projection",
|
||||
control: ref(control),
|
||||
observer: ref(observer),
|
||||
controlTraceIds: [...controlTraceIds].slice(0, 8),
|
||||
observerTraceIds: [...observerTraceIds].slice(0, 8),
|
||||
missingTraceIdsInObserver: missingInObserver.slice(0, 8),
|
||||
controlMessageCount: controlMessages,
|
||||
observerMessageCount: observerMessages,
|
||||
@@ -4837,6 +4839,8 @@ function detectAdjacentCrossPageProjectionDiffs(samples) {
|
||||
const controlZero = detectTerminalZeroElapsed([control]).length > 0;
|
||||
const observerZero = detectTerminalZeroElapsed([observer]).length > 0;
|
||||
const missingInObserver = [...visibleTraceIds(control)].filter((item) => !visibleTraceIds(observer).has(item));
|
||||
const controlTraceIds = visibleTraceIds(control);
|
||||
const observerTraceIds = visibleTraceIds(observer);
|
||||
const controlMessageDigest = digestMessageTexts(control);
|
||||
const observerMessageDigest = digestMessageTexts(observer);
|
||||
const messageTextDigestDiff = controlMessageDigest !== observerMessageDigest;
|
||||
@@ -4849,6 +4853,8 @@ function detectAdjacentCrossPageProjectionDiffs(samples) {
|
||||
diffKind: traceVisibilityDivergent ? "trace-visibility" : "projection",
|
||||
control: ref(control),
|
||||
observer: ref(observer),
|
||||
controlTraceIds: [...controlTraceIds].slice(0, 8),
|
||||
observerTraceIds: [...observerTraceIds].slice(0, 8),
|
||||
missingTraceIdsInObserver: missingInObserver.slice(0, 8),
|
||||
controlMessageCount: controlMessages,
|
||||
observerMessageCount: observerMessages,
|
||||
|
||||
Reference in New Issue
Block a user