98 lines
3.8 KiB
Markdown
98 lines
3.8 KiB
Markdown
# ProofOfUp
|
|
|
|
Computes availability for uptime and SLA statements from probe samples, and
|
|
refuses to report a number the samples do not support. It is used in Hitt
|
|
Hosting products.
|
|
|
|
## What it does and why
|
|
|
|
An uptime figure is only as good as the samples behind it, and the common
|
|
failures all flatter the service. ProofOfUp computes availability over
|
|
samples you have already loaded and handles the edge cases in the direction
|
|
of saying less.
|
|
|
|
**Zero samples is not 100%.** With no samples, `uptime_pct` is `null`, and
|
|
the report says availability cannot be computed. A statement that answers
|
|
"100%" when nothing was measured is worse than one that abstains. It also
|
|
does not say the SLA was missed: when a target applies but nothing was
|
|
measured, the report is not assessed and states that the target was neither
|
|
met nor missed. (The raw `met` field stays `false` in that case.)
|
|
|
|
"No SLA target" is not "SLA met". With no target, `met` is `null` and the
|
|
report says no SLA target applies to this plan, so a free plan never gets a
|
|
statement that reads as a failure.
|
|
|
|
The rest of the arithmetic:
|
|
|
|
- the window is half-open, `[from, to)`, so adjacent monthly statements never
|
|
count a boundary sample twice;
|
|
- samples outside the window or with bad timestamps are dropped, not counted;
|
|
- each failing sample is charged the gap to the next sample, capped at one
|
|
probe interval (300 seconds by default), so a long reporting gap after one
|
|
failure cannot inflate downtime; the last sample is charged one interval;
|
|
- samples inside scheduled maintenance windows are removed from the math as if
|
|
the probe never ran; cancelled windows are ignored, overlapping windows are
|
|
merged, and windows are clipped to the period;
|
|
- uptime is rounded to one decimal, and the result does not depend on the
|
|
order of the input.
|
|
|
|
The functions are pure, with no I/O and no clock, so the same samples always
|
|
give the same numbers. That is what makes an availability figure evidence and
|
|
not a reading taken at a moment. Reports use the `@extant2000/evidence-record`
|
|
format. The availability citation carries its sample count, so 100% over zero
|
|
samples cannot be mistaken for 100% over thousands, and excluded maintenance
|
|
is reported as not applicable with its own measurement so planned downtime
|
|
stays visible.
|
|
|
|
## Usage
|
|
|
|
```ts
|
|
import { slaReport, formatSla, describeAvailability, describeTarget, type Check } from '@extant2000/proof-of-up'
|
|
|
|
// One probe result every five minutes, loaded from wherever you store them.
|
|
const checks: Check[] = [
|
|
{ ts: '2026-08-01T00:00:00Z', ok: true },
|
|
{ ts: '2026-08-01T00:05:00Z', ok: false },
|
|
// ...
|
|
]
|
|
|
|
const report = slaReport(checks, {
|
|
from: '2026-08-01T00:00:00Z',
|
|
to: '2026-09-01T00:00:00Z',
|
|
target: 99.9, // omit or null for no SLA
|
|
intervalSeconds: 300,
|
|
excludeWindows: [{ starts_at: '2026-08-10T02:00:00Z', ends_at: '2026-08-10T03:00:00Z' }],
|
|
})
|
|
|
|
describeAvailability(report) // e.g. 'Availability 99.8% over 8916 samples, 100 minutes down.'
|
|
describeTarget(report) // e.g. 'Target 99.9% was NOT met.'
|
|
console.log(formatSla(report, { subject: 'app.example.com' }))
|
|
```
|
|
|
|
For a month of five-minute samples with 20 failures and one hour of
|
|
maintenance, `formatSla()` printed this (header line omitted):
|
|
|
|
```
|
|
NOT MET · 8916 items examined · 2 findings
|
|
Availability 99.8% over 8916 samples, 100 minutes down.
|
|
Target 99.9% was NOT met.
|
|
|
|
✗ CRITICAL Availability 99.8% over 8916 samples, 100 minutes down. [NOT MET]
|
|
Target 99.9% was NOT met.
|
|
evidence: Availability = 99.8% (8916 samples, 2026-08-01 → 2026-09-01)
|
|
◦ info 60 minutes of scheduled maintenance excluded (12 samples) [N/A]
|
|
```
|
|
|
|
With no samples, the same call reports NOT ASSESSED and "No samples in this
|
|
period; availability cannot be computed."
|
|
|
|
## Install
|
|
|
|
```
|
|
npm install @extant2000/proof-of-up
|
|
```
|
|
|
|
## License
|
|
|
|
MIT. See [LICENSE](LICENSE).
|