Skip to content

Alex4210987/ssh-watch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ssh-watch

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

Features

  • Reads host aliases from ~/.ssh/config automatically (follows Include directives)
  • Live full-screen dashboard (--top) with color: green = reachable, red = down
  • Sparkline history column: block height ∝ latency, × = failed probe
  • FOR column 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

Requirements

  • Python ≥ 3.8
  • ssh in 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; use ssh-agent or authorized_keys for passwordless access.

Installation

git clone https://github.com/Alex4210987/ssh-watch.git
cd ssh-watch
chmod +x ssh_watch.py

Optionally symlink to your PATH:

ln -s "$PWD/ssh_watch.py" /usr/local/bin/ssh-watch

Usage

Live dashboard (recommended)

python3 ssh_watch.py --top

Key bindings in dashboard

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

macOS notifications

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 N consecutive failures
python3 ssh_watch.py --top --notify

Raise 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 3

Tune 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 2

Notifications use terminal-notifier first (with osascript fallback on macOS).

Batch mode (single pass, for scripts)

python3 ssh_watch.py              # check all hosts, print table
python3 ssh_watch.py -q           # only print failures

Exit code is 0 if all hosts are up, 1 if any are down.

Common options

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

Examples

# 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

How it works

  1. Parses ~/.ssh/config to collect all literal Host aliases (wildcard patterns like Host *.internal are skipped — they can't be dialed directly).

  2. For each host, spawns:

    ssh -o BatchMode=yes -o ConnectTimeout=N -o NumberOfPasswordPrompts=0 <host> true
  3. Exit code 0 → host is UP; anything else → DOWN.

  4. In --top mode, a background thread runs probe rounds in a loop; the curses UI refreshes independently at ~12 fps.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages