Agentless TUI dashboard for monitoring a fleet of Linux servers over SSH.
One persistent connection and one compound exec command per host per poll
cycle; everything else is parsing, so the footprint on monitored machines is
close to zero.
| Column | Source |
|---|---|
| STATE | connection outcome: online / unreachable / auth-error |
| LOAD 1M | /proc/loadavg, coloured against the host's core count |
| CPU | delta of /proc/stat counters between two polls |
| MEM | (MemTotal − MemAvailable) / MemTotal from /proc/meminfo |
| DISK / | use% of the root mountpoint via df -kP / |
| UPTIME | /proc/uptime |
| RTT | round-trip time of the probe command |
CPU, MEM, DISK and LOAD turn yellow above warn_pct and red above
crit_pct (configurable, defaults 70 / 88).
Selecting a host opens a drill-down with the full metric set and a sparkline of load-1 history.
pipx install git+https://github.com/SHAWNiksDev/sshfleet.gitor from a clone:
pip install .Requires Python 3.11+. Authentication goes through your normal SSH setup:
agent, default keys in ~/.ssh, or an explicit identity_file per host.
Point it at an inventory file (see examples/fleet.example.toml):
[defaults]
user = "deploy"
interval = 10
timeout = 8
max_concurrent = 8
verify_hosts = true
[[hosts]]
name = "edge-fra-01"
host = "edge-fra-01" # resolved through ~/.ssh/config, like `ssh edge-fra-01`
[[hosts]]
host = "db.internal.lan" # or a plain address with explicit overrides
port = 2222Host entries are resolved through your ~/.ssh/config by default
(import_ssh_config = true): aliases, HostName, User, Port,
IdentityFile and even ProxyJump work exactly as they do for the plain
ssh client. Anything set explicitly in fleet.toml wins.
Then run:
sshfleet # uses ./fleet.toml or ~/.config/sshfleet/fleet.toml
sshfleet --config other.toml # explicit path
sshfleet --interval 5 # override the configured intervalNo fleet at hand? Try the synthetic one:
sshfleet --demoIt generates ten hosts with random-walking metrics — including one permanently down and one with broken credentials, so every UI state is visible.
| Key | Action |
|---|---|
r |
poll all hosts immediately |
p |
pause / resume background polling |
enter |
open detail view for the selected host |
s |
sort by the column under the cursor (press again to flip direction) |
? |
keymap overlay |
esc |
close overlay |
q |
quit |
[defaults]
| Key | Type | Default | Meaning |
|---|---|---|---|
user |
string | current user | SSH username fallback |
port |
int | – | port fallback (unset = ssh config / 22) |
interval |
float | 10 | seconds between poll cycles |
timeout |
float | 8 | login/command timeout per host |
max_concurrent |
int | 8 | simultaneous probes upper bound |
identity_file |
path | – | private key fallback (~ is expanded) |
password |
string | – | password fallback (avoid; prefer keys/agent) |
verify_hosts |
bool | true | check server keys against known_hosts |
import_ssh_config |
bool | true | resolve hosts through ~/.ssh/config |
warn_pct |
float | 70 | yellow threshold for CPU/MEM/DISK/LOAD |
crit_pct |
float | 88 | red threshold for CPU/MEM/DISK/LOAD |
Every key can be overridden per host in [[hosts]]; only host itself is
required, name defaults to the address and must be unique.
SSHFleet authenticates exactly like your normal SSH client, in this order of preference:
- SSH agent — nothing to configure, just have
ssh-addloaded. - Default keys —
~/.ssh/id_ed25519,~/.ssh/id_rsa, and friends. - Explicit key —
identity_filein[defaults]or per host. - Password — set
passwordin[defaults]or per host. Note it sits in the TOML as plaintext, sochmod 600 fleet.tomland prefer the options above whenever you can.
Each cycle probes every host concurrently under a semaphore. The first successful contact reuses its connection for later cycles; a transport error triggers exactly one reconnect before the host flips to unreachable. Auth failures are never retried. CPU usage needs two samples, so the column fills in on the second poll after startup or reconnect.
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest # unit + TUI tests, no real servers involved
ruff check .
mypy sshfleet
python scripts/make_preview.py # regenerate assets/*.svg from the demo fleetThe collector's SSH layer is fully injectable: tests drive scripted fake
connections instead of sockets, and the same seam powers --demo.
MIT — see LICENSE.