1,445 bytes · the TypeScript implementation · view raw
/** * How fast an SLO's error budget is burning, in thousandths: the window's * error rate divided by the error rate the SLO allows. 1000 spends exactly * the budget over the SLO period; 14400 (14.4x) spends 2% of a 30-day budget * in one hour. * * Exact BigInt arithmetic: bad x 10000 x 1000 passes 2^53 at under a billion * bad events. */exportfunction burnRate(targetBasisPoints: number, totalEvents: number, badEvents: number): number {
if (!Number.isSafeInteger(targetBasisPoints) || targetBasisPoints < 1 || targetBasisPoints > 9999) {
thrownew RangeError(`targetBasisPoints must be a whole number from 1 to 9999 (10000 leaves no error budget), received ${targetBasisPoints}`);
}
if (!Number.isSafeInteger(totalEvents) || totalEvents < 0) {
thrownew RangeError(`totalEvents must be a whole number of at least 0, received ${totalEvents}`);
}
if (!Number.isSafeInteger(badEvents) || badEvents < 0) {
thrownew RangeError(`badEvents must be a whole number of at least 0, received ${badEvents}`);
}
if (badEvents > totalEvents) thrownew RangeError(`badEvents must not exceed totalEvents: ${badEvents} > ${totalEvents}`);
// An empty window has no error rate; 0 keeps an alert quiet rather than failing it.if (totalEvents === 0) return0;
const n = BigInt(badEvents) * 10000n * 1000n;
const d = BigInt(totalEvents) * BigInt(10000 - targetBasisPoints);
return Number((2n * n + d) / (2n * d));
}