📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
// Errored function invocations still bill at full duration, so high-volume 5xx is a cost issue, not just reliability.
|
||||
import { withRouteShapeWarnings } from '../route-normalize.mjs';
|
||||
|
||||
const MIN_VOLUME_FOR_RATE_EMISSION = 1000;
|
||||
|
||||
export const metadata = {
|
||||
id: 'route_errors',
|
||||
threshold: `count > 250 OR (totalRequests >= ${MIN_VOLUME_FOR_RATE_EMISSION} AND errorRate > 0.01)`,
|
||||
billingDimension: 'function-duration',
|
||||
scope: 'route',
|
||||
sourceCitation: 'vercel-optimize gate threshold',
|
||||
description:
|
||||
'Routes producing > 250 5xx errors over the window, or with > 1% error rate on at least 1,000 total requests. Errored function invocations still bill at full duration; high error rates also poison user experience.',
|
||||
};
|
||||
|
||||
export function gate(signals) {
|
||||
const errors = extractErrors(signals);
|
||||
return errors
|
||||
.filter((e) => e.count > 250 || (e.total >= MIN_VOLUME_FOR_RATE_EMISSION && (e.errorRate ?? 0) > 0.01))
|
||||
.map((e) => withRouteShapeWarnings({
|
||||
kind: metadata.id,
|
||||
scope: 'route',
|
||||
route: e.route,
|
||||
files: [],
|
||||
priority: e.count,
|
||||
confidence: 0.93,
|
||||
o11ySignal: e.errorRate != null
|
||||
? `errs=${e.count},rate=${(e.errorRate * 100).toFixed(1)}%`
|
||||
: `errs=${e.count}`,
|
||||
reason: 'concentrated 5xx errors',
|
||||
question: `Why does ${e.route} produce ${e.count} 5xx errors over the window, and what code path is failing?`,
|
||||
evidence: { metric: e.metric, route: e.route, count: e.count, totalRequests: e.total, errorRate: e.errorRate },
|
||||
}, signals));
|
||||
}
|
||||
|
||||
function extractErrors(signals) {
|
||||
const fnStatus = signals.metrics?.fnStatusByRoute;
|
||||
if (Array.isArray(fnStatus?.rows)) return extractFromStatusRows(fnStatus.rows, 'fnStatusByRoute');
|
||||
|
||||
const m = signals.metrics?.requestsByRouteStatus;
|
||||
const cache = signals.metrics?.requestsByRouteCache;
|
||||
if (!m?.ok && !Array.isArray(m?.rows)) return [];
|
||||
|
||||
const errors = extractFromStatusRows(m?.rows ?? [], 'requestsByRouteStatus');
|
||||
|
||||
// cache rollup is summed across cache_result, giving per-route total request count.
|
||||
const totalByRoute = new Map();
|
||||
for (const row of (cache?.rows ?? [])) {
|
||||
if (!row.route) continue;
|
||||
totalByRoute.set(row.route, (totalByRoute.get(row.route) ?? 0) + (row.value ?? 0));
|
||||
}
|
||||
|
||||
return errors.map((e) => {
|
||||
const total = totalByRoute.get(e.route) ?? 0;
|
||||
return {
|
||||
...e,
|
||||
total,
|
||||
errorRate: total > 0 ? e.count / total : null,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function extractFromStatusRows(rows, metric) {
|
||||
const errByRoute = new Map();
|
||||
const totalByRoute = new Map();
|
||||
for (const row of rows) {
|
||||
const route = row.route;
|
||||
if (!route) continue;
|
||||
const v = row.value ?? 0;
|
||||
const status = String(row.http_status ?? '');
|
||||
if (/^5\d\d$/.test(status)) errByRoute.set(route, (errByRoute.get(route) ?? 0) + v);
|
||||
totalByRoute.set(route, (totalByRoute.get(route) ?? 0) + v);
|
||||
}
|
||||
|
||||
return [...errByRoute.entries()].map(([route, count]) => {
|
||||
const total = totalByRoute.get(route) ?? 0;
|
||||
const errorRate = total > 0 ? count / total : null;
|
||||
return { route, count, total, errorRate, metric };
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user