Skip to main content

A lightweight computer constants monitor using Rust and Python

Project description

๐Ÿ–ฅ๏ธ๐Ÿฉบ SysHealth

PyPI version CI Pipeline

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

global-metrics demo

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

process demo

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] or uv 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_gen after every Rust change so that the .pyi stub 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 sysinfo does not provide (e.g. GPU name), implement it as a plain Python helper function in cli.py using subprocess or the platform module โ€” see get_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/query using field names as metric names, e.g. cpu_usage, ram_percent.


๐Ÿ“„ License

See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

syshealth-0.0.2.tar.gz (67.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

syshealth-0.0.2-cp312-cp312-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.12Windows x86-64

syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl (4.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.38+ x86-64

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

Hashes for syshealth-0.0.2.tar.gz
Algorithm Hash digest
SHA256 45f5b5f144fb05a062da0cd17d649537549a7883b53f0ae36cf1292612c5d54d
MD5 9880bca633f929286fa5416568b116f1
BLAKE2b-256 77f08a2082261f4b2b8850a86cee0eb884f30e1b0c105ff903b07557c0281ad7

See more details on using hashes here.

Provenance

The following attestation bundles were made for syshealth-0.0.2.tar.gz:

Publisher: workflow.yml on opierre/syshealth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for syshealth-0.0.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2fe72dfac34744ef0ff17e5af8f8ff9e1b9fba4143a5c4827b992d300c48fc18
MD5 11514286cf54484ff037254db7f424c1
BLAKE2b-256 5d32507d277f2784291adce2ecf1348b3b808377b0a90cbb7951b2de1cfec611

See more details on using hashes here.

Provenance

The following attestation bundles were made for syshealth-0.0.2-cp312-cp312-win_amd64.whl:

Publisher: workflow.yml on opierre/syshealth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for syshealth-0.0.2-cp312-cp312-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 2190bded358a0c39c3f3983ae6fe7a31cdb8a296530f5f4f37ba295991fee2c5
MD5 8e894da580c88d1ff8a387a849967b5e
BLAKE2b-256 07cff0bfa3902e7254396ca6071b67058d47b3d49cc5a172dd85c066ec88bd5b

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page