docs: 1.60 update — fix fabricated content, add kill/platform/known-issues docs
Build and Deploy to K3s / test (push) Successful in 1m55s
Build and Deploy to K3s / lint (push) Failing after 13m39s
Build and Deploy to K3s / build-and-push (push) Has been skipped
Build and Deploy to K3s / deploy (push) Failing after 14m58s

- Rewrite configuration.md from the real CLI/env surface (the page documented
  ~10 agent flags, /etc/default/socktop-agent, and env vars that don't exist)
- Fix token docs: SOCKTOP_TOKEN env + URL query param; client -t is --tls-ca,
  not a token flag
- Rewrite agent-integration.md: requests are plain text (get_metrics, ...),
  not JSON; correct proto schema, real GPU/metrics fields, 1.60 additive
  fields (sampled_at_ms, timestamp_us, journal notice)
- Fix connector.md: real ConnectorConfig builder API, error variants,
  examples list; bump to 1.60
- Document the 1.60 process kill feature (usage/general + keyboard-mouse)
- TLS: document exact-match pinning semantics, cert rotation, key perms,
  upgrade-clients-first note; genericize profile example
- Agent service: journal access setup (systemd-journal group), packaged-
  service cert path, drop fake positional-port form, fix broken fences
- New pages: Platform Notes (Windows/macOS/RISC-V/Pi kernel tip, ARMv7
  --no-default-features) and Known Issues
- Fedora build prereqs: libdrm-devel + libdrm-amdgpu (closes socktop#35)
- Freshen intro (1.60, new demo apng, correct crates.io names, GitHub
  Releases link), quick-start, upgrading (order notes, stale-binary tip),
  zellij (remove invalid pane_template example)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jasonwitty
2026-08-23 21:35:27 -07:00
parent 98f8b4a865
commit 5c03b92807
18 changed files with 454 additions and 438 deletions
+4 -1
View File
@@ -9,6 +9,7 @@
- [Install via APT](./installation/apt.md) - [Install via APT](./installation/apt.md)
- [Agent Service Setup](./installation/agent-service.md) - [Agent Service Setup](./installation/agent-service.md)
- [Upgrading](./installation/upgrading.md) - [Upgrading](./installation/upgrading.md)
- [Platform Notes](./installation/platform-notes.md)
- [Usage]() - [Usage]()
- [General Usage](./usage/general.md) - [General Usage](./usage/general.md)
@@ -24,4 +25,6 @@
- [Monitor Multiple Hosts with tmux](./advanced/tmux.md) - [Monitor Multiple Hosts with tmux](./advanced/tmux.md)
- [Monitor Multiple Hosts with Zellij](./advanced/zellij.md) - [Monitor Multiple Hosts with Zellij](./advanced/zellij.md)
- [Agent Direct Integration](./advanced/agent-integration.md) - [Agent Direct Integration](./advanced/agent-integration.md)
- [Socktop Connector Library](./advanced/connector.md) - [Socktop Connector Library](./advanced/connector.md)
[Known Issues](./known-issues.md)
+76 -76
View File
@@ -1,6 +1,6 @@
# WebSocket API Integration # WebSocket API Integration
Integrate with the socktop agent's WebSocket API to build custom monitoring tools. Integrate with the socktop agent's WebSocket API to build custom monitoring tools. If you're writing Rust, prefer the [socktop_connector library](./connector.md), which wraps all of this.
## WebSocket Endpoint ## WebSocket Endpoint
@@ -15,22 +15,29 @@ ws://HOST:PORT/ws?token=YOUR_TOKEN
wss://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 ## Request Types
Send JSON messages to request specific metrics: Requests are **plain text WebSocket messages** (not JSON). The agent replies with one message per request:
```json | Request | Response |
{"type": "metrics"} // Fast-changing metrics (CPU, memory, network) |---|---|
{"type": "disks"} // Disk information | `get_metrics` | JSON — fast-changing metrics (CPU, memory, network, GPU) |
{"type": "processes"} // Process list (returns protobuf) | `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 ## Response Formats
### Metrics (JSON) ### `get_metrics` (JSON)
```json ```json
{ {
"sampled_at_ms": 1755900000000,
"cpu_total": 12.4, "cpu_total": 12.4,
"cpu_per_core": [11.2, 15.7], "cpu_per_core": [11.2, 15.7],
"mem_total": 33554432, "mem_total": 33554432,
@@ -39,40 +46,58 @@ Send JSON messages to request specific metrics:
"swap_used": 0, "swap_used": 0,
"hostname": "myserver", "hostname": "myserver",
"cpu_temp_c": 42.5, "cpu_temp_c": 42.5,
"disks": [],
"networks": [{"name":"eth0","received":12345678,"transmitted":87654321}], "networks": [{"name":"eth0","received":12345678,"transmitted":87654321}],
"gpus": [{"name":"nvidia-0","usage":56.7,"memory_total":8589934592,"memory_used":1073741824,"temp_c":65.0}] "top_processes": [],
"gpus": [{"name":"NVIDIA GeForce RTX 5080","utilization_gpu_pct":56,"mem_used_bytes":1073741824,"mem_total_bytes":8589934592}]
} }
``` ```
### Disks (JSON) 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 of `sampled_at_ms`, not from your own receive times.
- `disks` and `top_processes` are always empty here — request them separately with `get_disks` / `get_processes`.
- `cpu_temp_c` is `null` when no sensor is available; `gpus` is `null` when there is no GPU (or GPU collection is disabled).
- `received`/`transmitted` are cumulative byte counters since agent start.
### `get_disks` (JSON)
```json ```json
[ [
{"name":"nvme0n1p2","total":512000000000,"available":320000000000}, {"name":"nvme0n1","total":512000000000,"available":320000000000,"temperature":38.5,"is_partition":false},
{"name":"sda1","total":1000000000000,"available":750000000000} {"name":"nvme0n1p2","total":511000000000,"available":320000000000,"temperature":null,"is_partition":true}
] ]
``` ```
### Processes (Protocol Buffers) `is_partition` distinguishes partitions from whole disks (exact on Linux via `/sys/block`).
Processes are returned in protobuf format, optionally gzip-compressed. Schema: ### `get_processes` (Protocol Buffers)
Returned as a binary WebSocket message. If the encoded payload exceeds ~768 bytes (nearly always), it is gzip-compressed. Schema:
```protobuf ```protobuf
syntax = "proto3"; 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 { message Process {
uint32 pid = 1; uint32 pid = 1;
string name = 2; string name = 2;
float cpu_usage = 3; float cpu_usage = 3; // 0..100
uint64 mem_bytes = 4; uint64 mem_bytes = 4; // RSS bytes
}
message ProcessList {
uint32 process_count = 1;
repeated Process processes = 2;
} }
``` ```
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 ## Example: JavaScript/Node.js
```javascript ```javascript
@@ -80,36 +105,23 @@ const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:3000/ws'); const ws = new WebSocket('ws://localhost:3000/ws');
ws.on('open', function open() { ws.on('open', () => {
console.log('Connected to socktop_agent'); console.log('Connected to socktop_agent');
// Request metrics // Requests are plain text messages
ws.send(JSON.stringify({type: 'metrics'})); setInterval(() => ws.send('get_metrics'), 1000);
setInterval(() => ws.send('get_processes'), 3000);
// Poll every second
setInterval(() => {
ws.send(JSON.stringify({type: 'metrics'}));
}, 1000);
// Request processes every 3 seconds
setInterval(() => {
ws.send(JSON.stringify({type: 'processes'}));
}, 3000);
}); });
ws.on('message', function incoming(data) { ws.on('message', (data, isBinary) => {
try { if (isBinary) {
const jsonData = JSON.parse(data); // get_processes reply: gzip'd protobuf (see schema above)
console.log('Received JSON data:', jsonData); console.log('Binary process list, length:', data.length);
} catch (e) { } else {
console.log('Received binary data (protobuf), length:', data.length); const metrics = JSON.parse(data.toString());
// Process binary protobuf data with protobufjs console.log(`CPU: ${metrics.cpu_total}%`);
} }
}); });
ws.on('close', function close() {
console.log('Disconnected from socktop_agent');
});
``` ```
## Example: Python ## Example: Python
@@ -123,23 +135,18 @@ async def monitor_system():
uri = "ws://localhost:3000/ws" uri = "ws://localhost:3000/ws"
async with websockets.connect(uri) as websocket: async with websockets.connect(uri) as websocket:
print("Connected to socktop_agent") print("Connected to socktop_agent")
# Request initial metrics
await websocket.send(json.dumps({"type": "metrics"}))
while True: while True:
# Request metrics await websocket.send("get_metrics") # plain text request
await websocket.send(json.dumps({"type": "metrics"}))
# Receive response
response = await websocket.recv() response = await websocket.recv()
try: if isinstance(response, str):
data = json.loads(response) data = json.loads(response)
print(f"CPU: {data['cpu_total']}%, Memory: {data['mem_used']/data['mem_total']*100:.1f}%") print(f"CPU: {data['cpu_total']}%, "
except json.JSONDecodeError: f"Memory: {data['mem_used']/data['mem_total']*100:.1f}%")
print(f"Received binary data, length: {len(response)}") else:
print(f"Binary response, length: {len(response)}")
await asyncio.sleep(1) await asyncio.sleep(1)
asyncio.run(monitor_system()) asyncio.run(monitor_system())
@@ -147,31 +154,24 @@ asyncio.run(monitor_system())
## Recommended Intervals ## Recommended Intervals
- Metrics: ≥ 500ms - Metrics: ≥ 500 ms
- Processes: ≥ 2000ms - Processes: ≥ 2000 ms
- Disks: ≥ 5000ms - Disks: ≥ 5000 ms
## Handling Protocol Buffers Polling faster than the agent's TTL caches (250 ms / 1.5 s / 1 s) just returns cached snapshots.
For processing binary process data:
1. Check if response starts with gzip magic bytes (`0x1f, 0x8b`)
2. Decompress if necessary
3. Parse with protobuf library using the schema above
## Error Handling ## Error Handling
Implement reconnection logic with exponential backoff: 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.
```javascript ```javascript
function connect() { function connect() {
const ws = new WebSocket('ws://localhost:3000/ws'); const ws = new WebSocket('ws://localhost:3000/ws');
ws.on('open', () => { ws.on('open', () => {
console.log('Connected');
// Start polling // Start polling
}); });
ws.on('close', () => { ws.on('close', () => {
console.log('Connection lost, reconnecting...'); console.log('Connection lost, reconnecting...');
setTimeout(connect, 1000); setTimeout(connect, 1000);
@@ -181,6 +181,6 @@ function connect() {
connect(); connect();
``` ```
## More Info ## Compatibility
For detailed implementation, see the [socktop_agent README](https://github.com/jasonwitty/socktop/tree/master/socktop_agent). 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.
+32 -43
View File
@@ -17,7 +17,7 @@ Add to your `Cargo.toml`:
```toml ```toml
[dependencies] [dependencies]
socktop_connector = "1.50" socktop_connector = "1.60"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
``` ```
@@ -54,9 +54,9 @@ use socktop_connector::connect_to_socktop_agent_with_tls;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
let connector = connect_to_socktop_agent_with_tls( let connector = connect_to_socktop_agent_with_tls(
"wss://secure-host:3000/ws", "wss://secure-host:8443/ws",
"/path/to/ca.pem", "/path/to/cert.pem",
false // Enable hostname verification false // verify_hostname: false = pin the certificate (default socktop behavior)
).await?; ).await?;
// Use connector... // Use connector...
@@ -203,35 +203,39 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
### Custom Configuration ### Custom Configuration
`ConnectorConfig` uses a builder pattern:
```rust ```rust
use socktop_connector::{ConnectorConfig, SocktopConnector}; use socktop_connector::{ConnectorConfig, SocktopConnector};
let config = ConnectorConfig { let config = ConnectorConfig::new("wss://server:8443/ws?token=secret-token")
url: "ws://server:3000/ws".to_string(), .with_tls_ca("/path/to/cert.pem")
token: Some("secret-token".to_string()), .with_hostname_verification(false);
ca_cert_path: Some("/path/to/ca.pem".to_string()),
verify_tls: true,
};
let connector = SocktopConnector::connect_with_config(config).await?; 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 ### Error Handling
`ConnectorError` variants carry structured context:
```rust ```rust
use socktop_connector::{ConnectorError, Result}; use socktop_connector::{AgentRequest, ConnectorError, Result, connect_to_socktop_agent};
async fn monitor() -> Result<()> { async fn monitor() -> Result<()> {
let mut connector = connect_to_socktop_agent("ws://server:3000/ws").await?; let mut connector = connect_to_socktop_agent("ws://server:3000/ws").await?;
match connector.request(AgentRequest::Metrics).await { match connector.request(AgentRequest::Metrics).await {
Ok(response) => { Ok(_response) => {
// Handle response // Handle response
Ok(()) Ok(())
} }
Err(ConnectorError::ConnectionClosed) => { Err(e @ ConnectorError::ConnectionClosed { .. }) => {
eprintln!("Connection closed, attempting reconnect..."); eprintln!("Connection closed, attempting reconnect...");
Err(ConnectorError::ConnectionClosed) Err(e)
} }
Err(e) => { Err(e) => {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);
@@ -247,7 +251,7 @@ The connector supports WebAssembly for browser usage:
```toml ```toml
[dependencies] [dependencies]
socktop_connector = { version = "1.50", features = ["wasm"] } socktop_connector = { version = "1.60", default-features = false, features = ["wasm"] }
``` ```
```rust ```rust
@@ -356,12 +360,12 @@ async fn check_alerts(mut connector: SocktopConnector) -> Result<(), Box<dyn std
Key types provided by the library: Key types provided by the library:
- `Metrics` - System metrics (CPU, memory, network, GPU, etc.) - `Metrics` - System metrics (CPU, memory, network, GPU, etc.)
- `ProcessMetricsResponse` - Process information - `DetailedProcessInfo` - Per-process detail (command, threads, ...)
- `DiskInfo` - Disk usage information - `DiskInfo` - Disk usage information
- `NetworkInfo` - Network interface statistics - `NetworkInfo` - Network interface statistics
- `GpuInfo` - GPU metrics - `GpuInfo` - GPU metrics
- `JournalEntry` - Systemd journal entries - `JournalEntry` - Systemd journal entries
- `AgentRequest` - Request types - `AgentRequest` - Request types (`Metrics`, `Disks`, `Processes`, `ProcessMetrics { pid }`, `JournalEntries { pid }`)
- `AgentResponse` - Response types - `AgentResponse` - Response types
See the [crate documentation](https://docs.rs/socktop_connector) for complete API reference. See the [crate documentation](https://docs.rs/socktop_connector) for complete API reference.
@@ -386,12 +390,12 @@ Typical resource usage:
```rust ```rust
match connect_to_socktop_agent(url).await { match connect_to_socktop_agent(url).await {
Err(ConnectorError::ConnectionFailed(e)) => { Err(ConnectorError::ConnectionFailed { source }) => {
eprintln!("Connection failed: {}", e); eprintln!("Connection failed: {}", source);
// Retry logic here // Retry logic here
} }
Err(ConnectorError::InvalidUrl) => { Err(ConnectorError::InvalidUrl { url, .. }) => {
eprintln!("Invalid URL format"); eprintln!("Invalid URL: {}", url);
} }
Err(e) => eprintln!("Other error: {}", e), Err(e) => eprintln!("Other error: {}", e),
Ok(conn) => { /* Success */ } Ok(conn) => { /* Success */ }
@@ -400,25 +404,15 @@ match connect_to_socktop_agent(url).await {
### TLS Errors ### TLS Errors
```rust 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](../security/tls.md). Hostname verification is off by default (`with_hostname_verification(false)`), which pins the certificate rather than skipping checks.
// Disable TLS verification for testing (not recommended)
use socktop_connector::{ConnectorConfig, SocktopConnector};
let config = ConnectorConfig {
url: "wss://server:3000/ws".to_string(),
verify_tls: false,
..Default::default()
};
```
## Examples Repository ## Examples Repository
More examples available in the socktop repository: Working examples in the socktop repository:
- `examples/simple_monitor.rs` - Basic monitoring - [`examples/wasm_example.rs`](https://github.com/jasonwitty/socktop/blob/master/examples/wasm_example.rs) - Connector usage from WASM
- `examples/multi_server.rs` - Monitor multiple servers - [`socktop_wasm_test/`](https://github.com/jasonwitty/socktop/tree/master/socktop_wasm_test) - Browser-based test harness for the wasm feature
- `examples/alert_system.rs` - Threshold-based alerts - [`socktop/`](https://github.com/jasonwitty/socktop/tree/master/socktop) - The TUI itself is the reference consumer of the connector
- `examples/wasm_demo/` - Browser-based monitoring
## API Reference ## API Reference
@@ -429,9 +423,4 @@ Full API documentation: [docs.rs/socktop_connector](https://docs.rs/socktop_conn
- [Agent Direct Integration](./agent-integration.md) - Embed agent in your app - [Agent Direct Integration](./agent-integration.md) - Embed agent in your app
- [General Usage](../usage/general.md) - Using the TUI client - [General Usage](../usage/general.md) - Using the TUI client
- [Configuration](../usage/configuration.md) - Configuration options - [Configuration](../usage/configuration.md) - Configuration options
<!-- TODO: Add more documentation -->
<!-- TODO: Add WebSocket reconnection examples -->
<!-- TODO: Add rate limiting guidance -->
<!-- TODO: Add batch request examples -->
<!-- TODO: Add Prometheus exporter example --> <!-- TODO: Add Prometheus exporter example -->
+11 -28
View File
@@ -39,34 +39,17 @@ Run it:
zellij --layout socktop-layout.kdl zellij --layout socktop-layout.kdl
``` ```
## Saved Layouts
Layouts placed in `~/.config/zellij/layouts/` can be launched by name:
```bash
cp socktop-layout.kdl ~/.config/zellij/layouts/socktop-monitoring.kdl
zellij --layout socktop-monitoring
```
The pane commands reference [connection profiles](../usage/connection-profiles.md) by name (`-P rpi-master`), so create the profiles first.
## More Info ## More Info
For detailed Zellij documentation, see [Zellij](https://zellij.dev/). For detailed Zellij documentation, see [Zellij](https://zellij.dev/).
Create `~/.config/zellij/layouts/socktop-monitoring.kdl`:
```kdl
layout {
pane_template name="socktop_pane" {
command "socktop"
args "-P" "{profile}"
}
pane split_direction="vertical" {
pane split_direction="horizontal" {
socktop_pane profile="production-web"
socktop_pane profile="production-db"
}
pane split_direction="horizontal" {
socktop_pane profile="staging-web"
socktop_pane profile="staging-db"
}
}
}
```
### Use the Layout
```bash
zellij --layout socktop-monitoring
```
+17 -16
View File
@@ -53,7 +53,6 @@ Agent configuration via command-line flags or environment variables:
Port: Port:
- Flag: `--port 8080` or `-p 8080` - Flag: `--port 8080` or `-p 8080`
- Positional: `socktop_agent 8080`
- Env: `SOCKTOP_PORT=8080` - Env: `SOCKTOP_PORT=8080`
TLS (self-signed): TLS (self-signed):
@@ -62,7 +61,7 @@ TLS (self-signed):
- Certificate/Key location (created on first TLS run): - Certificate/Key location (created on first TLS run):
- Linux (XDG): `$XDG_CONFIG_HOME/socktop_agent/tls/{cert.pem,key.pem}` (defaults to `~/.config`) - Linux (XDG): `$XDG_CONFIG_HOME/socktop_agent/tls/{cert.pem,key.pem}` (defaults to `~/.config`)
- The agent prints these paths on creation - 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/`
Auth token (optional): `SOCKTOP_TOKEN=changeme` Auth token (optional): `SOCKTOP_TOKEN=changeme`
@@ -70,6 +69,21 @@ Disable GPU metrics: `SOCKTOP_AGENT_GPU=0`
Disable CPU temperature: `SOCKTOP_AGENT_TEMP=0` Disable CPU temperature: `SOCKTOP_AGENT_TEMP=0`
See [Configuration](../usage/configuration.md) 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:
```bash
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 ## Managing the Service
### Basic Commands ### Basic Commands
@@ -122,17 +136,4 @@ sudo systemctl is-active socktop-agent
## Updating ## Updating
```bash See [Upgrading](./upgrading.md).
# 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
```
Tip: If only the binary changed, restart is enough. If the unit file changed, run `sudo systemctl daemon-reload`.
```
+21 -41
View File
@@ -6,11 +6,14 @@ Installing socktop via Cargo gives you access to the latest version and works on
Before installing via Cargo, ensure you have: Before installing via Cargo, ensure you have:
- **Rust 1.70 or newer** - Install via [rustup](https://rustup.rs/) - **Current stable Rust** (1.85+, 2024 edition) - Install via [rustup](https://rustup.rs/)
- **Build dependencies** - See [Prerequisites](./prerequisites.md) for details - **Build dependencies** - See [Prerequisites](./prerequisites.md) for details
- **GPU support libraries** - Required on all systems: - **GPU support libraries** (x86_64/aarch64):
```bash ```bash
# Debian/Ubuntu
sudo apt install libdrm-dev libdrm-amdgpu1 sudo apt install libdrm-dev libdrm-amdgpu1
# Fedora
sudo dnf install libdrm-devel libdrm-amdgpu
``` ```
## Installation ## Installation
@@ -26,7 +29,7 @@ This will download, compile, and install the `socktop` binary to `~/.cargo/bin/`
### Installing the Agent ### Installing the Agent
```bash ```bash
cargo install socktop-agent cargo install socktop_agent
``` ```
This installs the `socktop_agent` binary to `~/.cargo/bin/`. This installs the `socktop_agent` binary to `~/.cargo/bin/`.
@@ -34,7 +37,7 @@ This installs the `socktop_agent` binary to `~/.cargo/bin/`.
### Installing Both (Recommended) ### Installing Both (Recommended)
```bash ```bash
cargo install socktop socktop-agent cargo install socktop socktop_agent
``` ```
## Verify Installation ## Verify Installation
@@ -51,7 +54,7 @@ socktop_agent --version
You should see output like: You should see output like:
``` ```
socktop 1.50.2 socktop 1.60.1
``` ```
## First Run ## First Run
@@ -67,8 +70,8 @@ socktop_agent
# Run in background # Run in background
socktop_agent & socktop_agent &
# Or with custom options # Or on a custom port
socktop_agent --port 3000 --host 0.0.0.0 socktop_agent --port 3000
``` ```
### Connect with the Client ### Connect with the Client
@@ -76,54 +79,31 @@ socktop_agent --port 3000 --host 0.0.0.0
In another terminal, connect to the agent: In another terminal, connect to the agent:
```bash ```bash
# Monitor local system socktop ws://localhost:3000/ws
socktop ```
# Or explicitly specify the WebSocket URL Or just try demo mode (starts and stops its own local agent):
socktop ws://localhost:3000
```bash
socktop --demo
``` ```
## Configuration ## Configuration
### Agent 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:
The agent accepts the following command-line arguments:
```bash ```bash
socktop_agent --help
```
Common options:
- `--port <PORT>` - Port to listen on (default: 3000)
- `--host <HOST>` - Host/IP to bind to (default: 0.0.0.0)
- `--token <TOKEN>` - Authentication token (optional)
- `--tls-cert <CERT>` - TLS certificate path (optional)
- `--tls-key <KEY>` - TLS private key path (optional)
Example with custom configuration:
```bash
socktop_agent --port 8080 --token mySecretToken123
```
### Client Configuration
The client can connect using various methods:
```bash
# Local connection
socktop
# Remote connection # Remote connection
socktop ws://192.168.1.100:3000 socktop ws://192.168.1.100:3000/ws
# Secure connection with TLS # Secure connection with a pinned certificate
socktop wss://secure-host:3000 socktop --tls-ca /path/to/cert.pem wss://secure-host:8443/ws
# Using a connection profile # Using a connection profile
socktop -P my-server socktop -P my-server
``` ```
See [Configuration](../usage/configuration.md) for details on setting up profiles. See [Configuration](../usage/configuration.md) for the complete reference and [Connection Profiles](../usage/connection-profiles.md) for profiles.
## System-wide agent (Linux) ## System-wide agent (Linux)
+32
View File
@@ -0,0 +1,32 @@
# 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 `.exe` binaries for both are available in the build artifacts under [GitHub Actions](https://github.com/jasonwitty/socktop/actions).
- CPU temperature may be unavailable.
## macOS
- The client works well — build or `cargo install` as 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)
- `riscv64` builds from source; install your distribution's `protobuf-compiler` package 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](https://github.com/jasonwitty/socktop/blob/master/docs/cross-compiling.md) (Linux, macOS, or Windows hosts).
+20 -5
View File
@@ -8,7 +8,10 @@
- **Fedora** 35+ - **Fedora** 35+
- **Raspberry Pi OS** - **Raspberry Pi OS**
- Other Linux distributions with kernel 4.15+ - Other Linux distributions with kernel 4.15+
- Windows 10+ (Binaries available in build artifacts) - Windows 10+ (binaries available in build artifacts)
- macOS (client; the agent runs but is primarily targeted at Linux)
See [Platform Notes](./platform-notes.md) for platform-specific details.
#### Supported Architectures #### Supported Architectures
@@ -19,18 +22,30 @@
## Software Dependencies ## Software Dependencies
GPU support requires additional libraries: GPU support requires additional libraries (x86_64 and aarch64 only):
**Debian/Ubuntu/Raspberry Pi OS:**
```bash ```bash
sudo apt update sudo apt update
sudo apt install libdrm-dev libdrm-amdgpu1 sudo apt install libdrm-dev libdrm-amdgpu1
``` ```
**Fedora:**
```bash
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`:
```bash
cargo build --release -p socktop_agent --no-default-features
```
### For Cargo Installation ### For Cargo Installation
#### 1. Rust Toolchain #### 1. Rust Toolchain
Rust 1.70+ required. A current stable Rust toolchain is required (the crates use the 2024 edition, so Rust 1.85+).
```bash ```bash
# Install Rust via rustup (recommended) # Install Rust via rustup (recommended)
@@ -53,10 +68,10 @@ sudo apt install build-essential pkg-config libssl-dev libdrm-dev libdrm-amdgpu1
**Fedora:** **Fedora:**
```bash ```bash
sudo dnf install gcc pkg-config openssl-devel sudo dnf install gcc pkg-config openssl-devel libdrm-devel libdrm-amdgpu
``` ```
**Arch Linux:** **Arch Linux:**
```bash ```bash
sudo pacman -S base-devel openssl sudo pacman -S base-devel openssl libdrm
``` ```
+8 -7
View File
@@ -27,21 +27,21 @@ sudo apt install socktop socktop-agent
sudo systemctl enable --now socktop-agent sudo systemctl enable --now socktop-agent
``` ```
Run `socktop` to monitor your local system or connect to remote agents. Then connect to it: `socktop ws://localhost:3000/ws` — or to any remote agent by hostname.
## Option 2: Cargo Installation ## Option 2: Cargo Installation
Install from crates.io: Install from crates.io:
```bash ```bash
# Install GPU support libraries (required) # Install GPU support libraries (see Prerequisites for other distros)
sudo apt install libdrm-dev libdrm-amdgpu1 sudo apt install libdrm-dev libdrm-amdgpu1
# Install the TUI client # Install the TUI client
cargo install socktop cargo install socktop
# Install the agent # Install the agent
cargo install socktop-agent cargo install socktop_agent
# Run the agent manually or set up as a service (see Agent Service Setup) # Run the agent manually or set up as a service (see Agent Service Setup)
socktop_agent socktop_agent
@@ -67,11 +67,12 @@ This spins up a temporary local agent on port 3231, connects to it, and stops wh
# Quick demo (no agent setup needed) # Quick demo (no agent setup needed)
socktop --demo socktop --demo
# Monitor your local system (requires agent running) # Connect to an agent (local or remote) — note the /ws path
socktop socktop ws://localhost:3000/ws
# Or connect to a remote agent
socktop ws://hostname: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. The TUI displays system metrics in real-time.
+11 -1
View File
@@ -1,6 +1,13 @@
# Upgrading # Upgrading
This guide covers upgrading socktop and socktop-agent to newer versions. 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](../usage/general.md#killing-a-process)** — older agents keep reporting dead processes, so killed rows would linger on screen.
## Upgrading via APT ## Upgrading via APT
@@ -30,6 +37,9 @@ socktop_agent --version
# Check service status # Check service status
sudo systemctl status socktop-agent 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 ## Upgrading via Cargo
+13 -8
View File
@@ -1,11 +1,11 @@
# Introduction # Introduction
![socktop logo](https://raw.githubusercontent.com/jasonwitty/socktop/master/docs/socktop_demo.apng) ![socktop demo](https://raw.githubusercontent.com/jasonwitty/socktop/master/docs/socktop_demo_1_60.apng)
**socktop** is a TUI-first remote system monitor built with Rust. Two components: **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 (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 - **socktop_agent** - A lightweight background service that collects and serves system metrics over WebSocket
## Features ## Features
@@ -15,8 +15,11 @@
- Disks: per-device usage - Disks: per-device usage
- Network: per-interface throughput with sparklines - Network: per-interface throughput with sparklines
- Temperatures: CPU (optional) - Temperatures: CPU (optional)
- Top processes (top 50): sortable by CPU% or memory, scrollable - 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 - Optional GPU metrics
- Compact layout for small terminal windows (automatic, or pinned with `--compact`)
- Remote monitoring via WebSocket (JSON over WS) - 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 WSS (TLS): agent auto-generates self-signed cert on first run, client pins cert via --tls-ca/-t
- Optional auth token - Optional auth token
@@ -62,19 +65,21 @@ Spins up a temporary local agent on port 3231 and connects to it. Stops automati
socktop is actively maintained and used in production environments. The project follows semantic versioning and maintains backward compatibility within major versions. socktop is actively maintained and used in production environments. The project follows semantic versioning and maintains backward compatibility within major versions.
- **Current Version**: 1.50.x - **Current Version**: 1.60.x — see [GitHub Releases](https://github.com/jasonwitty/socktop/releases) for release notes
- **Minimum Rust Version**: 1.70+ - **Supported Platforms**: Linux (amd64, arm64, armhf, riscv64), Windows, macOS (client) — see [Platform Notes](./installation/platform-notes.md)
- **Supported Platforms**: Linux (amd64, arm64, armhf, riscv64)
- **License**: MIT - **License**: MIT
Wire changes between versions are additive: mixed client/agent versions keep working during rollouts.
## Community and Support ## Community and Support
- **GitHub Repository**: [https://github.com/jasonwitty/socktop](https://github.com/jasonwitty/socktop) - **GitHub Repository**: [https://github.com/jasonwitty/socktop](https://github.com/jasonwitty/socktop)
- **Release Notes**: [GitHub Releases](https://github.com/jasonwitty/socktop/releases)
- **Issue Tracker**: Report bugs and request features on GitHub - **Issue Tracker**: Report bugs and request features on GitHub
- **crates.io**: - **crates.io**:
- [socktop](https://crates.io/crates/socktop) - TUI client - [socktop](https://crates.io/crates/socktop) - TUI client
- [socktop-agent](https://crates.io/crates/socktop-agent) - Background agent - [socktop_agent](https://crates.io/crates/socktop_agent) - Background agent
- [socktop-connector](https://crates.io/crates/socktop-connector) - Library for integrations - [socktop_connector](https://crates.io/crates/socktop_connector) - Library for integrations
- **APT Repository**: [https://jasonwitty.github.io/socktop/](https://jasonwitty.github.io/socktop/) - **APT Repository**: [https://jasonwitty.github.io/socktop/](https://jasonwitty.github.io/socktop/)
## Next Steps ## Next Steps
+15
View File
@@ -0,0 +1,15 @@
# Known Issues
Current limitations worth knowing about. See the [issue tracker](https://github.com/jasonwitty/socktop/issues) for the live list.
## Process kill inside containers
The kill feature only offers itself when the agent is local (see [Killing a Process](./usage/general.md#killing-a-process)). A client running inside a container with **host networking but its own PID namespace** can pass that local-agent check even though its PID view differs from the host's. The PID-reuse guard (the process name must still match at signal time) limits the blast radius, but avoid using the kill feature from inside such containers.
## Switching between agents of different versions mid-session
When socktop detects an old agent without the per-process endpoints, it remembers that the details view is unsupported. If you then reconnect the same session to a *different, older* agent, that detection may not reset correctly. Restart socktop when hopping between agents that are generations apart.
## Zellij plugin example
The in-repo `zellij_socktop_plugin` example does not currently compile and is pending a rework. This does not affect [monitoring multiple hosts with Zellij](./advanced/zellij.md), which just runs the normal client in panes.
+31 -20
View File
@@ -1,6 +1,16 @@
# TLS Configuration # TLS Configuration
Secure your socktop agent connections with TLS/SSL encryption. 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-hostname` off, any server certificate was silently accepted. If you use TLS, make sure your clients are 1.60 or newer.
### Enable TLS (Auto-Generated Certificate) ### Enable TLS (Auto-Generated Certificate)
The agent automatically generates a self-signed certificate on first run when you enable TLS: The agent automatically generates a self-signed certificate on first run when you enable TLS:
@@ -13,6 +23,7 @@ socktop_agent --enableSSL --port 8443
The certificate is stored at: The certificate is stored at:
- **Linux (XDG)**: `$XDG_CONFIG_HOME/socktop_agent/tls/cert.pem` (defaults to `~/.config/socktop_agent/tls/`) - **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 agent prints the certificate location on first run
- The private key (`key.pem`) is created with mode `0600`; agents also tighten permissions on existing keys at startup
**Example output:** **Example output:**
``` ```
@@ -67,19 +78,30 @@ socktop --tls-ca ~/socktop-agent-cert.pem wss://hostname:8443/ws
socktop -t ~/socktop-agent-cert.pem wss://hostname:8443/ws socktop -t ~/socktop-agent-cert.pem wss://hostname:8443/ws
``` ```
**Note:** Providing `--tls-ca/-t` automatically upgrades `ws://` to `wss://` if you forget the protocol. **Notes:**
- Providing `--tls-ca/-t` automatically upgrades `ws://` to `wss://` if you forget the protocol.
- Copy only `cert.pem` to clients — **never** the private key (`key.pem`); it stays on the agent.
- You can monitor multiple agents by passing a different `--tls-ca` per invocation, or better, saving one [profile](../usage/connection-profiles.md) per host.
### Example Profile with SSL ### 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:
```bash ```bash
socktop wss://server:3000 # 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
``` ```
Profile: 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`):
```json ```json
File: /home/jasonw/.config/socktop/profiles.json
{ {
"profiles": { "profiles": {
"local": { "local": {
@@ -87,30 +109,19 @@ File: /home/jasonw/.config/socktop/profiles.json
}, },
"rpi-master": { "rpi-master": {
"url": "wss://rpi-master:8443/ws", "url": "wss://rpi-master:8443/ws",
"tls_ca": "/home/jasonw/.config/socktop/rpi-master.pem", "tls_ca": "/home/user/.config/socktop/rpi-master.pem",
"metrics_interval_ms": 1000, "metrics_interval_ms": 1000,
"processes_interval_ms": 5000 "processes_interval_ms": 5000
}, },
"rpi-worker-1": { "rpi-worker-1": {
"url": "wss://192.168.1.102:8443/ws", "url": "wss://192.168.1.102:8443/ws",
"tls_ca": "/home/jasonw/.config/socktop/rpi-worker-1.pem", "tls_ca": "/home/user/.config/socktop/rpi-worker-1.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-2": {
"url": "ws://192.168.1.103:8443/ws",
"tls_ca": "/home/jasonw/.config/socktop/rpi-worker-2.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-3": {
"url": "ws://192.168.1.104:8443/ws",
"tls_ca": "/home/jasonw/.config/socktop/rpi-worker-3.pem",
"metrics_interval_ms": 1000, "metrics_interval_ms": 1000,
"processes_interval_ms": 5000 "processes_interval_ms": 5000
} }
}, },
"version": 0 "version": 0
} }
``` ```
Then connect with `socktop -P rpi-master`. See [Connection Profiles](../usage/connection-profiles.md).
+32 -48
View File
@@ -1,56 +1,31 @@
# Authentication Token # Authentication Token
This guide covers token-based authentication for securing socktop agent connections. The agent can require a shared token from connecting clients. Without the correct token, the WebSocket connection is rejected.
- **Access Control** - Only authorized clients can connect - **Access control** - only clients that know the token can connect
- **Security** - Prevent unauthorized monitoring of your systems - **Defense in depth** - combine with [TLS](./tls.md) so the token isn't sent in cleartext over untrusted networks
- **Auditability** - Track which tokens are in use
- **Flexibility** - Revoke and rotate tokens as needed
## Configuring Token Authentication ## Agent: Setting the Token
### Agent Configuration The token is configured with the `SOCKTOP_TOKEN` environment variable. (There is no `--token` command-line flag.)
#### APT Installation ### Running Manually
Edit `/etc/default/socktop-agent`:
```bash ```bash
sudo nano /etc/default/socktop-agent SOCKTOP_TOKEN=changeme socktop_agent --port 3000
``` ```
Add your token: ### Running as a systemd Service
```bash Add the environment variable with a drop-in (works for both APT and manual installs):
# Authentication token
TOKEN=7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8=
```
Restart the service:
```bash
sudo systemctl restart socktop-agent
```
#### Cargo Installation
Start the agent with the token:
```bash
socktop_agent --token "7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8="
```
Or with systemd service:
```bash ```bash
sudo systemctl edit socktop-agent sudo systemctl edit socktop-agent
``` ```
Add environment variable:
```ini ```ini
[Service] [Service]
Environment="TOKEN=7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8=" Environment=SOCKTOP_TOKEN=changeme
``` ```
```bash ```bash
@@ -58,24 +33,30 @@ sudo systemctl daemon-reload
sudo systemctl restart socktop-agent sudo systemctl restart socktop-agent
``` ```
### Client Configuration Alternatively, uncomment the `# Environment=SOCKTOP_TOKEN=changeme` line that ships in the packaged unit file.
#### Command Line ## 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 `?`:
```bash ```bash
# Pass token via command line socktop "ws://server:3000/ws?token=changeme"
socktop ws://server:3000 -t "7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8="
# With TLS
socktop --tls-ca /path/to/cert.pem "wss://server:8443/ws?token=changeme"
``` ```
#### Connection Profile **Warning:** the client's `-t` flag is short for `--tls-ca` (a certificate path), not for the token.
Add token to profile (`~/.config/socktop/profiles.json`): ### In a Connection Profile
Store the token as part of the profile URL (`~/.config/socktop/profiles.json`):
```json ```json
{ {
"profiles": { "profiles": {
"secure-server": { "secure-server": {
"url": "ws://server.example.com:3000/ws?token=7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8=" "url": "ws://server.example.com:3000/ws?token=changeme"
} }
}, },
"version": 0 "version": 0
@@ -88,12 +69,15 @@ Then connect:
socktop -P secure-server socktop -P secure-server
``` ```
#### Environment Variable **Note:** the profiles file then contains the token in plaintext — keep its permissions restrictive.
## Generating a Strong Token
```bash ```bash
# Set token in environment openssl rand -base64 32
export SOCKTOP_TOKEN="7KJ9m3LnP4qR8sT2vW5xY6zA1bC3dE4fG7hI9jK0lM8="
# Connect without specifying token
socktop ws://server:3000
``` ```
## Recommendations
- On untrusted networks, always combine the token with [TLS](./tls.md); over plain `ws://` the token is visible to anyone who can capture traffic.
- Rotate the token by updating `SOCKTOP_TOKEN` on the agent, restarting the service, and updating client profiles.
+83 -93
View File
@@ -1,115 +1,105 @@
# Configuration # Configuration
This guide covers all configuration options for socktop client and agent. 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 ## Client Configuration
### Configuration File Location
By default, socktop looks for configuration in:
- **Linux**: `~/.config/socktop/`
- **Custom**: Set `XDG_CONFIG_HOME` environment variable
### Command-Line Options ### Command-Line Options
```bash ```
socktop_agent --help socktop [--tls-ca CERT_PEM|-t CERT_PEM] [--verify-hostname] [--profile NAME|-P NAME]
[--save] [--demo] [--compact] [--metrics-interval-ms N]
OPTIONS: [--processes-interval-ms N] [ws://HOST:PORT/ws]
--port <PORT> Port to listen on [default: 3000]
--host <HOST> Host/IP to bind to [default: 0.0.0.0]
--token <TOKEN> Authentication token (optional)
--tls-cert <FILE> TLS certificate path (optional)
--tls-key <FILE> TLS private key path (optional)
--log-level <LEVEL> Log level: error, warn, info, debug, trace
--cache-duration <MS> Metrics cache duration in milliseconds [default: 1000]
--max-processes <NUM> Maximum processes to report [default: 100]
--enable-journald Enable journald log collection
--journald-lines <NUM> Number of journal lines to keep [default: 1000]
``` ```
### Configuration File (APT Installation) | Option | Description |
|---|---|
| `--tls-ca <FILE>`, `-t <FILE>` | Pin the agent's TLS certificate (PEM). Auto-upgrades `ws://` to `wss://`. See [TLS Configuration](../security/tls.md) |
| `--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) |
Edit `/etc/default/socktop-agent`: **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](../security/token.md).
### Configuration Files
The client stores connection profiles in:
- `$XDG_CONFIG_HOME/socktop/profiles.json`
- `~/.config/socktop/profiles.json` when `XDG_CONFIG_HOME` is not set
See [Connection Profiles](./connection-profiles.md) 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](../security/token.md).
### 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 (116). 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:
```bash ```bash
# Port configuration sudo systemctl edit socktop-agent
PORT=3000
# Bind address (0.0.0.0 for all interfaces, 127.0.0.1 for local only)
HOST=0.0.0.0
# Authentication token
# Uncomment and set for token-based auth
# TOKEN=your-secret-token-here
# TLS configuration
# Uncomment to enable TLS
# TLS_CERT=/etc/socktop/cert.pem
# TLS_KEY=/etc/socktop/key.pem
# Log level (error, warn, info, debug, trace)
LOG_LEVEL=info
# Cache duration (milliseconds)
CACHE_DURATION=1000
# Maximum processes to report
MAX_PROCESSES=100
# Enable journald collection
ENABLE_JOURNALD=false
# Additional options
# OPTIONS="--some-option --another-option"
``` ```
After editing, restart the service: ```ini
[Service]
Environment=SOCKTOP_TOKEN=changeme
Environment=SOCKTOP_AGENT_GPU=0
```
Then:
```bash ```bash
sudo systemctl daemon-reload
sudo systemctl restart socktop-agent sudo systemctl restart socktop-agent
``` ```
### Environment Variables (debugging) To change the port or enable TLS, override `ExecStart` (it must be cleared first in a drop-in):
Override settings with environment variables: ```ini
[Service]
```bash ExecStart=
# Refresh rate ExecStart=/usr/bin/socktop_agent --enableSSL --port 8443
export SOCKTOP_REFRESH_RATE=2000
# Default profile
export SOCKTOP_DEFAULT_PROFILE=production
# Config directory
export SOCKTOP_CONFIG_DIR=~/.config/socktop
# Disable TLS verification (not recommended)
export SOCKTOP_NO_VERIFY_TLS=1
# Authentication token
export SOCKTOP_TOKEN=your-secret-token
``` ```
### Agent Environment Variables (debugging) See [Agent Service Setup](../installation/agent-service.md) for the full service walkthrough.
```bash
# Port
export SOCKTOP_AGENT_PORT=3000
# Host
export SOCKTOP_AGENT_HOST=0.0.0.0
# Token
export SOCKTOP_AGENT_TOKEN=secret
# TLS cert path
export SOCKTOP_AGENT_TLS_CERT=/path/to/cert.pem
# TLS key path
export SOCKTOP_AGENT_TLS_KEY=/path/to/key.pem
# Log level
export SOCKTOP_AGENT_LOG_LEVEL=info
```
+1 -1
View File
@@ -7,7 +7,7 @@ Connection profiles allow you to save frequently used agent connections for quic
Instead of typing the full WebSocket URL every time: Instead of typing the full WebSocket URL every time:
```bash ```bash
socktop ws://production-server.example.com:3000 socktop ws://production-server.example.com:3000/ws
``` ```
You can save it as a profile and use: You can save it as a profile and use:
+45 -50
View File
@@ -11,7 +11,7 @@ Try socktop without any setup:
socktop --demo 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"). 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 ### Interactive Mode
@@ -27,14 +27,14 @@ Enter number (or blank to abort):
Select a number to connect, or choose `demo` (always available). Press Enter on blank to abort. Select a number to connect, or choose `demo` (always available). Press Enter on blank to abort.
### Monitor Remote System ### Monitor a Remote System
Connect to a remote agent by specifying the WebSocket URL: Connect to a remote agent by specifying the WebSocket URL (note the `/ws` path):
```bash ```bash
socktop ws://hostname:3000/ws socktop ws://hostname:3000/ws
socktop ws://192.168.1.100:3000/ws socktop ws://192.168.1.100:3000/ws
socktop wss://secure-host:8443/ws # With TLS socktop --tls-ca /path/to/cert.pem wss://secure-host:8443/ws # With TLS
``` ```
### Using Connection Profiles ### Using Connection Profiles
@@ -44,29 +44,12 @@ For frequently monitored systems, use profiles:
```bash ```bash
# Use a saved profile # Use a saved profile
socktop -P production-server socktop -P production-server
socktop -P rpi-cluster-01 socktop --profile rpi-cluster-01
# List available profiles
socktop --list-profiles
``` ```
See [Connection Profiles](./connection-profiles.md). Running `socktop` with no arguments lists your saved profiles interactively. See [Connection Profiles](./connection-profiles.md).
## Keyboard and Mouse ## Finding Processes
### Keyboard
- Quit: `q` or `Esc`
### 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
### Filtering Processes
Press `/` to enter filter mode: Press `/` to enter filter mode:
@@ -74,42 +57,54 @@ Press `/` to enter filter mode:
Filter: pyth_ Filter: pyth_
``` ```
This will show only processes matching "pyth" (case-insensitive). Press `ESC` to clear filter. 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 ## Command Line Options
### Client Options
```bash
socktop [OPTIONS] [URL]
OPTIONS:
-P, --profile <PROFILE> Use a connection profile
-t, --token <TOKEN> Authentication token
--tls-ca <FILE> CA certificate for TLS verification
--verify-hostname Enable strict hostname verification for TLS
--metrics-interval-ms <MS> Fast metrics polling interval (default: 500)
--processes-interval-ms <MS> Process list polling interval (default: 2000)
--list-profiles List available connection profiles
-h, --help Show help information
-V, --version Show version information
ARGUMENTS:
[URL] WebSocket URL (e.g., ws://host:3000)
``` ```
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](./configuration.md) for the full option reference, and [Keyboard and Mouse Controls](./keyboard-mouse.md) for all key bindings.
### Examples ### Examples
```bash ```bash
# Connect with custom intervals # Connect with custom intervals
socktop ws://server:3000 --metrics-interval-ms 750 --processes-interval-ms 3000 socktop --metrics-interval-ms 750 --processes-interval-ms 3000 ws://server:3000/ws
# Connect with authentication token # Connect with an authentication token (query parameter, quoted)
socktop ws://server:3000 -t mySecretToken socktop "ws://server:3000/ws?token=mySecretToken"
# Connect with TLS and custom CA # Connect with TLS, pinning the agent's certificate
socktop wss://server:3000 --tls-ca /path/to/ca.pem socktop --tls-ca /path/to/cert.pem wss://server:8443/ws
# Connect with TLS and hostname verification # Connect with TLS and strict hostname verification
socktop wss://server:3000 --tls-ca /path/to/ca.pem --verify-hostname socktop --tls-ca /path/to/cert.pem --verify-hostname wss://server:8443/ws
# Pin the compact layout
socktop --compact -P rpi-cluster-01
``` ```
+2
View File
@@ -12,6 +12,7 @@
- `c` - Clear search filter - `c` - Clear search filter
- `↑/↓` - Navigate - `↑/↓` - Navigate
- `Enter` - Open details - `Enter` - Open details
- `t` - Terminate selected process (local agents only; opens a Terminate / Force kill confirmation — see [Killing a Process](./general.md#killing-a-process))
- `x` - Clear selection - `x` - Clear selection
### Search (after /) ### Search (after /)
@@ -28,6 +29,7 @@
### Process Details ### Process Details
- `x` - Close - `x` - Close
- `p` - Navigate to parent - `p` - Navigate to parent
- `t` - Terminate this process (local agents only)
- `j/k` - Scroll threads ↓/↑ - `j/k` - Scroll threads ↓/↑
- `d/u` - Scroll threads (10 lines) - `d/u` - Scroll threads (10 lines)
- `[` / `]` - Scroll journal - `[` / `]` - Scroll journal