A terminal tool for monitoring whether SSH servers in your ~/.ssh/config can be logged into — with a live full-screen dashboard (like top) and per-host latency sparklines.
Terminal dashboard (sample):
ssh-watch │ UP 3/8 ████████░░░░░░ │ 14:23:01 │ last 5.2s
[q]uit [r]efresh [s]ort [↑↓]scroll int 8s │ history ▁▂…█ = latency × = fail
HOST ST MS FOR HISTORY
devbox UP 312 23m10s ▃▃▄▃▄▄▃▂▃▃▅▄▃▄▄▄▂▃▂▃▃▄▃▃▄▂▃
work-gpu UP 892 2h04m ▅▄▆▅▅▄▆▅▅▄▅▄▄▄▅▅▄▃▄▅▄▆▅▄▅▄▃
myvm UP 145 14m52s ▁▁▂▁▂▁▁▂▁▂▁▁▂▂▁▂▁▂▁▁▂▁▁▁▂▁▁
cancon.hpccube.com DN 863 52m33s ×××××××××××× Permission denied (publickey)
162.105.146.175 DN 5042 1d02h ×××××××××××× Connection timed out
- Reads host aliases from
~/.ssh/configautomatically (followsIncludedirectives) - Live full-screen dashboard (
--top) with color: green = reachable, red = down - Sparkline history column: block height ∝ latency,
×= failed probe FORcolumn shows how long current state (UP/DN) has been continuous- Parallel probing — checks dozens of hosts in seconds
- Batch mode (no
--top) for scripts / cron use; non-zero exit if any host is down - Zero dependencies — pure Python 3.8+ stdlib
- Python ≥ 3.8
sshin your$PATH- Hosts configured with key-based (non-interactive) authentication
Note: Probes use
BatchMode=yes— hosts requiring a password will show as DOWN. This is intentional; usessh-agentorauthorized_keysfor passwordless access.
git clone https://github.com/Alex4210987/ssh-watch.git
cd ssh-watch
chmod +x ssh_watch.pyOptionally symlink to your PATH:
ln -s "$PWD/ssh_watch.py" /usr/local/bin/ssh-watchpython3 ssh_watch.py --top| Key | Action |
|---|---|
q |
Quit |
r |
Refresh immediately (skip interval wait) |
s |
Toggle sort: fail-first ↔ alphabetical |
↑ / ↓ |
Scroll host list |
Home / End |
Jump to top / bottom |
Add --notify to get native macOS banners automatically:
- Down alert: uses progressive backoff, default thresholds are
N,2N,4N,8N... - Recovery alert: fires once when a host recovers after reaching at least
Nconsecutive failures
python3 ssh_watch.py --top --notifyRaise or lower the threshold with --notify-fail-streak N (default: 10):
# Alert after 3 consecutive failures
python3 ssh_watch.py --top --notify --notify-fail-streak 3Tune the backoff multiplier (default 2.0) with --notify-backoff:
# Thresholds: 3, 6, 12, 24...
python3 ssh_watch.py --top --notify --notify-fail-streak 3 --notify-backoff 2Notifications use
terminal-notifierfirst (withosascriptfallback on macOS).
python3 ssh_watch.py # check all hosts, print table
python3 ssh_watch.py -q # only print failuresExit code is 0 if all hosts are up, 1 if any are down.
| Flag | Default | Description |
|---|---|---|
-c FILE |
~/.ssh/config |
Use a different SSH config file |
--hosts A B … |
(all) | Only check these aliases |
-i SEC |
8 |
Probe interval in --top mode |
-j N |
12 |
Parallel probes |
--connect-timeout SEC |
5 |
SSH ConnectTimeout |
--timeout SEC |
25 |
Hard subprocess timeout |
--command CMD |
true |
Remote command to run (default is instant) |
--notify |
off | Enable macOS notifications |
--notify-fail-streak N |
10 |
Consecutive fails before down alert |
--notify-backoff K |
2.0 |
Growth multiplier for next fail alert interval |
# Only monitor a subset of hosts every 15 seconds
python3 ssh_watch.py --top --hosts myvm work devbox -i 15
# High concurrency for large inventories
python3 ssh_watch.py --top -j 40 --connect-timeout 3
# Cron-friendly: alert on any failure
python3 ssh_watch.py -q && echo "all up" || echo "some hosts down"
# Use a non-default config (e.g. a project-specific one)
python3 ssh_watch.py -c ~/projects/infra/.ssh/config --top-
Parses
~/.ssh/configto collect all literalHostaliases (wildcard patterns likeHost *.internalare skipped — they can't be dialed directly). -
For each host, spawns:
ssh -o BatchMode=yes -o ConnectTimeout=N -o NumberOfPasswordPrompts=0 <host> true
-
Exit code 0 → host is UP; anything else → DOWN.
-
In
--topmode, a background thread runs probe rounds in a loop; the curses UI refreshes independently at ~12 fps.
MIT