socktop/README.md

248 lines
6.9 KiB
Markdown
Raw Normal View History

2025-08-08 08:06:43 +00:00
# socktop
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
**socktop** is a remote system monitor with a rich TUI interface, inspired by `top` and `btop`, that communicates with a lightweight remote agent over WebSockets.
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
It lets you watch CPU, memory, disks, network, temperatures, and processes on another machine in real-time — from the comfort of your terminal.
2025-08-08 08:03:35 +00:00
Major refactor, additional comments, performance improvements, idle performance improvements, access token, port specification Release highlights Introduced split client/agent architecture with a ratatui-based TUI and a lightweight WebSocket agent. Added adaptive (idle-aware) sampler: agent samples fast only when clients are connected; sleeps when idle. Implemented metrics JSON caching for instant ws replies; cold-start does one-off collection. Port configuration: --port/-p, positional PORT, or SOCKTOP_PORT env (default 3000). Optional token auth: SOCKTOP_TOKEN on agent, ws://HOST:PORT/ws?token=VALUE in client. Logging via tracing with RUST_LOG control. CI workflow (fmt, clippy, build) for Linux and Windows. Systemd unit example for always-on agent. TUI features CPU: overall sparkline + per-core history with trend arrows and color thresholds. Memory/Swap gauges with humanized labels. Disks panel with per-device usage and icons. Network download/upload sparklines (KB/s) with peak tracking. Top processes table (PID, name, CPU%, mem, mem%). Header with hostname and CPU temperature indicator. Agent changes sysinfo 0.36.1 targeted refresh: refresh_cpu_all, refresh_memory, refresh_processes_specifics(ProcessesToUpdate::All, ProcessRefreshKind::new().with_cpu().with_memory(), true). WebSocket handler: client counting with wake notifications, cold-start handling, proper Response returns. Sampler uses MissedTickBehavior::Skip to avoid catch-up bursts. Docs README updates: running instructions, port configuration, optional token auth, platform notes, example JSON. Added socktop-agent.service systemd unit. Platform notes Linux (AMD/Intel) supported; tested on AMD, targeting Intel next. Raspberry Pi supported (availability of temps varies by model). Windows builds/run; CPU temperature may be unavailable (shows N/A). Known/next Roadmap includes configurable refresh interval, TUI filtering/sorting, TLS/WSS, and export to file. Add Context... README.md
2025-08-08 19:41:32 +00:00
![socktop screenshot](./docs/socktop-screenshot.png)
2025-08-08 08:03:35 +00:00
---
2025-08-08 08:06:43 +00:00
## Features
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
- 📡 **Remote monitoring** via WebSocket — lightweight agent sends JSON metrics
- 🖥 **Rich TUI** built with [ratatui](https://github.com/ratatui-org/ratatui)
- 🔍 **Detailed CPU view** — per-core history, current load, and trends
- 📊 **Memory, Swap, Disk usage** — human-readable units, color-coded
- 🌡 **Temperatures** — CPU temperature with visual indicators
- 📈 **Network throughput** — live sparkline graphs with peak tracking
- 🏷 **Top processes table** — PID, name, CPU%, memory, and memory%
- 🎨 Color-coded load, zebra striping for readability
-**Keyboard shortcuts**:
- `q` / `Esc` → Quit
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
---
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
## Architecture
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
`socktop` has **two components**:
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
1. **Agent** (remote side)
A small Rust WebSocket server that runs on the target machine and gathers metrics via [sysinfo](https://crates.io/crates/sysinfo).
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
2. **Client** (local side)
The TUI app (`socktop`) that connects to the agents `/ws` endpoint, receives JSON metrics, and renders them.
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
The two communicate over a persistent WebSocket connection.
2025-08-08 08:03:35 +00:00
---
Major refactor, additional comments, performance improvements, idle performance improvements, access token, port specification Release highlights Introduced split client/agent architecture with a ratatui-based TUI and a lightweight WebSocket agent. Added adaptive (idle-aware) sampler: agent samples fast only when clients are connected; sleeps when idle. Implemented metrics JSON caching for instant ws replies; cold-start does one-off collection. Port configuration: --port/-p, positional PORT, or SOCKTOP_PORT env (default 3000). Optional token auth: SOCKTOP_TOKEN on agent, ws://HOST:PORT/ws?token=VALUE in client. Logging via tracing with RUST_LOG control. CI workflow (fmt, clippy, build) for Linux and Windows. Systemd unit example for always-on agent. TUI features CPU: overall sparkline + per-core history with trend arrows and color thresholds. Memory/Swap gauges with humanized labels. Disks panel with per-device usage and icons. Network download/upload sparklines (KB/s) with peak tracking. Top processes table (PID, name, CPU%, mem, mem%). Header with hostname and CPU temperature indicator. Agent changes sysinfo 0.36.1 targeted refresh: refresh_cpu_all, refresh_memory, refresh_processes_specifics(ProcessesToUpdate::All, ProcessRefreshKind::new().with_cpu().with_memory(), true). WebSocket handler: client counting with wake notifications, cold-start handling, proper Response returns. Sampler uses MissedTickBehavior::Skip to avoid catch-up bursts. Docs README updates: running instructions, port configuration, optional token auth, platform notes, example JSON. Added socktop-agent.service systemd unit. Platform notes Linux (AMD/Intel) supported; tested on AMD, targeting Intel next. Raspberry Pi supported (availability of temps varies by model). Windows builds/run; CPU temperature may be unavailable (shows N/A). Known/next Roadmap includes configurable refresh interval, TUI filtering/sorting, TLS/WSS, and export to file. Add Context... README.md
2025-08-08 19:41:32 +00:00
## Adaptive (idle-aware) sampling
The socktop agent now samples system metrics only when at least one WebSocket client is connected. When idle (no clients), the sampler sleeps and CPU usage drops to ~0%.
How it works
- The WebSocket handler increments/decrements a client counter in `AppState` on connect/disconnect.
- A background sampler wakes when the counter transitions from 0 → >0 and sleeps when it returns to 0.
- The most recent metrics snapshot is cached as JSON for fast responses.
Cold start behavior
- If a client requests metrics while the cache is empty (e.g., just started or after a long idle), the agent performs a one-off synchronous collection to respond immediately.
Tuning
- Sampling interval (active): update `spawn_sampler(state, Duration::from_millis(500))` in `socktop_agent/src/main.rs`.
- Always-on or low-frequency idle sampling: replace the “sleep when idle” logic in `socktop_agent/src/sampler.rs` with a low-frequency interval. Example sketch:
```rust
// In sampler.rs (sketch): sample every 10s when idle, 500ms when active
let idle_period = Duration::from_secs(10);
loop {
let active = state.client_count.load(Ordering::Relaxed) > 0;
let period = if active { Duration::from_millis(500) } else { idle_period };
let mut ticker = tokio::time::interval(period);
ticker.tick().await;
if !active {
// wake early if a client connects
tokio::select! {
_ = ticker.tick() => {},
_ = state.wake_sampler.notified() => continue,
}
}
let m = collect_metrics(&state).await;
if let Ok(js) = serde_json::to_string(&m) {
*state.last_json.write().await = js;
}
}
```
---
2025-08-08 08:06:43 +00:00
## Installation
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
### Prerequisites
- Rust 1.75+ (recommended latest stable)
- Cargo package manager
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
### Build from source
2025-08-08 08:03:35 +00:00
```bash
2025-08-08 08:06:43 +00:00
git clone https://github.com/YOURNAME/socktop.git
cd socktop
cargo build --release
2025-08-08 08:03:35 +00:00
```
2025-08-08 08:06:43 +00:00
### Install as a cargo binary
```bash
cargo install --path .
```
This will install the `socktop` binary into `~/.cargo/bin`.
2025-08-08 08:03:35 +00:00
---
2025-08-08 08:06:43 +00:00
## Running
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
### 1. Start the agent on the remote machine
The agent binary listens on a TCP port and serves `/ws`:
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
```bash
remote_agent 0.0.0.0:8080
```
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
> **Tip:** You can run the agent under `systemd`, inside a Docker container, or just in a tmux/screen session.
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
### 2. Connect with the client
From your local machine:
2025-08-08 08:03:35 +00:00
```bash
2025-08-08 08:06:43 +00:00
socktop ws://REMOTE_HOST:8080/ws
```
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
Example:
```bash
socktop ws://192.168.1.50:8080/ws
2025-08-08 08:03:35 +00:00
```
---
2025-08-08 08:06:43 +00:00
## Usage
When connected, `socktop` displays:
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
**Left column:**
- **CPU avg graph** — sparkline of recent overall CPU usage
- **Memory gauge** — total and used RAM
- **Swap gauge** — total and used swap
- **Disks** — usage per device (only devices with available space > 0)
- **Network Download/Upload** — sparkline in KB/s, with current & peak values
**Right column:**
- **Per-core history & trends** — each cores recent load, current %, and trend arrow
- **Top processes table** — top 20 processes with PID, name, CPU%, memory usage, and memory%
2025-08-08 08:03:35 +00:00
---
Major refactor, additional comments, performance improvements, idle performance improvements, access token, port specification Release highlights Introduced split client/agent architecture with a ratatui-based TUI and a lightweight WebSocket agent. Added adaptive (idle-aware) sampler: agent samples fast only when clients are connected; sleeps when idle. Implemented metrics JSON caching for instant ws replies; cold-start does one-off collection. Port configuration: --port/-p, positional PORT, or SOCKTOP_PORT env (default 3000). Optional token auth: SOCKTOP_TOKEN on agent, ws://HOST:PORT/ws?token=VALUE in client. Logging via tracing with RUST_LOG control. CI workflow (fmt, clippy, build) for Linux and Windows. Systemd unit example for always-on agent. TUI features CPU: overall sparkline + per-core history with trend arrows and color thresholds. Memory/Swap gauges with humanized labels. Disks panel with per-device usage and icons. Network download/upload sparklines (KB/s) with peak tracking. Top processes table (PID, name, CPU%, mem, mem%). Header with hostname and CPU temperature indicator. Agent changes sysinfo 0.36.1 targeted refresh: refresh_cpu_all, refresh_memory, refresh_processes_specifics(ProcessesToUpdate::All, ProcessRefreshKind::new().with_cpu().with_memory(), true). WebSocket handler: client counting with wake notifications, cold-start handling, proper Response returns. Sampler uses MissedTickBehavior::Skip to avoid catch-up bursts. Docs README updates: running instructions, port configuration, optional token auth, platform notes, example JSON. Added socktop-agent.service systemd unit. Platform notes Linux (AMD/Intel) supported; tested on AMD, targeting Intel next. Raspberry Pi supported (availability of temps varies by model). Windows builds/run; CPU temperature may be unavailable (shows N/A). Known/next Roadmap includes configurable refresh interval, TUI filtering/sorting, TLS/WSS, and export to file. Add Context... README.md
2025-08-08 19:41:32 +00:00
## Configuring the agent port
The agent listens on TCP port 3000 by default. You can override this via a CLI flag, a positional port argument, or an environment variable:
- CLI flag:
- socktop_agent --port 8080
- socktop_agent -p 8080
- Positional:
- socktop_agent 8080
- Environment variable:
- SOCKTOP_PORT=8080 socktop_agent
Help:
- socktop_agent --help
The TUI should point to ws://HOST:PORT/ws, e.g.:
- cargo run -p socktop -- ws://127.0.0.1:8080/ws
---
2025-08-08 08:06:43 +00:00
## Keyboard Shortcuts
| Key | Action |
|-------------|------------|
| `q` or `Esc`| Quit |
2025-08-08 08:03:35 +00:00
2025-08-08 08:06:43 +00:00
---
Major refactor, additional comments, performance improvements, idle performance improvements, access token, port specification Release highlights Introduced split client/agent architecture with a ratatui-based TUI and a lightweight WebSocket agent. Added adaptive (idle-aware) sampler: agent samples fast only when clients are connected; sleeps when idle. Implemented metrics JSON caching for instant ws replies; cold-start does one-off collection. Port configuration: --port/-p, positional PORT, or SOCKTOP_PORT env (default 3000). Optional token auth: SOCKTOP_TOKEN on agent, ws://HOST:PORT/ws?token=VALUE in client. Logging via tracing with RUST_LOG control. CI workflow (fmt, clippy, build) for Linux and Windows. Systemd unit example for always-on agent. TUI features CPU: overall sparkline + per-core history with trend arrows and color thresholds. Memory/Swap gauges with humanized labels. Disks panel with per-device usage and icons. Network download/upload sparklines (KB/s) with peak tracking. Top processes table (PID, name, CPU%, mem, mem%). Header with hostname and CPU temperature indicator. Agent changes sysinfo 0.36.1 targeted refresh: refresh_cpu_all, refresh_memory, refresh_processes_specifics(ProcessesToUpdate::All, ProcessRefreshKind::new().with_cpu().with_memory(), true). WebSocket handler: client counting with wake notifications, cold-start handling, proper Response returns. Sampler uses MissedTickBehavior::Skip to avoid catch-up bursts. Docs README updates: running instructions, port configuration, optional token auth, platform notes, example JSON. Added socktop-agent.service systemd unit. Platform notes Linux (AMD/Intel) supported; tested on AMD, targeting Intel next. Raspberry Pi supported (availability of temps varies by model). Windows builds/run; CPU temperature may be unavailable (shows N/A). Known/next Roadmap includes configurable refresh interval, TUI filtering/sorting, TLS/WSS, and export to file. Add Context... README.md
2025-08-08 19:41:32 +00:00
## Security (optional token)
By default, the agent exposes metrics over an unauthenticated WebSocket. For untrusted networks, set an auth token and pass it in the client URL:
- Server:
- SOCKTOP_TOKEN=changeme socktop_agent --port 3000
- Client:
- socktop ws://HOST:3000/ws?token=changeme
---
## Platform notes
- Linux x86_64/AMD/Intel: fully supported.
- Raspberry Pi:
- 64-bit: rustup target add aarch64-unknown-linux-gnu; build on-device for simplicity.
- 32-bit: rustup target add armv7-unknown-linux-gnueabihf.
- Windows:
- TUI and agent build/run with stable Rust. Use PowerShell:
- cargo run -p socktop_agent -- --port 3000
- cargo run -p socktop -- ws://127.0.0.1:3000/ws
- CPU temperature may be unavailable; display will show N/A.
---
2025-08-08 08:06:43 +00:00
## Example agent JSON
`socktop` expects the agent to send metrics in this shape:
```json
{
"cpu_total": 12.4,
"cpu_per_core": [11.2, 15.7, ...],
"mem_total": 33554432,
"mem_used": 18321408,
"swap_total": 0,
"swap_used": 0,
"process_count": 127,
"hostname": "myserver",
"cpu_temp_c": 42.5,
"disks": [{"name":"nvme0n1p2","total":512000000000,"available":320000000000}],
"networks": [{"name":"eth0","received":12345678,"transmitted":87654321}],
"top_processes": [
{"pid":1234,"name":"nginx","cpu_usage":1.2,"mem_bytes":12345678}
]
}
```
---
## Development
### Run in debug mode:
```bash
cargo run -- ws://127.0.0.1:8080/ws
```
### Code formatting & lint:
2025-08-08 08:03:35 +00:00
```bash
2025-08-08 08:06:43 +00:00
cargo fmt
cargo clippy
2025-08-08 08:03:35 +00:00
```
---
2025-08-08 08:06:43 +00:00
## Roadmap
- [ ] Configurable refresh interval
- [ ] Filter/sort top processes in the TUI
- [ ] Export metrics to file
- [ ] TLS / WSS support
- [ ] Agent authentication
---
## License
MIT License — see [LICENSE](LICENSE).
---
## Acknowledgements
- [`ratatui`](https://github.com/ratatui-org/ratatui) for terminal UI rendering
- [`sysinfo`](https://crates.io/crates/sysinfo) for system metrics
- [`tokio-tungstenite`](https://crates.io/crates/tokio-tungstenite) for WebSocket client/server