feat: add web sentinel request-rate curves

This commit is contained in:
Codex
2026-07-02 04:51:18 +00:00
parent 9d9f8e1dca
commit f7a0b0672c
13 changed files with 921 additions and 12 deletions
@@ -116,6 +116,16 @@ export function renderWebObserveAnalyzeTable(value: Record<string, unknown>): st
const runtimeAlerts = record(analysis?.runtimeAlerts);
const pagePerformance = record(analysis?.pagePerformance);
const pagePerformanceSummary = record(pagePerformance?.summary);
const nonEmptyRecord = (item: unknown): Record<string, unknown> | null => {
const valueRecord = record(item);
return Object.keys(valueRecord).length > 0 ? valueRecord : null;
};
const requestRateSummarySource = nonEmptyRecord(analysis?.requestRate);
const requestRateCurve = nonEmptyRecord(analysis?.requestRateCurve) ?? (requestRateSummarySource?.summary ? requestRateSummarySource : null);
const requestRateSummary = nonEmptyRecord(requestRateCurve?.summary) ?? requestRateSummarySource;
const requestRatePeaks = webObserveArray(analysis?.requestRatePeaks ?? requestRateCurve?.peaks ?? requestRateSummarySource?.peaks).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8);
const requestRatePageCurves = webObserveArray(requestRateCurve?.pageCurves ?? requestRateSummarySource?.pageCurves).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8);
const requestRateApiPathCurves = webObserveArray(requestRateCurve?.apiPathCurves ?? requestRateSummarySource?.apiPathCurves).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8);
const projectManagement = record(analysis?.projectManagement) ?? record(value.projectManagement);
const projectManagementSummary = record(projectManagement?.summary) ?? projectManagement;
const projectManagementCommandsSource = Array.isArray(projectManagement?.launchCommands) && projectManagement.launchCommands.length > 0
@@ -558,6 +568,41 @@ export function renderWebObserveAnalyzeTable(value: Record<string, unknown>): st
webObserveText(promptNetwork?.promptSegments),
]]),
"",
"Request rate:",
webObserveTable(["BUCKET", "REQUESTS", "TOTAL_PEAK", "PAGE_PEAK", "API_PEAK", "OVER_PEAKS", "THRESHOLDS"], [[
requestRateSummary?.bucketSeconds ? `${webObserveText(requestRateSummary.bucketSeconds)}s` : webObserveText(requestRateSummary?.bucketMs),
webObserveText(requestRateSummary?.requestCount),
webObserveText(requestRateSummary?.totalPeakPerMinute),
webObserveText(requestRateSummary?.pagePeakPerMinute),
webObserveText(requestRateSummary?.apiPathPeakPerMinute),
webObserveText(requestRateSummary?.overThresholdPeakCount),
`total=${webObserveText(requestRateSummary?.totalRedPerMinute)} page=${webObserveText(requestRateSummary?.pageRedPerMinute)} api=${webObserveText(requestRateSummary?.apiPathRedPerMinute)}`,
]]),
requestRatePeaks.length === 0
? "Request rate peaks:\n-"
: webObserveTable(["SCOPE", "RPM", "COUNT", "START", "PAGE", "API"], requestRatePeaks.map((item) => [
webObserveText(item.scope),
webObserveText(item.requestPerMinute),
webObserveText(item.count),
webObserveShort(webObserveText(item.startAt), 24),
webObserveShort(webObserveText(item.path ?? item.pageKey), 48),
webObserveShort(webObserveText(item.apiKey), 64),
])),
"Request page curves:",
webObserveTable(["PAGE", "COUNT", "PEAK_RPM", "PEAK_AT"], requestRatePageCurves.length > 0 ? requestRatePageCurves.map((item) => [
webObserveShort(webObserveText(item.path ?? item.pageKey), 56),
webObserveText(item.count),
webObserveText(item.peakRequestPerMinute),
webObserveShort(webObserveText(record(item.peakBucket)?.startAt), 24),
]) : [["-", "-", "-", "-"]]),
"Request API curves:",
webObserveTable(["API", "COUNT", "PEAK_RPM", "PEAK_AT"], requestRateApiPathCurves.length > 0 ? requestRateApiPathCurves.map((item) => [
webObserveShort(webObserveText(item.apiKey ?? item.path), 72),
webObserveText(item.count),
webObserveText(item.peakRequestPerMinute),
webObserveShort(webObserveText(record(item.peakBucket)?.startAt), 24),
]) : [["-", "-", "-", "-"]]),
"",
"Runner errors:",
webObserveTable(["TS", "TYPE", "RETRY", "EXH", "ATTEMPTS", "LAST_KIND", "READY", "MESSAGE"], runnerErrors.length > 0 ? runnerErrors.map((item) => [
webObserveShort(webObserveText(item.ts), 24),