A lightweight computer constants monitor using Rust and Python
Project description
๐ฅ๏ธ๐ฉบ SysHealth
A highly optimized, cross-platform system resource monitor with a Rust core and a beautiful Python CLI.
SysHealth pushes the performance-critical work (polling loops, hardware inspection, network sampling) into compiled Rust code via PyO3, while keeping the Python surface clean, ergonomic, and easy to extend.
โจ Features
- โก Near-zero CPU footprint โ all heavy lifting runs in compiled Rust via
sysinfo - ๐ฅ๏ธ Rich terminal UI โ colour-coded panels with adaptive side-by-side layout
- ๐ Cross-platform โ Windows and Linux supported
- ๐ Extensible โ adding a new Rust metric takes fewer than 10 lines
- ๐งช Tested โ pytest integration tests with full mock coverage
- ๐ก Background Exporters โ Start a zero-overhead Rust background thread to continuously export metrics to MQTT or VictoriaMetrics
- ๐๏ธ Configurable Priorities โ Control the exporter thread priority dynamically (from 0 to 5) so it never impacts system performance
๐ Installation
Install SysHealth directly from PyPI using uv (recommended) or standard pip:
# Install system-wide or in your active environment
uv tool install syshealth
# OR using standard pip
pip install syshealth
(Optional: If you plan to use the MQTT exporter, install with the mqtt extra: uv tool install syshealth[mqtt])
๐ Usage
CLI Dashboard (global-metrics)
Displays a full system snapshot dashboard. Panels are automatically placed side-by-side when the terminal is wide enough.
syshealth global-metrics
Output panels:
| Panel | Metric | Backend |
|---|---|---|
| ๐ฅ๏ธ System Information | OS name & version | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | Kernel version | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | Hostname | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | CPU brand, cores & threads | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | GPU name | ๐ Python (wmic / lspci subprocess) |
| ๐ฅ๏ธ System Information | Total RAM | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | Available disk space & % | ๐ฆ Rust (sysinfo) |
| ๐ฅ๏ธ System Information | Boot time & uptime | ๐ฆ Rust (sysinfo) |
| ๐ฅ System Users | Real OS user accounts | ๐ฆ Rust (sysinfo) |
| ๐ฅ System Users | Admin rights detection | ๐ Python (group name filtering) |
| โก System Instant Metrics | CPU usage % | ๐ฆ Rust (sysinfo) |
| โก System Instant Metrics | CPU temperature | ๐ฆ Rust (sysinfo components) |
| โก System Instant Metrics | Per-core CPU usage | ๐ฆ Rust (sysinfo) |
| โก System Instant Metrics | Load average (1m / 5m / 15m) | ๐ฆ Rust (sysinfo) |
| โก System Instant Metrics | RAM usage % | ๐ฆ Rust (sysinfo) |
| โก System Instant Metrics | Swap usage % | ๐ฆ Rust (sysinfo) |
| ๐ Top CPU Consumers | Top 4 processes by CPU | ๐ฆ Rust (sysinfo) |
| ๐ Network Instant Metrics | Interface names | ๐ฆ Rust (sysinfo) |
| ๐ Network Instant Metrics | Local IPv4 address | ๐ฆ Rust (sysinfo) |
| ๐ Network Instant Metrics | Rx / Tx speed (MB/s) | ๐ฆ Rust (sysinfo) |
Process Monitor (process)
Monitors all running instances of a named process and shows per-PID resource usage, sorted by CPU consumption.
syshealth process --name python
# or short form:
syshealth process -n chrome.exe
Output table:
| Column | Metric | Backend |
|---|---|---|
| PID | Process identifier | ๐ฆ Rust (sysinfo) |
| CPU Usage (%) | Per-process CPU % | ๐ฆ Rust (sysinfo) |
| RAM Usage (%) | Per-process RAM % of total | ๐ฆ Rust (sysinfo) |
[!NOTE] Rows are sorted descending by CPU usage. If multiple instances of the same process are running (e.g. browser tabs), you will see one row per PID.
Background Service (install-service)
Installs SysHealth as a background service for the current OS (Windows or Linux). Requires Administrator or root privileges.
# Windows: open terminal as Administrator
# Linux: run with sudo
syshealth install-service
[!NOTE] If the service is already installed, you will be prompted to stop and replace it.
Background Exporter (Python API)
[!IMPORTANT] When using the MQTT exporter, ensure you have installed the optional dependency (
pip install syshealth[mqtt]oruv pip install ".[mqtt]") and that your MQTT broker is up and running before starting the exporter.
You can run SysHealth as a background thread in your own Python applications. It will automatically load your configuration from ~/.syshealth/config.json.
from syshealth.monitor import ExporterType, SysHealth
import time
# Use the context manager to ensure graceful shutdown
with SysHealth() as monitor:
# Start background monitoring thread (priority 0 to 5)
# The 'duration' argument will automatically stop the thread after 60 seconds.
monitor.start(refresh_rate=5, exporter_type=ExporterType.MQTT, priority=5, duration=60)
# Do your other work while metrics are exported automatically in Rust
time.sleep(60)
# monitor.stop() is automatically called when exiting the 'with' block!
๐ ๏ธ Development
Prerequisites
| Tool | Purpose |
|---|---|
rustup |
Rust compiler toolchain |
uv |
Python project & venv manager |
Install & Build from Source
# 1. Create virtual environment and compile the Rust extension in one step
uv pip install -e .
# 2. (Optional) install dev dependencies for tests and linting
uv pip install -e ".[dev]"
uv detects maturin as the build backend in pyproject.toml, compiles src/lib.rs, and links the resulting shared library into your local Python environment automatically.
Start External Dependencies
If you plan to use the background exporter for MQTT or VictoriaMetrics, ensure these services are running. You can quickly start them using docker-compose or podman-compose with the provided file:
docker-compose up -d
# OR with podman
podman-compose up -d
Run Tests & Linting
uv sync --group test && uv run pytest # run all tests
uv run ruff format . # auto-format
uv run ruff check . # lint
Rebuild After Rust Changes
Every time you modify src/lib.rs you need to recompile the extension and regenerate the Python stubs:
# 1. Recompile & reinstall the Rust extension into the active venv
uv pip install -e .
# 2. Regenerate Python type stubs (updates python/syshealth/_rust_monitor.pyi)
cargo run --bin stub_gen
๐ง Adding a New Metric
Follow these steps to expose a new piece of system data end-to-end.
Step 1 โ Add the field to GlobalMetricsSnapshot in src/lib.rs
#[gen_stub_pyclass]
#[pyclass(get_all)]
pub struct GlobalMetricsSnapshot {
// ... existing fields ...
pub my_new_metric: f32, // ๐ add your field here
}
Step 2 โ Populate the field inside get_global_metrics()
fn get_global_metrics() -> PyResult<GlobalMetricsSnapshot> {
// ... existing logic ...
let my_new_metric = sys.some_sysinfo_call(); // ๐ gather data
Ok(GlobalMetricsSnapshot {
// ... existing fields ...
my_new_metric, // ๐ include in the struct literal
})
}
Step 3 โ Recompile and regenerate stubs
uv pip install -e .
cargo run --bin stub_gen
Step 4 โ Display it in python/syshealth/cli.py
# Inside global_metrics():
table.add_row("My New Metric:", f"{metrics.my_new_metric:.2f}")
Step 5 โ Update the mock in tests/test_cli.py
mock_metrics.my_new_metric = 42.0
[!IMPORTANT] Always run
cargo run --bin stub_genafter every Rust change so that the.pyistub file stays in sync with the compiled extension. Without this, IDEs and type checkers will show incorrect type information.
[!NOTE] If you need a metric that
sysinfodoes not provide (e.g. GPU name), implement it as a plain Python helper function incli.pyusingsubprocessor theplatformmodule โ seeget_gpu_name()for an example.
๐๏ธ Architecture
syshealth/
โโโ src/
โ โโโ linux/
โ โโโ syshealth.service # systemd service configuration
โ โโโ service_runner.py # ๐ Main program to run with systemd
โ โโโ windows/
โ โโโ syshealth_windows_service.py # ๐ Windows Service implementation
โโโ src/
โ โโโ bin/
โ โ โโโ stub_gen.rs # ๐ฆ Standalone Rust binary to generate Python type stubs
โ โโโ lib.rs # ๐ฆ Rust extension โ sysinfo polling, PyO3 bindings, background thread
โ โโโ exporter/
โ โโโ mod.rs # ๐ฆ Exporter trait + factory (create_exporter)
โ โโโ mqtt.rs # ๐ฆ MQTT exporter (rumqttc, non-blocking channel)
โ โโโ victoria_metrics.rs # ๐ฆ VictoriaMetrics exporter (ureq, non-blocking channel)
โโโ python/
โ โโโ syshealth/
โ โโโ _rust_monitor.pyi # ๐ Auto-generated type stubs (do not edit manually)
โ โโโ monitor.py # ๐ Python wrapper โ SysHealth + ExporterType enum
โ โโโ cli.py # ๐ Typer CLI + Rich display logic
โโโ tests/
โโโ test_cli.py # ๐ Integration tests for all CLI commands
โโโ test_monitor.py # ๐ Integration tests: Rust backend + MQTT subscriber
Data flow โ background exporter
sysinfo (Rust crate)
โโโถ get_global_metrics_internal() [monitoring thread โ priority-adjusted]
โโโถ GlobalMetricsSnapshot (Serialize)
โโโถ serde_json::to_string()
โโโถ mpsc::Sender<String> [non-blocking, exporter worker thread]
โโโถ MqttExporter / VictoriaMetricsExporter
โโโถ Broker / Database
๐ก Receiving Exported Data
MQTT
SysHealth publishes a JSON object (all fields of GlobalMetricsSnapshot) to a single topic every refresh_rate seconds.
| Item | Value |
|---|---|
| Broker address | ~/.syshealth/config.json โ endpoints.mqtt (e.g. localhost:1883) |
| Topic | syshealth/metrics |
| QoS | 0 (At Most Once) |
| Retain | No |
| Payload format | UTF-8 JSON |
Payload fields (all in one JSON object on syshealth/metrics):
| JSON key | Type | Description |
|---|---|---|
cpu_usage |
float |
Global CPU usage % |
cpu_brand |
string |
CPU model name |
ram_percent |
float |
RAM used % |
max_ram |
int |
Total RAM in bytes |
disk_percent |
float |
Disk free % |
available_disk |
int |
Available disk in bytes |
boot_time |
int |
Unix timestamp of last boot |
os_name |
string |
OS name |
os_version |
string |
OS version string |
kernel_version |
string |
Kernel version |
hostname |
string |
Machine hostname |
core_count_physical |
int | null |
Physical CPU core count |
core_count_logical |
int |
Logical CPU thread count |
cpu_temperature |
float | null |
CPU temperature in ยฐC (if available) |
swap_total |
int |
Total swap in bytes |
swap_used |
int |
Used swap in bytes |
network_rx_bytes |
int |
Total bytes received (all interfaces) |
network_tx_bytes |
int |
Total bytes transmitted (all interfaces) |
network_interfaces |
array |
Per-interface [name, rx, tx, [ips]] |
per_core_usage |
array[float] |
Per-logical-core usage % |
load_avg_1m |
float |
1-minute load average |
load_avg_5m |
float |
5-minute load average |
load_avg_15m |
float |
15-minute load average |
users |
array |
[username, [groups]] pairs |
top_processes |
array |
Top 4 CPU consumers โ [name, pid, cpu%] |
Example subscriber (Python):
import json
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
data = json.loads(msg.payload)
print(f"CPU: {data['cpu_usage']:.1f}% RAM: {data['ram_percent']:.1f}%")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_message = on_message
client.connect("localhost", 1883)
client.subscribe("syshealth/metrics")
client.loop_forever()
VictoriaMetrics
SysHealth POSTs the same JSON snapshot to the VictoriaMetrics import endpoint.
| Item | Value |
|---|---|
| Endpoint | ~/.syshealth/config.json โ endpoints.victoriametrics (e.g. http://localhost:8428/api/v1/import) |
| HTTP method | POST |
| Content-Type | application/json |
| Payload format | JSON (same field list as the MQTT table above) |
[!NOTE] Query stored metrics via MetricsQL or
/api/v1/queryusing field names as metric names, e.g.cpu_usage,ram_percent.
๐ License
See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file syshealth-0.0.2.tar.gz.
File metadata
- Download URL: syshealth-0.0.2.tar.gz
- Upload date:
- Size: 67.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45f5b5f144fb05a062da0cd17d649537549a7883b53f0ae36cf1292612c5d54d
|
|
| MD5 |
9880bca633f929286fa5416568b116f1
|
|
| BLAKE2b-256 |
77f08a2082261f4b2b8850a86cee0eb884f30e1b0c105ff903b07557c0281ad7
|
Provenance
The following attestation bundles were made for syshealth-0.0.2.tar.gz:
Publisher:
workflow.yml on opierre/syshealth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
syshealth-0.0.2.tar.gz -
Subject digest:
45f5b5f144fb05a062da0cd17d649537549a7883b53f0ae36cf1292612c5d54d - Sigstore transparency entry: 1592165060
- Sigstore integration time:
-
Permalink:
opierre/syshealth@fb20219e42bde23be6aaa9dce77411e683ebafee -
Branch / Tag:
refs/heads/main - Owner: https://github.com/opierre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@fb20219e42bde23be6aaa9dce77411e683ebafee -
Trigger Event:
push
-
Statement type:
File details
Details for the file syshealth-0.0.2-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: syshealth-0.0.2-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fe72dfac34744ef0ff17e5af8f8ff9e1b9fba4143a5c4827b992d300c48fc18
|
|
| MD5 |
11514286cf54484ff037254db7f424c1
|
|
| BLAKE2b-256 |
5d32507d277f2784291adce2ecf1348b3b808377b0a90cbb7951b2de1cfec611
|
Provenance
The following attestation bundles were made for syshealth-0.0.2-cp312-cp312-win_amd64.whl:
Publisher:
workflow.yml on opierre/syshealth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
syshealth-0.0.2-cp312-cp312-win_amd64.whl -
Subject digest:
2fe72dfac34744ef0ff17e5af8f8ff9e1b9fba4143a5c4827b992d300c48fc18 - Sigstore transparency entry: 1592165112
- Sigstore integration time:
-
Permalink:
opierre/syshealth@fb20219e42bde23be6aaa9dce77411e683ebafee -
Branch / Tag:
refs/heads/main - Owner: https://github.com/opierre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@fb20219e42bde23be6aaa9dce77411e683ebafee -
Trigger Event:
push
-
Statement type:
File details
Details for the file syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.12, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2190bded358a0c39c3f3983ae6fe7a31cdb8a296530f5f4f37ba295991fee2c5
|
|
| MD5 |
8e894da580c88d1ff8a387a849967b5e
|
|
| BLAKE2b-256 |
07cff0bfa3902e7254396ca6071b67058d47b3d49cc5a172dd85c066ec88bd5b
|
Provenance
The following attestation bundles were made for syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl:
Publisher:
workflow.yml on opierre/syshealth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl -
Subject digest:
2190bded358a0c39c3f3983ae6fe7a31cdb8a296530f5f4f37ba295991fee2c5 - Sigstore transparency entry: 1592165087
- Sigstore integration time:
-
Permalink:
opierre/syshealth@fb20219e42bde23be6aaa9dce77411e683ebafee -
Branch / Tag:
refs/heads/main - Owner: https://github.com/opierre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@fb20219e42bde23be6aaa9dce77411e683ebafee -
Trigger Event:
push
-
Statement type: