syswatch 0.8.0

Single-host, read-only system diagnostics TUI. Twelve tabs covering CPU, memory, disks, processes, GPU, power, services, network, plus a Timeline scrubber and an Insights anomaly engine. Sibling to netwatch.
syswatch-0.8.0 is not a library.

What it shows

# Tab Replaces
1 Overview dashboard view of all subsystems
2 CPU htop CPU panel, top -d, mpstat
3 Memory free, vm_stat, htop mem panel
4 Disks iostat, iotop (aggregate)
5 Filesystems df -h, df -i, mount
6 Procs htop, ps auxf, pstree
7 GPU ioreg AGXAccelerator PerformanceStatistics / /sys/class/drm
8 Power pmset, ioreg AppleSmartBattery / /sys/class/power_supply
9 Services launchctl list / systemctl list-units
0 Net nettop, iftop
- Timeline (no equivalent — session log + scrubber)
+ Insights (no equivalent — plain-English anomaly cards)

Where htop shows you what's running, SysWatch shows you what's happening — across CPU, memory, IO, GPU, power, services — and tells you why in plain English when something's anomalous.

Install

brew install syswatch                 # macOS / Linux
nix-shell -p syswatch                 # NixOS / Nix
paru -S syswatch                      # Arch
cargo install syswatch                # anywhere with Rust

Or grab a pre-built binary from Releases.

# From source
git clone https://github.com/matthart1983/syswatch.git && cd syswatch
cargo build --release && ./target/release/syswatch

The Nix and Arch packages are maintained by community packagers — thank you. File packaging issues with them; file syswatch bugs here. The Repology page shows which packages are current.

Prerequisites (source/cargo builds): Rust 1.75+. No system dependencies on Linux. macOS links against the system frameworks.

Usage

syswatch                       # default 1Hz tick
syswatch --tick 500            # 2Hz
syswatch --tab procs           # boot straight into a tab
syswatch --replay session.swr  # scrub a recorded session
syswatch --lite                # the one-screen Lite view

Keys

1 2 3 4 5 6 7 8 9   →  Overview / CPU / Mem / Disks / FS / Procs / GPU / Power / Services
0 - +               →  Net / Timeline / Insights
Tab / Shift-Tab     →  Cycle tabs
↑ / ↓               →  Select row (Procs, Services)
s                   →  Cycle sort (Procs, Services)
/ or f              →  Filter the table (Procs, Memory, Services)
← / →               →  Scrub session backward / forward
Home / End          →  Oldest sample / live
p                   →  Pause
g                   →  Graph style (bars / dots)
t                   →  Cycle theme (incl. "terminal" — uses your terminal's own palette)
,                   →  Settings (tick, theme, btop-style fade)
S / R               →  Snapshot to disk / record session
L                   →  Toggle the Lite view
?                   →  Help
q / Ctrl-C          →  Quit

Lite view

syswatch --lite, or L at any time. One screen at 80×24 answering one question — why is this machine hot, slow, or loud? — with six keys and four colors. It is not the full tool with tabs hidden; it is a different product for someone with one machine, and the deliberate sibling of netwatch --lite: identical grid geometry, column positions, keys and palette, so muscle memory carries between them.

q  quit     p  pause    /  filter (name or user)
↵  detail   L  full     ?  help          ↑↓ / j k move   Esc unwind

CPU gets a three-row chart and memory two — when a machine feels wrong, CPU is the answer more often than RAM. A single vitals line carries temp, fan, power and disk throughput, each rendering -- rather than moving when a sensor isn't readable. Red appears only when the machine is actually in trouble — thermal throttling, swap thrashing, critical memory pressure — on fixed thresholds with hysteresis (three samples to fire, five to clear) so it never flaps. Memory pressure comes from the kernel's own verdict where there is one (PSI on Linux, kern.memorystatus_vm_pressure_level on macOS) rather than being inferred from swap, so a Mac doing what Macs normally do doesn't read as an emergency. It follows your theme and graph style like every other screen, and it is read-only, same as the rest of syswatch.

What's distinctive

Insights tab. Heuristic anomaly detection over the rolling session — swap thrash, runaway processes, disk full, memory pressure, high load, zombie parties — surfaced as plain-English cards with a suggested tab. The Overview's bottom strip and the tab bar's [+] badge keep them in sight from anywhere.

Session-wide scrubbing. The Timeline tab's ←/→ rewinds the entire app — every panel transparently shows historical state. R records a session to a .swr file; --replay scrubs it back later. S dumps the current snapshot to disk.

Honest about platform limits. Where data needs sudo (powermetrics for fans, per-component power, GPU util on Apple Silicon) the tab shows what we can get for free and a one-line note about what's gated. Nothing is faked, nothing prompts.

Anti-goals

  • Not multi-host. For fleet view, use NetWatch's web dashboard.
  • Not a daemon. No long-running collector, no Prometheus push. The session is the database.
  • Not interactive remediation. Read-only, deliberately. We don't kill, renice, unmount, or restart.
  • Not a logging product. We surface OOM kills as a signal in Memory; we are not a log search UI.
  • Not pretty charts for screenshots. Block sparklines, real numbers, no smooth curves, no themes-of-the-week.

Scope

All twelve tabs render real data on macOS and Linux. Cross-platform collection via sysinfo; aggregate disk IO routes through netwatch-sdk so SysWatch and the NetWatch agent share a single source of truth. Recording/Replay (R / --replay), Settings (,), Help (?), table filter (/ or f, on Procs / Memory / Services), themes (t), the Lite view (L / --lite), and the btop-style fade rendering are all live.

Lite's temp / fan / power vitals depend on platform sensors: Linux reads /sys/class/hwmon, /sys/class/thermal and RAPL; macOS needs IOKit/SMC access, so on Apple Silicon those three commonly render -- while CPU, memory, disk and processes remain fully live.

No sudo, ever. GPU utilization, VRAM, and the renderer/tiler split on Apple Silicon come from ioreg (AGXAccelerator PerformanceStatistics); GPU temperature, per-rail power, and fans come from IOReport + SMC. Linux reads sysfs (/sys/class/drm, thermal zones, hwmon). Where a figure genuinely needs elevated access, the tab says so rather than prompting.

Behind cargo features — NVIDIA live GPU stats (gpu-nvidia, nvml-wrapper).

Architecture

src/
├── main.rs              CLI + entry
├── app.rs               Event loop, tab state, scrub plumbing
├── collect/             One Collector per subsystem; Snapshot the wire format
│   ├── collector.rs     sysinfo-backed CPU/Mem/Procs/Net + dispatch
│   ├── gpu.rs           ioreg AGXAccelerator / sysfs DRM / nvml
│   ├── macos_sampler.rs Shared IOReport + SMC worker (GPU/power/fans)
│   ├── power.rs         ioreg / pmset / sysfs power_supply
│   ├── services.rs      launchctl / systemctl
│   └── ring.rs          Bounded history + nth_back for scrubbing
├── insights/            Pure functions over (History, &Snapshot)
├── tabs/                One file per tab; thin renderers over the model
└── ui/
    ├── chrome.rs        Header, tab bar, footer
    ├── palette.rs       Single source of color truth
    └── widgets.rs       block_bar, sparkline, panel

Refresh model: a 1 Hz fast loop reads CPU/Mem/Net/IO in-process every tick; the heavier collectors run on their own budgets — processes every ~1.5 s, Power/Services every 5 s, per-process bandwidth on a background thread — so the loop stays cheap regardless of tick rate. The UI redraws on tick or keypress.

License

MIT.