Three dashboards served by one FastAPI app with a SQLite history store
(raw / 1m / 1h) and hand-written SVG charts: no Prometheus, no Grafana,
no CDN, no build step. Nothing is fetched from the internet at runtime.
* system: a stdlib-only agent (agent/host_agent.py) reports /proc and
/sys counters; the dashboard turns them into rates over a labelled
window, so every number says how it was measured.
* llm: gufo/llama.cpp and vLLM /metrics are parsed by an in-house
exposition parser. Measured delta/elapsed throughput beats a native
per-request gauge, and each value carries its provenance.
* ups: a NUT wire-protocol client plus health checks that name what
they looked at. Commands are gated by NUT_ALLOW_ACTIONS,
DASH_READ_ONLY and a DANGER confirmation, re-checked server-side.
Missing values render as n/a rather than 0, and an unconfigured source
answers 404 {"configured": false} without dialling anything, so "not
deployed here" never looks like an outage.
253 tests at 94% coverage against captured real fixtures; ruff and
pyright clean.
LLM-Generated: true
96 lines
3.2 KiB
Python
96 lines
3.2 KiB
Python
"""Rate estimation over a labelled window.
|
|
|
|
Every throughput number in this dashboard is Δcounter/Δt. If the estimator returns a
|
|
plausible-looking number for a counter that restarted, or a silent 0 for a scrape that
|
|
arrived late, the UI cannot tell the difference — so the None cases matter more here than
|
|
the happy path.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
|
|
import pytest
|
|
|
|
from dashboards.rates import RateEstimator
|
|
|
|
|
|
def test_first_sample_has_no_rate() -> None:
|
|
r = RateEstimator(span=10)
|
|
assert r.rate("cpu", 100.0, now=1_000.0) == (None, None)
|
|
|
|
|
|
def test_second_sample_gives_rate_and_window() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("cpu", 100.0, now=1_000.0)
|
|
rate, window = r.rate("cpu", 300.0, now=1_010.0)
|
|
assert rate == 20.0
|
|
assert window == 10.0
|
|
|
|
|
|
def test_window_is_labelled_with_the_span_actually_used() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("x", 0.0, now=0.0)
|
|
r.rate("x", 10.0, now=2.0) # inside the span
|
|
rate, window = r.rate("x", 30.0, now=11.0)
|
|
# base is the sample 11s ago (outside the span) -> falls back to the previous sample
|
|
assert window == 9.0
|
|
assert rate == pytest.approx(20.0 / 9.0)
|
|
|
|
|
|
def test_none_value_does_not_poison_the_window() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("x", 10.0, now=0.0)
|
|
assert r.rate("x", None, now=1.0) == (None, None)
|
|
rate, _window = r.rate("x", 30.0, now=2.0)
|
|
assert rate == 10.0, "the None scrape must not become the baseline"
|
|
|
|
|
|
def test_nan_and_inf_are_treated_as_missing() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("x", 1.0, now=0.0)
|
|
for bad in (float("nan"), float("inf")):
|
|
assert r.rate("x", bad, now=1.0) == (None, None)
|
|
|
|
|
|
def test_counter_reset_yields_none_once_then_recovers() -> None:
|
|
"""A restart must not report a huge negative — or, worse, a huge positive — rate."""
|
|
r = RateEstimator(span=60)
|
|
r.rate("tokens", 5_000.0, now=0.0)
|
|
rate, _ = r.rate("tokens", 10.0, now=10.0) # process restarted
|
|
assert rate is None
|
|
rate, _ = r.rate("tokens", 60.0, now=20.0)
|
|
assert rate == 5.0, "the window re-seeds from the post-restart counter"
|
|
|
|
|
|
def test_flat_counter_reports_zero_not_none() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("idle", 5.0, now=0.0)
|
|
rate, window = r.rate("idle", 5.0, now=5.0)
|
|
assert rate == 0.0 and window == 5.0
|
|
|
|
|
|
def test_keys_are_independent() -> None:
|
|
r = RateEstimator(span=10)
|
|
r.rate("a", 0.0, now=0.0)
|
|
r.rate("b", 100.0, now=0.0)
|
|
assert r.rate("a", 10.0, now=1.0)[0] == 10.0
|
|
assert r.rate("b", 100.0, now=1.0)[0] == 0.0
|
|
|
|
|
|
def test_forget_drops_a_removed_target() -> None:
|
|
r = RateEstimator(span=10)
|
|
for key in ("driveripper:cpu.total", "driveripper:disk.read", "deskwork:cpu.total"):
|
|
r.rate(key, 1.0, now=0.0)
|
|
assert r.forget("driveripper:") == 2
|
|
assert r.keys() == ["deskwork:cpu.total"]
|
|
# and the surviving target is untouched
|
|
assert r.rate("deskwork:cpu.total", 11.0, now=1.0)[0] == 10.0
|
|
|
|
|
|
def test_history_is_trimmed_to_max_samples() -> None:
|
|
r = RateEstimator(span=1e6, max_samples=8)
|
|
for i in range(50):
|
|
r.rate("x", float(i), now=float(i))
|
|
assert len(r._samples["x"]) <= 8 # bounded memory is the contract
|
|
assert all(math.isfinite(v) for _, v in r._samples["x"])
|