Introduction
socktop is a TUI-first remote system monitor built with Rust. Two components:
- socktop (TUI Client) - A terminal-based user interface for viewing system metrics
- socktop_agent - A lightweight background service that collects and serves system metrics over WebSocket
Features
- TUI built with ratatui, Catppuccin Frappe theme
- CPU: overall sparkline + per-core bars, accurate per-process CPU% (normalized 0-100%)
- Memory/Swap gauges
- Disks: per-device usage
- Network: per-interface throughput with sparklines
- Temperatures: CPU (optional)
- Process list: fuzzy search, sortable by CPU% or memory, scrollable
- Process details: command line, working directory, per-thread CPU, journal entries
- Kill local processes from the TUI (Terminate / Force kill, with confirmation)
- Optional GPU metrics
- Compact layout for small terminal windows (automatic, or pinned with
--compact) - Remote monitoring via WebSocket (JSON over WS)
- Optional WSS (TLS): agent auto-generates self-signed cert on first run, client pins cert via –tls-ca/-t
- Optional auth token
- Connection profiles for quick access to saved hosts
- Built-in demo mode (–demo)
Architecture
socktop uses a client-server architecture:
┌─────────────────┐ WebSocket ┌──────────────────┐
│ │ ◄────────────────────────► │ │
│ socktop (TUI) │ (with TLS optional) │ socktop-agent │
│ Client │ │ (Background) │
│ │ │ │
└─────────────────┘ └──────────────────┘
│ │
│ │
▼ ▼
User Terminal System Metrics
Local or Remote (sysinfo crate)
The agent runs on each system you want to monitor, collecting metrics using the sysinfo crate. The client connects to one or more agents to display real-time system information.
Quick Demo
socktop --demo
Spins up a temporary local agent on port 3231 and connects to it. Stops automatically when you quit.
Use Cases
- Remote server monitoring
- Homelab / Raspberry Pi cluster monitoring
- Development / testing resource usage
- Custom dashboards via
socktop_connectorlibrary
Project Status
socktop is actively maintained and used in production environments. The project follows semantic versioning and maintains backward compatibility within major versions.
- Current Version: 1.60.x — see GitHub Releases for release notes
- Supported Platforms: Linux (amd64, arm64, armhf, riscv64), Windows, macOS (client) — see Platform Notes
- License: MIT
Wire changes between versions are additive: mixed client/agent versions keep working during rollouts.
Community and Support
- GitHub Repository: https://github.com/jasonwitty/socktop
- Release Notes: GitHub Releases
- Issue Tracker: Report bugs and request features on GitHub
- crates.io:
- socktop - TUI client
- socktop_agent - Background agent
- socktop_connector - Library for integrations
- APT Repository: https://jasonwitty.github.io/socktop/
Next Steps
See Quick Start for installation.
Quick Start
Installation Methods
socktop can be installed via APT (Debian/Ubuntu), Cargo, or built from source.
Option 1: APT Installation (Recommended for Debian/Ubuntu)
Debian/Ubuntu installation:
# Add the repository's GPG signing key
curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
# Add the APT repository
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" | \
sudo tee /etc/apt/sources.list.d/socktop.list
# Update the package list
sudo apt update
# Install socktop and the agent
sudo apt install socktop socktop-agent
# Enable the agent service
sudo systemctl enable --now socktop-agent
Then connect to it: socktop ws://localhost:3000/ws — or to any remote agent by hostname.
Option 2: Cargo Installation
Install from crates.io:
# Install GPU support libraries (see Prerequisites for other distros)
sudo apt install libdrm-dev libdrm-amdgpu1
# Install the TUI client
cargo install socktop
# Install the agent
cargo install socktop_agent
# Run the agent manually or set up as a service (see Agent Service Setup)
socktop_agent
Demo Mode
Test socktop without setting up an agent:
# If you have socktop installed
socktop --demo
# Or just run socktop with no arguments and select 'demo' from the interactive menu
socktop
This spins up a temporary local agent on port 3231, connects to it, and stops when you quit (Ctrl-C or q).
Usage
# Quick demo (no agent setup needed)
socktop --demo
# Connect to an agent (local or remote) — note the /ws path
socktop ws://localhost:3000/ws
socktop ws://hostname:3000/ws
# Or run socktop with no arguments to pick a saved profile interactively
socktop
The TUI displays system metrics in real-time.
Interactive Profile Selection
If you run socktop with no arguments, you’ll see an interactive menu:
Select profile:
1. prod
2. dev-server
3. demo
Enter number (or blank to abort):
- Choose a numbered profile to connect to a saved server
- Select
demoto launch demo mode (always available) - Press Enter on blank to abort
Monitoring Remote Systems
To monitor a remote system:
- Install the agent on the target system (using APT or Cargo)
- Start the agent on the remote system:
# Via systemd (APT install) sudo systemctl start socktop-agent # Or manually socktop_agent - Connect from your client:
socktop ws://remote-hostname:3000/ws
Save frequently used connections as profiles. See Connection Profiles.
Prerequisites
Supported Operating Systems
- Debian 10+
- Ubuntu 20.04+
- Arch Linux (latest)
- Fedora 35+
- Raspberry Pi OS
- Other Linux distributions with kernel 4.15+
- Windows 10+ (binaries available in build artifacts)
- macOS (client; the agent runs but is primarily targeted at Linux)
See Platform Notes for platform-specific details.
Supported Architectures
- amd64 (x86_64)
- arm64 (aarch64) - Raspberry Pi 4, AWS Graviton
- armhf (ARMv7) - Raspberry Pi 3
- riscv64 (experimental)
Software Dependencies
GPU support requires additional libraries (x86_64 and aarch64 only):
Debian/Ubuntu/Raspberry Pi OS:
sudo apt update
sudo apt install libdrm-dev libdrm-amdgpu1
Fedora:
sudo dnf install libdrm-devel libdrm-amdgpu
On ARMv7 (32-bit) and RISC-V, GPU support is not available — build the agent with --no-default-features:
cargo build --release -p socktop_agent --no-default-features
For Cargo Installation
1. Rust Toolchain
A current stable Rust toolchain is required (the crates use the 2024 edition, so Rust 1.85+).
# Install Rust via rustup (recommended)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Verify installation
rustc --version
cargo --version
# Update if needed
rustup update
2. Build Dependencies
Debian/Ubuntu:
sudo apt install build-essential pkg-config libssl-dev libdrm-dev libdrm-amdgpu1
Fedora:
sudo dnf install gcc pkg-config openssl-devel libdrm-devel libdrm-amdgpu
Arch Linux:
sudo pacman -S base-devel openssl libdrm
Install via Cargo
Installing socktop via Cargo gives you access to the latest version and works on any Linux distribution with Rust installed.
Prerequisites
Before installing via Cargo, ensure you have:
- Current stable Rust (1.85+, 2024 edition) - Install via rustup
- Build dependencies - See Prerequisites for details
- GPU support libraries (x86_64/aarch64):
# Debian/Ubuntu sudo apt install libdrm-dev libdrm-amdgpu1 # Fedora sudo dnf install libdrm-devel libdrm-amdgpu
Installation
Installing the TUI Client
cargo install socktop
This will download, compile, and install the socktop binary to ~/.cargo/bin/. Make sure this directory is in your PATH.
Installing the Agent
cargo install socktop_agent
This installs the socktop_agent binary to ~/.cargo/bin/.
Installing Both (Recommended)
cargo install socktop socktop_agent
Verify Installation
Check that the binaries are installed correctly:
# Check socktop client
socktop --version
# Check socktop agent
socktop_agent --version
You should see output like:
socktop 1.60.1
First Run
Start the Agent
Start the agent in a separate terminal or background process:
# Run in foreground (for testing)
socktop_agent
# Run in background
socktop_agent &
# Or on a custom port
socktop_agent --port 3000
Connect with the Client
In another terminal, connect to the agent:
socktop ws://localhost:3000/ws
Or just try demo mode (starts and stops its own local agent):
socktop --demo
Configuration
The agent is configured with a small set of flags (--port/-p, --enableSSL) and environment variables (SOCKTOP_TOKEN, SOCKTOP_AGENT_GPU=0, …). The client connects by URL or saved profile:
# Remote connection
socktop ws://192.168.1.100:3000/ws
# Secure connection with a pinned certificate
socktop --tls-ca /path/to/cert.pem wss://secure-host:8443/ws
# Using a connection profile
socktop -P my-server
See Configuration for the complete reference and Connection Profiles for profiles.
System-wide agent (Linux)
# If you installed with cargo, binaries are in ~/.cargo/bin
sudo install -o root -g root -m 0755 "$HOME/.cargo/bin/socktop_agent" /usr/local/bin/socktop_agent
# Install and enable the systemd service (example unit in docs/)
sudo install -o root -g root -m 0644 docs/socktop-agent.service /etc/systemd/system/socktop-agent.service
sudo systemctl daemon-reload
sudo systemctl enable --now socktop-agent
Install via APT
The easiest way to install socktop on Debian and Ubuntu systems is through the official APT repository.
Supported Systems
The APT repository supports:
- Debian 10+ (Buster and newer)
- Ubuntu 20.04+ (Focal and newer)
- Raspberry Pi OS (Debian-based)
- Other Debian derivatives
Supported Architectures
- amd64 (x86_64)
- arm64 (aarch64)
- armhf (ARMv7)
- riscv64 (experimental)
Installation
Step 1: Add GPG Signing Key
First, add the repository’s GPG signing key to verify package authenticity:
curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
This ensures that packages are cryptographically verified before installation.
Step 2: Add APT Repository
Add the socktop repository to your system’s sources list:
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" | \
sudo tee /etc/apt/sources.list.d/socktop.list
Step 3: Update Package Lists
Refresh your package cache to include the new repository:
sudo apt update
Step 4: Install Packages
Install socktop and the agent:
# Install both client and agent
sudo apt install socktop socktop-agent
# Or install individually
sudo apt install socktop # TUI client only
sudo apt install socktop-agent # Agent only
Automatic Service Setup
The APT package automatically configures the agent as a systemd service, but it’s not enabled by default.
Enable and Start the Agent
# Enable the service to start at boot
sudo systemctl enable socktop-agent
# Start the service now
sudo systemctl start socktop-agent
# Or do both in one command
sudo systemctl enable --now socktop-agent
Check Service Status
# View service status
sudo systemctl status socktop-agent
# View service logs
sudo journalctl -u socktop-agent -f
# View recent logs
sudo journalctl -u socktop-agent -n 50
Control the Service
# Stop the service
sudo systemctl stop socktop-agent
# Restart the service
sudo systemctl restart socktop-agent
# Disable auto-start
sudo systemctl disable socktop-agent
Agent Service Setup
APT Installation
If you installed via APT, the service is already configured:
sudo systemctl enable --now socktop-agent
Cargo Installation
System-wide agent setup:
# If you installed with cargo, binaries are in ~/.cargo/bin
sudo install -o root -g root -m 0755 "$HOME/.cargo/bin/socktop_agent" /usr/local/bin/socktop_agent
# Install and enable the systemd service (example unit in docs/)
sudo install -o root -g root -m 0644 docs/socktop-agent.service /etc/systemd/system/socktop-agent.service
sudo systemctl daemon-reload
sudo systemctl enable --now socktop-agent
Enable SSL
# Stop service
sudo systemctl stop socktop-agent
# Edit service to append SSL option and port
sudo nano /etc/systemd/system/socktop-agent.service
# Change ExecStart line to:
# ExecStart=/usr/local/bin/socktop_agent --enableSSL --port 8443
# Reload
sudo systemctl daemon-reload
# Restart
sudo systemctl start socktop-agent
# Check logs for certificate location
sudo journalctl -u socktop-agent -f
# Example output:
# Aug 22 22:25:26 rpi-master socktop_agent[2913998]: socktop_agent: generated self-signed TLS certificate at /var/lib/socktop/.config/socktop_agent/tls/cert.pem
Configuration
Agent configuration via command-line flags or environment variables:
Port:
- Flag:
--port 8080or-p 8080 - Env:
SOCKTOP_PORT=8080
TLS (self-signed):
- Enable:
--enableSSL - Default TLS port: 8443 (override with
--port/-p) - Certificate/Key location (created on first TLS run):
- Linux (XDG):
$XDG_CONFIG_HOME/socktop_agent/tls/{cert.pem,key.pem}(defaults to~/.config) - The agent prints these paths on creation
- Note: when running as the packaged service, the service user’s home is
/var/lib/socktop, so certs land under/var/lib/socktop/.config/socktop_agent/tls/
- Linux (XDG):
Auth token (optional): SOCKTOP_TOKEN=changeme
Disable GPU metrics: SOCKTOP_AGENT_GPU=0
Disable CPU temperature: SOCKTOP_AGENT_TEMP=0
See Configuration for the complete reference, including tuning variables.
Journal Access (Process Details)
The process-details view can show recent journal entries for a process. The agent reads them with journalctl, so it needs permission to read the system journal. If it can’t, the TUI shows a journal-access notice instead of entries (rather than a misleading “no entries”).
The packaged service runs as the socktop user. To grant journal access:
sudo usermod -aG systemd-journal socktop
sudo systemctl restart socktop-agent
An agent run ad hoc as your own user can typically only read your user journal; run it as a service (or as a user in the systemd-journal group) to see entries for system services.
Managing the Service
Basic Commands
# Start the service
sudo systemctl start socktop-agent
# Stop the service
sudo systemctl stop socktop-agent
# Restart the service
sudo systemctl restart socktop-agent
# Reload configuration (if supported)
sudo systemctl reload socktop-agent
# View service status
sudo systemctl status socktop-agent
# Enable auto-start on boot
sudo systemctl enable socktop-agent
# Disable auto-start on boot
sudo systemctl disable socktop-agent
# Enable and start in one command
sudo systemctl enable --now socktop-agent
Logs
# Follow live logs
sudo journalctl -u socktop-agent -f
# View recent logs
sudo journalctl -u socktop-agent -n 50
Status
# Check status
sudo systemctl status socktop-agent --no-pager
# Is the service running?
sudo systemctl is-active socktop-agent
Updating
See Upgrading.
Upgrading
This guide covers upgrading socktop and socktop_agent to newer versions.
Upgrade Order
Mixed versions keep working during rollouts (wire changes are additive), but two things set the order:
- Upgrade clients first where you use TLS. Versions before 1.60 did not actually enforce certificate pinning — any server certificate was accepted. The fix is client-side.
- Upgrade agent and client together on machines where you use the process kill feature — older agents keep reporting dead processes, so killed rows would linger on screen.
Upgrading via APT
Standard Upgrade
The easiest method - upgrade through normal system updates:
# Update package lists
sudo apt update
# Upgrade socktop packages
sudo apt upgrade socktop socktop-agent
# Or upgrade entire system
sudo apt upgrade
The service will automatically restart after the upgrade.
Verify Upgrade
# Check new versions
socktop --version
socktop_agent --version
# Check service status
sudo systemctl status socktop-agent
Tip: if socktop --version still shows the old version after upgrading, an older copy in ~/.cargo/bin may be shadowing the new one on your PATH. Check with type -a socktop and remove the stale copy (then hash -r in bash). Also note a long-running agent keeps serving its old behavior until restarted — restart the service after any upgrade.
Upgrading via Cargo
Update from crates.io
# Update client
cargo install socktop --force
# Update agent
# on the server running the agent
cargo install socktop_agent --force
sudo systemctl stop socktop-agent
sudo install -o root -g root -m 0755 "$HOME/.cargo/bin/socktop_agent" /usr/local/bin/socktop_agent
# if you changed the unit file:
# sudo install -o root -g root -m 0644 docs/socktop-agent.service /etc/systemd/system/socktop-agent.service
# sudo systemctl daemon-reload
sudo systemctl start socktop-agent
sudo systemctl status socktop-agent --no-pager
# logs:
# journalctl -u socktop-agent -f
Platform Notes
Linux
Fully supported — agent and client, amd64 and arm64. This is the primary platform.
Raspberry Pi
- 64-bit (Raspberry Pi OS 64-bit, Ubuntu):
aarch64-unknown-linux-gnu— full support including the APT packages. - 32-bit (ARMv7):
armv7-unknown-linux-gnueabihf— supported, but GPU metrics are not available; when building from source, build the agent with--no-default-features.
Kernel tip: update to kernel 6.6 or newer if you can. The agent uses considerably less CPU on newer kernels — on a Pi 4 under continuous polling, roughly 0.8 of a core before 6.6 versus 0.2 after (idle usage is 0 either way).
Windows
- Client and agent build with stable Rust and the MSVC toolchain (install Visual Studio Build Tools).
- Prebuilt
.exebinaries for both are available in the build artifacts under GitHub Actions. - CPU temperature may be unavailable.
macOS
- The client works well — build or
cargo installas on Linux. - The agent runs fine for local use and debugging, but it is primarily targeted at Linux; running it as a launchd service is not documented.
RISC-V (experimental)
riscv64builds from source; install your distribution’sprotobuf-compilerpackage first.- No GPU support — build the agent with
--no-default-features.
Cross-Compiling
To build agent binaries for Raspberry Pi or other ARM devices from a faster machine, see the cross-compilation guide (Linux, macOS, or Windows hosts).
General Usage
Starting socktop
Demo Mode
Try socktop without any setup:
# Launch demo mode
socktop --demo
Starts a temporary local agent on port 3231, connects to it, and monitors your local system. The agent stops when you quit (you’ll see “Stopped demo agent on port 3231”). Demo mode needs the socktop_agent binary on your PATH; if it’s missing, socktop explains how to install it.
Interactive Mode
Run socktop with no arguments to see an interactive profile menu (if you have saved profiles):
Select profile:
1. prod
2. dev-server
3. demo
Enter number (or blank to abort):
Select a number to connect, or choose demo (always available). Press Enter on blank to abort.
Monitor a Remote System
Connect to a remote agent by specifying the WebSocket URL (note the /ws path):
socktop ws://hostname:3000/ws
socktop ws://192.168.1.100:3000/ws
socktop --tls-ca /path/to/cert.pem wss://secure-host:8443/ws # With TLS
Using Connection Profiles
For frequently monitored systems, use profiles:
# Use a saved profile
socktop -P production-server
socktop --profile rpi-cluster-01
Running socktop with no arguments lists your saved profiles interactively. See Connection Profiles.
Finding Processes
Press / to enter filter mode:
Filter: pyth_
This shows only processes matching “pyth” (fuzzy, case-insensitive). Press Esc to cancel or Enter to apply; c clears an applied filter.
Select a process with ↑/↓ and press Enter to open the details view (command line, working directory, per-thread CPU, journal entries, and more).
Killing a Process
With a process selected in the list (or from inside Process Details), press t to terminate it. A confirmation dialog offers two actions, btop-style:
- Terminate - sends SIGTERM, letting the process shut down cleanly
- Force kill - sends SIGKILL
Things to know:
- Local agents only. The signal is sent by the socktop client itself, with its own privileges — it is never sent over the wire. When you’re connected to a remote agent, the option doesn’t appear, and an agent can never be instructed to kill anything remotely.
- Your privileges apply. You can only kill processes your user could kill from the shell.
- PID-reuse guard. If the PID has been recycled to a different process between confirmation and signal time, nothing is sent.
- Killed rows leave the list once the process actually exits.
- Requires agent and client 1.60 or newer together on the machine where you use it — older agents keep reporting dead processes, so killed rows would linger on screen.
Compact Layout
On small terminal windows, socktop automatically switches to a compact layout: the Disks pane is dropped, Memory/Swap sit side by side, and GPU collapses to a single line — keeping the CPU graph and per-core bars visible. Pass --compact to pin this layout regardless of window size.
Command Line Options
socktop [--tls-ca CERT_PEM|-t CERT_PEM] [--verify-hostname] [--profile NAME|-P NAME]
[--save] [--demo] [--compact] [--metrics-interval-ms N]
[--processes-interval-ms N] [ws://HOST:PORT/ws]
See Configuration for the full option reference, and Keyboard and Mouse Controls for all key bindings.
Examples
# Connect with custom intervals
socktop --metrics-interval-ms 750 --processes-interval-ms 3000 ws://server:3000/ws
# Connect with an authentication token (query parameter, quoted)
socktop "ws://server:3000/ws?token=mySecretToken"
# Connect with TLS, pinning the agent's certificate
socktop --tls-ca /path/to/cert.pem wss://server:8443/ws
# Connect with TLS and strict hostname verification
socktop --tls-ca /path/to/cert.pem --verify-hostname wss://server:8443/ws
# Pin the compact layout
socktop --compact -P rpi-cluster-01
Connection Profiles
Connection profiles allow you to save frequently used agent connections for quick access.
What are Connection Profiles?
Instead of typing the full WebSocket URL every time:
socktop ws://production-server.example.com:3000/ws
You can save it as a profile and use:
socktop -P production
Profile Configuration File
Profiles are stored in ~/.config/socktop/profiles.json (or $XDG_CONFIG_HOME/socktop/profiles.json).
Basic Profile Format
{
"profiles": {
"production": {
"url": "ws://production-server:3000/ws"
},
"dev": {
"url": "ws://dev-server:3000/ws"
},
"rpi": {
"url": "ws://192.168.1.100:3000/ws"
}
},
"version": 0
}
Profile with Authentication
{
"profiles": {
"secure-server": {
"url": "wss://secure.example.com:3000/ws?token=your-secret-token-here"
}
},
"version": 0
}
Note: Tokens are passed as query parameters in the URL.
Profile with TLS Configuration
{
"profiles": {
"tls-server": {
"url": "wss://tls-server.example.com:8443/ws",
"tls_ca": "/path/to/cert.pem"
}
},
"version": 0
}
Profile with All Options
{
"profiles": {
"full-config": {
"url": "wss://example.com:8443/ws?token=secret-token",
"tls_ca": "/etc/socktop/cert.pem",
"metrics_interval_ms": 750,
"processes_interval_ms": 3000
}
},
"version": 0
}
Note: Custom intervals are optional. Values below 100ms (metrics) or 200ms (processes) are clamped.
Creating Profiles
Method 1: Manual Creation
Create or edit the profiles file:
mkdir -p ~/.config/socktop
nano ~/.config/socktop/profiles.json
Add your profiles:
{
"profiles": {
"homelab": {
"url": "ws://192.168.1.50:3000/ws"
},
"cloud-server": {
"url": "wss://cloud.example.com:8443/ws?token=abc123xyz",
"tls_ca": "/home/user/.config/socktop/cloud-cert.pem"
}
},
"version": 0
}
Method 2: Automatic Profile Creation
When you specify a new --profile/-P name with a URL (and optional --tls-ca), it’s saved automatically:
# First connection creates and saves the profile
socktop --profile prod ws://prod-host:3000/ws
# With TLS pinning
socktop --profile prod-tls --tls-ca /path/to/cert.pem wss://prod-host:8443/ws
# With custom intervals
socktop --profile fast --metrics-interval-ms 250 --processes-interval-ms 1000 ws://host:3000/ws
To overwrite an existing profile without prompt, use --save:
socktop --profile prod --save ws://new-host:3000/ws
Using Profiles
Basic Usage
# Use a saved profile
socktop -P production
socktop --profile homelab
Keyboard and Mouse Controls
Keyboard
Global
- Quit:
qorEsc - About:
a - Help:
h
Processes
/- Start fuzzy searchc- Clear search filter↑/↓- NavigateEnter- Open detailst- Terminate selected process (local agents only; opens a Terminate / Force kill confirmation — see Killing a Process)x- Clear selection
Search (after /)
- Type - Enter query (fuzzy match)
↑/↓- Navigate resultsEsc- CancelEnter- Apply filter
CPU Per-Core
←/→- Scroll coresPgUp/PgDn- Page up/downHome/End- Jump to first/last
Process Details
x- Closep- Navigate to parentt- Terminate this process (local agents only)j/k- Scroll threads ↓/↑d/u- Scroll threads (10 lines)[/]- Scroll journalEsc/Enter- Close
Modal Navigation
Tab/→- Next buttonShift+Tab/←- Previous buttonEnter- ConfirmEsc- Cancel
Mouse (Processes pane)
- Click “CPU %” to sort by CPU descending
- Click “Mem” to sort by memory descending
- Mouse wheel: scroll
- Drag scrollbar: scroll
- Arrow/PageUp/PageDown/Home/End: scroll
Configuration
This page is the complete reference for configuring the socktop client and agent. Every option listed here exists in the current release — if an option isn’t listed, it isn’t supported.
Client Configuration
Command-Line Options
socktop [--tls-ca CERT_PEM|-t CERT_PEM] [--verify-hostname] [--profile NAME|-P NAME]
[--save] [--demo] [--compact] [--metrics-interval-ms N]
[--processes-interval-ms N] [ws://HOST:PORT/ws]
| Option | Description |
|---|---|
--tls-ca <FILE>, -t <FILE> | Pin the agent’s TLS certificate (PEM). Auto-upgrades ws:// to wss://. See TLS Configuration |
--verify-hostname | Enable strict hostname/SAN verification instead of certificate pinning |
--profile <NAME>, -P <NAME> | Use (or create) a saved connection profile |
--save | Overwrite an existing profile without the interactive prompt |
--demo | Spin up a temporary local agent and connect to it |
--compact | Pin the compact layout (normally auto-selected when the window is small) |
--metrics-interval-ms <N> | Fast metrics polling interval (default: 500, clamped to ≥ 100) |
--processes-interval-ms <N> | Process list polling interval (default: 2000, clamped to ≥ 200) |
Note: there is no --token client flag. Authentication tokens are passed in the URL as a query parameter: socktop "ws://HOST:3000/ws?token=changeme". See Authentication Token.
Configuration Files
The client stores connection profiles in:
$XDG_CONFIG_HOME/socktop/profiles.json~/.config/socktop/profiles.jsonwhenXDG_CONFIG_HOMEis not set
See Connection Profiles for the file format.
Agent Configuration
The agent is configured with a small set of command-line flags and environment variables. There is no configuration file.
Command-Line Flags
| Flag | Description |
|---|---|
--port <PORT>, -p <PORT> | Port to listen on (default: 3000, or 8443 with TLS) |
--enableSSL | Enable TLS with an auto-generated self-signed certificate |
--version, -V | Print version and exit |
The agent always binds to 0.0.0.0 (all interfaces). To restrict access, use a firewall or an authentication token.
Environment Variables
Core settings:
| Variable | Description |
|---|---|
SOCKTOP_PORT | Port to listen on (same as --port) |
SOCKTOP_ENABLE_SSL | Set to 1 to enable TLS (same as --enableSSL) |
SOCKTOP_TOKEN | Require this authentication token from clients |
SOCKTOP_AGENT_GPU | Set to 0 to disable GPU metrics collection |
SOCKTOP_AGENT_TEMP | Set to 0 to disable CPU temperature collection |
SOCKTOP_AGENT_EXTRA_SANS | Comma-separated extra IPs/DNS names to include in the auto-generated TLS certificate |
Tuning (defaults are sensible; change only if you have a reason):
| Variable | Default | Description |
|---|---|---|
SOCKTOP_WORKER_THREADS | 2 | Tokio worker threads (1–16). The agent is I/O-bound; 2 is enough for typical use |
SOCKTOP_AGENT_METRICS_TTL_MS | 250 | How long a collected metrics snapshot is served from cache |
SOCKTOP_AGENT_DISKS_TTL_MS | 1000 | Disk snapshot cache lifetime |
SOCKTOP_AGENT_PROCESSES_TTL_MS | 1500 | Process list cache lifetime (Linux) |
SOCKTOP_AGENT_NAME_CACHE_CLEANUP_THRESHOLD | 1000 | Process-name cache sweep threshold (non-Linux) |
The TTL caches mean multiple clients polling the same agent share collection work instead of multiplying it.
Configuring the systemd Service
The service unit (installed by the APT package at /etc/systemd/system/ or from docs/socktop-agent.service) sets options on the ExecStart line and via Environment= entries. To change them without editing the packaged unit, use a drop-in:
sudo systemctl edit socktop-agent
[Service]
Environment=SOCKTOP_TOKEN=changeme
Environment=SOCKTOP_AGENT_GPU=0
Then:
sudo systemctl daemon-reload
sudo systemctl restart socktop-agent
To change the port or enable TLS, override ExecStart (it must be cleared first in a drop-in):
[Service]
ExecStart=
ExecStart=/usr/bin/socktop_agent --enableSSL --port 8443
See Agent Service Setup for the full service walkthrough.
Authentication Token
The agent can require a shared token from connecting clients. Without the correct token, the WebSocket connection is rejected.
- Access control - only clients that know the token can connect
- Defense in depth - combine with TLS so the token isn’t sent in cleartext over untrusted networks
Agent: Setting the Token
The token is configured with the SOCKTOP_TOKEN environment variable. (There is no --token command-line flag.)
Running Manually
SOCKTOP_TOKEN=changeme socktop_agent --port 3000
Running as a systemd Service
Add the environment variable with a drop-in (works for both APT and manual installs):
sudo systemctl edit socktop-agent
[Service]
Environment=SOCKTOP_TOKEN=changeme
sudo systemctl daemon-reload
sudo systemctl restart socktop-agent
Alternatively, uncomment the # Environment=SOCKTOP_TOKEN=changeme line that ships in the packaged unit file.
Client: Sending the Token
The client passes the token as a token query parameter in the WebSocket URL. Quote the URL so your shell doesn’t interpret the ?:
socktop "ws://server:3000/ws?token=changeme"
# With TLS
socktop --tls-ca /path/to/cert.pem "wss://server:8443/ws?token=changeme"
Warning: the client’s -t flag is short for --tls-ca (a certificate path), not for the token.
In a Connection Profile
Store the token as part of the profile URL (~/.config/socktop/profiles.json):
{
"profiles": {
"secure-server": {
"url": "ws://server.example.com:3000/ws?token=changeme"
}
},
"version": 0
}
Then connect:
socktop -P secure-server
Note: the profiles file then contains the token in plaintext — keep its permissions restrictive.
Generating a Strong Token
openssl rand -base64 32
Recommendations
- On untrusted networks, always combine the token with TLS; over plain
ws://the token is visible to anyone who can capture traffic. - Rotate the token by updating
SOCKTOP_TOKENon the agent, restarting the service, and updating client profiles.
TLS Configuration
Secure your socktop agent connections with TLS/SSL encryption.
How Verification Works
The client supports two modes:
- Certificate pinning (default). The certificate the agent presents must be byte-identical to one of the certificates in the PEM file you pass with
--tls-ca/-t. Nothing else is accepted — not other certificates chained to the same CA, not renewed certificates. The pinned PEM may contain multiple certificates (useful during rotation: ship old + new together). Expiry is irrelevant for pinned connections. This mode is designed for the agent’s self-signed certificates on home networks. - Hostname verification (
--verify-hostname). Standard WebPKI validation against the certificate as a root, including hostname/SAN checking.
Upgrade note: client versions before 1.60 did not enforce pinning — with
--verify-hostnameoff, any server certificate was silently accepted. If you use TLS, make sure your clients are 1.60 or newer.
Enable TLS (Auto-Generated Certificate)
The agent automatically generates a self-signed certificate on first run when you enable TLS:
# The agent will auto-generate cert and key on first TLS run
socktop_agent --enableSSL --port 8443
The certificate is stored at:
- Linux (XDG):
$XDG_CONFIG_HOME/socktop_agent/tls/cert.pem(defaults to~/.config/socktop_agent/tls/) - The agent prints the certificate location on first run
- The private key (
key.pem) is created with mode0600; agents also tighten permissions on existing keys at startup
Example output:
socktop_agent: generated self-signed TLS certificate at /home/user/.config/socktop_agent/tls/cert.pem
Optional: Custom SANs (Subject Alternative Names)
To include additional IPs or hostnames in the auto-generated certificate:
SOCKTOP_AGENT_EXTRA_SANS="192.168.1.101,myhost.internal" socktop_agent --enableSSL --port 8443
This prevents NotValidForName errors when connecting via IPs not in the default SAN list.
Systemd Service with TLS
Edit /etc/systemd/system/socktop-agent.service:
[Service]
ExecStart=/usr/local/bin/socktop_agent --enableSSL --port 8443
Reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart socktop-agent
# Check logs for certificate location
sudo journalctl -u socktop-agent -f
Connect with Client
Copy the auto-generated certificate from the agent to your client machine:
# Copy certificate from agent host
scp user@agent-host:~/.config/socktop_agent/tls/cert.pem ~/socktop-agent-cert.pem
Connect with certificate pinning:
# Connect with TLS and pin the server certificate
socktop --tls-ca ~/socktop-agent-cert.pem wss://hostname:8443/ws
# Short form
socktop -t ~/socktop-agent-cert.pem wss://hostname:8443/ws
Notes:
- Providing
--tls-ca/-tautomatically upgradesws://towss://if you forget the protocol. - Copy only
cert.pemto clients — never the private key (key.pem); it stays on the agent. - You can monitor multiple agents by passing a different
--tls-caper invocation, or better, saving one profile per host.
Certificate Expiry and Rotation
The auto-generated certificate is valid for ~397 days. Pinned clients don’t check expiry, but --verify-hostname clients do, and the agent won’t regenerate an expired certificate on its own. To rotate:
# On the agent host (adjust path if XDG_CONFIG_HOME is set, or
# /var/lib/socktop/.config/socktop_agent/tls/ for the packaged service)
rm ~/.config/socktop_agent/tls/cert.pem ~/.config/socktop_agent/tls/key.pem
sudo systemctl restart socktop-agent # if running under systemd
The agent generates a fresh pair on the next TLS start. Distribute the new cert.pem to clients. For a seamless rollover, append the new cert to the clients’ pinned PEM first (both are accepted), then remove the old one after the agent switches.
Example Profiles with TLS
Profiles store the pinned certificate path alongside the URL (~/.config/socktop/profiles.json):
{
"profiles": {
"local": {
"url": "ws://127.0.0.1:3000/ws"
},
"rpi-master": {
"url": "wss://rpi-master:8443/ws",
"tls_ca": "/home/user/.config/socktop/rpi-master.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-1": {
"url": "wss://192.168.1.102:8443/ws",
"tls_ca": "/home/user/.config/socktop/rpi-worker-1.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
}
},
"version": 0
}
Then connect with socktop -P rpi-master. See Connection Profiles.
Monitor Multiple Hosts with tmux
Use tmux to show multiple socktop instances in a single terminal.
monitoring 4 Raspberry Pis using Tmux
Prerequisites
Install tmux:
# Ubuntu/Debian
sudo apt-get install tmux
Two panes (left/right)
This creates a session named “socktop”, splits it horizontally, and starts two socktops.
tmux new-session -d -s socktop 'socktop ws://HOST1:3000/ws' \; \
split-window -h 'socktop ws://HOST2:3000/ws' \; \
select-layout even-horizontal \; \
attach
Four panes (2x2 grid)
This creates a 2x2 grid with one socktop per pane.
tmux new-session -d -s socktop 'socktop ws://HOST1:3000/ws' \; \
split-window -h 'socktop ws://HOST2:3000/ws' \; \
select-pane -t 0 \; split-window -v 'socktop ws://HOST3:3000/ws' \; \
select-pane -t 1 \; split-window -v 'socktop ws://HOST4:3000/ws' \; \
select-layout tiled \; \
attach
Tips
- Replace HOST1..HOST4 (and ports) with your targets
- Reattach later:
tmux attach -t socktop
Key bindings (defaults)
- Split left/right:
Ctrl-b % - Split top/bottom:
Ctrl-b " - Move between panes:
Ctrl-b+ Arrow keys - Show pane numbers:
Ctrl-b q - Close a pane:
Ctrl-b x - Detach from session:
Ctrl-b d
More Info
For detailed tmux documentation, see the tmux GitHub.
Monitor Multiple Hosts with Zellij
Use Zellij to monitor multiple socktop instances in a single terminal.
Installation
cargo install zellij
Example Layout
Create socktop-layout.kdl:
layout {
pane split_direction="vertical" {
pane command="socktop" {
args "-P" "rpi-master"
}
pane command="socktop" {
args "-P" "rpi-worker-1"
}
}
pane split_direction="vertical" {
pane command="socktop" {
args "-P" "rpi-worker-2"
}
pane command="socktop" {
args "-P" "rpi-worker-3"
}
}
}
Run it:
zellij --layout socktop-layout.kdl
Saved Layouts
Layouts placed in ~/.config/zellij/layouts/ can be launched by name:
cp socktop-layout.kdl ~/.config/zellij/layouts/socktop-monitoring.kdl
zellij --layout socktop-monitoring
The pane commands reference connection profiles by name (-P rpi-master), so create the profiles first.
More Info
For detailed Zellij documentation, see Zellij.
WebSocket API Integration
Integrate with the socktop agent’s WebSocket API to build custom monitoring tools. If you’re writing Rust, prefer the socktop_connector library, which wraps all of this.
WebSocket Endpoint
ws://HOST:PORT/ws # Without TLS
wss://HOST:PORT/ws # With TLS
With authentication token (if configured):
ws://HOST:PORT/ws?token=YOUR_TOKEN
wss://HOST:PORT/ws?token=YOUR_TOKEN
The agent also serves GET /healthz over plain HTTP, returning 200 OK — useful for liveness probes.
Request Types
Requests are plain text WebSocket messages (not JSON). The agent replies with one message per request:
| Request | Response |
|---|---|
get_metrics | JSON — fast-changing metrics (CPU, memory, network, GPU) |
get_disks | JSON — array of disk/partition entries |
get_processes | Binary — protobuf process list, gzip-compressed above ~768 bytes |
get_process_metrics:<PID> | JSON — detailed metrics for one process |
get_journal_entries:<PID> | JSON — recent journal entries for one process |
Unknown messages are ignored. The agent is fully request-driven: it collects nothing until you ask, and short TTL caches (metrics 250 ms, disks 1 s, processes 1.5 s) mean multiple clients share collection work.
Response Formats
get_metrics (JSON)
{
"sampled_at_ms": 1755900000000,
"cpu_total": 12.4,
"cpu_per_core": [11.2, 15.7],
"mem_total": 33554432,
"mem_used": 18321408,
"swap_total": 0,
"swap_used": 0,
"hostname": "myserver",
"cpu_temp_c": 42.5,
"disks": [],
"networks": [{"name":"eth0","received":12345678,"transmitted":87654321}],
"top_processes": [],
"gpus": [{"name":"NVIDIA GeForce RTX 5080","utilization_gpu_pct":56,"mem_used_bytes":1073741824,"mem_total_bytes":8589934592}]
}
Notes:
sampled_at_ms(added in 1.60) is the epoch-milliseconds timestamp of when the snapshot was actually collected on the agent. Because responses can be served from the TTL cache, compute rates (e.g. network KB/s) from deltas ofsampled_at_ms, not from your own receive times.disksandtop_processesare always empty here — request them separately withget_disks/get_processes.cpu_temp_cisnullwhen no sensor is available;gpusisnullwhen there is no GPU (or GPU collection is disabled).received/transmittedare cumulative byte counters since agent start.
get_disks (JSON)
[
{"name":"nvme0n1","total":512000000000,"available":320000000000,"temperature":38.5,"is_partition":false},
{"name":"nvme0n1p2","total":511000000000,"available":320000000000,"temperature":null,"is_partition":true}
]
is_partition distinguishes partitions from whole disks (exact on Linux via /sys/block).
get_processes (Protocol Buffers)
Returned as a binary WebSocket message. If the encoded payload exceeds ~768 bytes (nearly always), it is gzip-compressed. Schema:
syntax = "proto3";
package socktop;
message Processes {
uint64 process_count = 1; // total processes in the system
repeated Process rows = 2; // all processes (sorting is client-side)
}
message Process {
uint32 pid = 1;
string name = 2;
float cpu_usage = 3; // 0..100
uint64 mem_bytes = 4; // RSS bytes
}
To decode: check for the gzip magic bytes (0x1f 0x8b), decompress if present, then parse with any protobuf library.
get_process_metrics:<PID> and get_journal_entries:<PID> (JSON)
Added for the process-details view: per-process detail (command line, executable, working directory, per-thread CPU times in microseconds, and more) and recent journal entries. Journal entries carry both a display timestamp (RFC 3339 UTC) and a numeric timestamp_us (epoch microseconds, added in 1.60); the response’s notice field, when present, explains empty results caused by journal access restrictions rather than absence of logs. These responses are cached per PID for 250 ms / 1 s respectively.
Example: JavaScript/Node.js
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:3000/ws');
ws.on('open', () => {
console.log('Connected to socktop_agent');
// Requests are plain text messages
setInterval(() => ws.send('get_metrics'), 1000);
setInterval(() => ws.send('get_processes'), 3000);
});
ws.on('message', (data, isBinary) => {
if (isBinary) {
// get_processes reply: gzip'd protobuf (see schema above)
console.log('Binary process list, length:', data.length);
} else {
const metrics = JSON.parse(data.toString());
console.log(`CPU: ${metrics.cpu_total}%`);
}
});
Example: Python
import json
import asyncio
import websockets
async def monitor_system():
uri = "ws://localhost:3000/ws"
async with websockets.connect(uri) as websocket:
print("Connected to socktop_agent")
while True:
await websocket.send("get_metrics") # plain text request
response = await websocket.recv()
if isinstance(response, str):
data = json.loads(response)
print(f"CPU: {data['cpu_total']}%, "
f"Memory: {data['mem_used']/data['mem_total']*100:.1f}%")
else:
print(f"Binary response, length: {len(response)}")
await asyncio.sleep(1)
asyncio.run(monitor_system())
Recommended Intervals
- Metrics: ≥ 500 ms
- Processes: ≥ 2000 ms
- Disks: ≥ 5000 ms
Polling faster than the agent’s TTL caches (250 ms / 1.5 s / 1 s) just returns cached snapshots.
Error Handling
Send each request and await its reply before sending the next of the same kind — replies carry no request ID and are matched by order. Wrap requests in a timeout and treat a timeout as a dead connection: reconnect rather than continuing on a stream that may now be misaligned.
function connect() {
const ws = new WebSocket('ws://localhost:3000/ws');
ws.on('open', () => {
// Start polling
});
ws.on('close', () => {
console.log('Connection lost, reconnecting...');
setTimeout(connect, 1000);
});
}
connect();
Compatibility
Wire changes are additive: new fields (like sampled_at_ms and timestamp_us) appear alongside old ones, so integrations built against older agents keep working against newer ones and vice versa.
Socktop Connector Library
The socktop_connector library provides a high-level interface for connecting to socktop agents programmatically.
Overview
The connector library allows you to:
- Build custom monitoring tools - Create your own dashboards and UIs
- Integrate with existing systems - Add socktop metrics to your applications
- Automate monitoring - Script-based system checks and alerts
- WASM support - Use in browser-based applications
Installation
Add to your Cargo.toml:
[dependencies]
socktop_connector = "1.60"
tokio = { version = "1", features = ["full"] }
Quick Start
Basic Connection
use socktop_connector::{connect_to_socktop_agent, AgentRequest, AgentResponse};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to agent
let mut connector = connect_to_socktop_agent("ws://localhost:3000/ws").await?;
// Request metrics
if let Ok(AgentResponse::Metrics(metrics)) = connector.request(AgentRequest::Metrics).await {
println!("Hostname: {}", metrics.hostname);
println!("CPU Usage: {:.1}%", metrics.cpu_total);
println!("Memory: {:.1} GB / {:.1} GB",
metrics.mem_used as f64 / 1_000_000_000.0,
metrics.mem_total as f64 / 1_000_000_000.0);
}
Ok(())
}
With TLS
use socktop_connector::connect_to_socktop_agent_with_tls;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let connector = connect_to_socktop_agent_with_tls(
"wss://secure-host:8443/ws",
"/path/to/cert.pem",
false // verify_hostname: false = pin the certificate (default socktop behavior)
).await?;
// Use connector...
Ok(())
}
Request Types
The connector supports several request types:
Metrics Request
Get comprehensive system metrics:
use socktop_connector::{AgentRequest, AgentResponse};
match connector.request(AgentRequest::Metrics).await {
Ok(AgentResponse::Metrics(metrics)) => {
println!("CPU Total: {:.1}%", metrics.cpu_total);
// Per-core usage
for (i, usage) in metrics.cpu_per_core.iter().enumerate() {
println!("Core {}: {:.1}%", i, usage);
}
// CPU temperature
if let Some(temp) = metrics.cpu_temp_c {
println!("CPU Temperature: {:.1}°C", temp);
}
// Memory
println!("Memory Used: {} bytes", metrics.mem_used);
println!("Memory Total: {} bytes", metrics.mem_total);
// Swap
println!("Swap Used: {} bytes", metrics.swap_used);
println!("Swap Total: {} bytes", metrics.swap_total);
// Network interfaces
for net in &metrics.networks {
println!("Interface {}: ↓{} ↑{}",
net.name, net.received, net.transmitted);
}
// GPU information
if let Some(gpus) = &metrics.gpus {
for gpu in gpus {
if let Some(name) = &gpu.name {
println!("GPU: {}", name);
println!(" Utilization: {:.1}%", gpu.utilization.unwrap_or(0.0));
if let Some(temp) = gpu.temp {
println!(" Temperature: {:.1}°C", temp);
}
}
}
}
}
Err(e) => eprintln!("Error: {}", e),
_ => unreachable!(),
}
Process Request
Get process information:
match connector.request(AgentRequest::Processes).await {
Ok(AgentResponse::Processes(processes)) => {
println!("Total processes: {}", processes.process_count);
for proc in &processes.top_processes {
println!("PID {}: {} - CPU: {:.1}%, Mem: {} MB",
proc.pid,
proc.name,
proc.cpu_usage,
proc.mem_bytes / 1_000_000);
}
}
Err(e) => eprintln!("Error: {}", e),
_ => unreachable!(),
}
Disk Request
Get disk information:
match connector.request(AgentRequest::Disks).await {
Ok(AgentResponse::Disks(disks)) => {
for disk in disks {
let used = disk.total - disk.available;
let used_gb = used as f64 / 1_000_000_000.0;
let total_gb = disk.total as f64 / 1_000_000_000.0;
let percent = (used as f64 / disk.total as f64) * 100.0;
println!("Disk {}: {:.1} GB / {:.1} GB ({:.1}%)",
disk.name, used_gb, total_gb, percent);
}
}
Err(e) => eprintln!("Error: {}", e),
_ => unreachable!(),
}
Continuous Monitoring
Monitor metrics in a loop:
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut connector = connect_to_socktop_agent("ws://localhost:3000/ws").await?;
loop {
match connector.request(AgentRequest::Metrics).await {
Ok(AgentResponse::Metrics(metrics)) => {
println!("CPU: {:.1}%, Memory: {:.1}%",
metrics.cpu_total,
(metrics.mem_used as f64 / metrics.mem_total as f64) * 100.0
);
}
Err(e) => {
eprintln!("Connection error: {}", e);
break;
}
_ => unreachable!(),
}
sleep(Duration::from_secs(2)).await;
}
Ok(())
}
Advanced Usage
Custom Configuration
ConnectorConfig uses a builder pattern:
use socktop_connector::{ConnectorConfig, SocktopConnector};
let config = ConnectorConfig::new("wss://server:8443/ws?token=secret-token")
.with_tls_ca("/path/to/cert.pem")
.with_hostname_verification(false);
let mut connector = SocktopConnector::new(config);
connector.connect().await?;
An authentication token is passed as a token query parameter in the URL (there is no separate token field).
Error Handling
ConnectorError variants carry structured context:
use socktop_connector::{AgentRequest, ConnectorError, Result, connect_to_socktop_agent};
async fn monitor() -> Result<()> {
let mut connector = connect_to_socktop_agent("ws://server:3000/ws").await?;
match connector.request(AgentRequest::Metrics).await {
Ok(_response) => {
// Handle response
Ok(())
}
Err(e @ ConnectorError::ConnectionClosed { .. }) => {
eprintln!("Connection closed, attempting reconnect...");
Err(e)
}
Err(e) => {
eprintln!("Error: {}", e);
Err(e)
}
}
}
WASM Support
The connector supports WebAssembly for browser usage:
[dependencies]
socktop_connector = { version = "1.60", default-features = false, features = ["wasm"] }
use socktop_connector::connect_to_socktop_agent;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub async fn monitor_system(url: String) -> Result<JsValue, JsValue> {
let mut connector = connect_to_socktop_agent(&url)
.await
.map_err(|e| JsValue::from_str(&e.to_string()))?;
match connector.request(AgentRequest::Metrics).await {
Ok(AgentResponse::Metrics(metrics)) => {
Ok(JsValue::from_str(&format!("CPU: {:.1}%", metrics.cpu_total)))
}
Err(e) => Err(JsValue::from_str(&e.to_string())),
_ => Err(JsValue::from_str("Unexpected response")),
}
}
Building Custom Applications
Example: Simple Dashboard
use socktop_connector::*;
use tokio::time::{interval, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let servers = vec![
("web", "ws://web.example.com:3000/ws"),
("db", "ws://db.example.com:3000/ws"),
("cache", "ws://cache.example.com:3000/ws"),
];
let mut connectors = Vec::new();
for (name, url) in servers {
match connect_to_socktop_agent(url).await {
Ok(conn) => connectors.push((name, conn)),
Err(e) => eprintln!("Failed to connect to {}: {}", name, e),
}
}
let mut tick = interval(Duration::from_secs(2));
loop {
tick.tick().await;
for (name, connector) in &mut connectors {
if let Ok(AgentResponse::Metrics(m)) = connector.request(AgentRequest::Metrics).await {
println!("[{}] CPU: {:.1}%, Mem: {:.1}%",
name,
m.cpu_total,
(m.mem_used as f64 / m.mem_total as f64) * 100.0
);
}
}
println!("---");
}
}
Example: Alert System
use socktop_connector::*;
async fn check_alerts(mut connector: SocktopConnector) -> Result<(), Box<dyn std::error::Error>> {
match connector.request(AgentRequest::Metrics).await {
Ok(AgentResponse::Metrics(metrics)) => {
// CPU alert
if metrics.cpu_total > 90.0 {
eprintln!("ALERT: CPU usage at {:.1}%", metrics.cpu_total);
}
// Memory alert
let mem_percent = (metrics.mem_used as f64 / metrics.mem_total as f64) * 100.0;
if mem_percent > 90.0 {
eprintln!("ALERT: Memory usage at {:.1}%", mem_percent);
}
// Disk alert
if let Ok(AgentResponse::Disks(disks)) = connector.request(AgentRequest::Disks).await {
for disk in disks {
let used_percent = ((disk.total - disk.available) as f64 / disk.total as f64) * 100.0;
if used_percent > 90.0 {
eprintln!("ALERT: Disk {} at {:.1}%", disk.name, used_percent);
}
}
}
}
Err(e) => eprintln!("Error fetching metrics: {}", e),
_ => {}
}
Ok(())
}
Data Types
Key types provided by the library:
Metrics- System metrics (CPU, memory, network, GPU, etc.)DetailedProcessInfo- Per-process detail (command, threads, …)DiskInfo- Disk usage informationNetworkInfo- Network interface statisticsGpuInfo- GPU metricsJournalEntry- Systemd journal entriesAgentRequest- Request types (Metrics,Disks,Processes,ProcessMetrics { pid },JournalEntries { pid })AgentResponse- Response types
See the crate documentation for complete API reference.
Performance Considerations
The connector is lightweight and efficient:
- Protocol Buffers - Efficient binary serialization
- Gzip compression - Reduced bandwidth usage
- Async I/O - Non-blocking operations
- Connection reuse - Single WebSocket for multiple requests
Typical resource usage:
- Memory: ~1-5 MB per connection
- CPU: < 0.1% during idle
- Bandwidth: ~1-5 KB per metrics request
Troubleshooting
Connection Errors
match connect_to_socktop_agent(url).await {
Err(ConnectorError::ConnectionFailed { source }) => {
eprintln!("Connection failed: {}", source);
// Retry logic here
}
Err(ConnectorError::InvalidUrl { url, .. }) => {
eprintln!("Invalid URL: {}", url);
}
Err(e) => eprintln!("Other error: {}", e),
Ok(conn) => { /* Success */ }
}
TLS Errors
A TlsError or CertificateError usually means the pinned certificate doesn’t match what the agent presented (or the PEM path is wrong). Re-copy cert.pem from the agent — see TLS Configuration. Hostname verification is off by default (with_hostname_verification(false)), which pins the certificate rather than skipping checks.
Examples Repository
Working examples in the socktop repository:
examples/wasm_example.rs- Connector usage from WASMsocktop_wasm_test/- Browser-based test harness for the wasm featuresocktop/- The TUI itself is the reference consumer of the connector
API Reference
Full API documentation: docs.rs/socktop_connector
Next Steps
- Agent Direct Integration - Embed agent in your app
- General Usage - Using the TUI client
- Configuration - Configuration options