Repository navigation
Syspeek 0.9.0
The biggest Syspeek release so far: four new console pages, real actions on the things it watches, and a local cloud-cost surface — with the packaging gaps that only show up on a real distribution fixed before shipping.
Highlights
- GPU page — device utilisation, VRAM, temperature and the processes on the GPU. Linux reads
fdinfo/amdgpu/nvidia-smi, macOSIOAccelerator, Windows PDHGPU Enginecounters. - Sensors & battery — hwmon thermal/fan/power plus battery charge, health, cycles and AC state, with
host_tempandbattery_lowmonitors wired to the same editable rule table. - Actions — TERM/KILL/HUP/PAUSE/RESUME, NICE ±5, I/O priority and OOM adjustment on the selected process; START/STOP/RESTART on containers through the Docker Engine socket; RESTART on systemd/launchd/SCM units. Every refusal names the OS reason, and destructive verbs take a second press.
- History ring + rewind — a bounded on-disk ring (default 1 h at 1 s) with first/prev/next/latest paging and stored-window charts.
- Alert silences, chart bands, healthy-only — snooze a monitor for a rolling window without disabling it, see the threshold as a band on the chart, and hide healthy rows in the process tree.
- Cloud page — instance identity from the link-local metadata service (AWS/Azure/GCP/OCI), accrued cost since this boot, per-app share of the instance rate, and fleet inventory + instance age from your own provider CLI. Prices are never invented:
syspeek --cloud-pricesimports the on-demand rate through theawsCLI when you ask it to. Read-only, no credentials stored, and a CLOUD FOOTPRINT card on the page lists every outbound action with its cadence and budget. /metricsbind + bearer token — a non-loopback bind is refused unless a token is set, and refused scrapes get401with a challenge and zero samples.- Per-process disk I/O — iotop's DISK READ/WRITE semantics (
write_bytes - cancelled_write_bytes) plus a machine-wide top-consumers card. - No more popups — desktop notification popups are gone; alerts live in the console and outbound delivery is
[webhook]-only, off by default. - Cost + Settings console pages, plus overlay robustness: X11 click-through, sticky across desktops, geometry persisted and rescued if a monitor disappears.
Packaging and honesty (this release's hardening)
- The tree now builds and runs its suite on Ubuntu 22.04 (Qt 6.2) and 24.04 (Qt 6.4), not only on the newer Qt CI builds against. The
.deblinks the distribution's Qt, so this is the configuration users actually get. - Found and fixed by that gate:
Depends:was missinglibqt6network6(a clean install died withlibQt6Network.so.6 => not found), andQDateTimeon Qt 6.4 renders ISO dates as+00:00where 6.5+ rendersZ, which broke the Alertmanager webhook payload's RFC3339 timestamps. Both are fixed and gated in CI. syspeek --probenow prints the sampler's own cost (tickMs, slowest section, self CPU and RSS) and CI fails a probe whose worst tick exceeds 1.5 s — a blocking call on a sampler tick cannot land silently. Settings states the same numbers.
What CI proves, what the code proves, what nobody has run yet
- Proven in CI: builds + 14/14 ctest on Linux (apt Qt 6.4.2), macOS 14 (Qt 6.8) and Windows (MSVC Qt 6.8); the
.debinstalled in a clean Ubuntu 22.04/24.04 container with every shared object resolving and--dump/--proberunning; the Azure identity path against a real metadata service (the GitHub Linux/Windows runners are Azure VMs); the gated cloud path plus all cloud cost/rate/fleet maths self-tests on a host with no IMDS; container install, screenshot and installer smokes. - Proven by fixtures and self-tests: every provider parser (AWS/Azure/GCP/OCI), rate-file staleness, cost/share arithmetic, fleet state/age/rate rules, webhook payload schemas, history ring layout and corruption handling, sensor/battery parsing.
- Never run on real hardware: a real cloud account with
--cloud-pricescredentials; a Mac with a realAppleSmartBattery(runners are VMs); NVIDIA silicon (the development box is Intel i915 without hwmon); a real X11 desktop for click-through; a laptop whose battery actually discharges. Those paths state their gate rather than pretending.
Full changelog: v0.8.9...v0.9.0