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/
โ”œโ”€โ”€ scripts/
โ”‚   โ””โ”€โ”€ 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.

Grafana Dashboard Example

A complete and pre-configured Grafana dashboard template for VictoriaMetrics is provided in the resources/grafana-dashboard.json file. You can import this JSON directly into your Grafana instance to instantly get a comprehensive visualization of your SysHealth metrics.

Grafana Dashboard Example


๐Ÿ“„ 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.3.tar.gz (457.5 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.3-cp312-cp312-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.12Windows x86-64

syshealth-0.0.3-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.3.tar.gz.

File metadata

  • Download URL: syshealth-0.0.3.tar.gz
  • Upload date:
  • Size: 457.5 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.3.tar.gz
Algorithm Hash digest
SHA256 0ee63560d78f33661f9ebdcb73e251308822d064212a6ebd93f0ebd6f1d60916
MD5 da6334e018fa54c4dc54dd997b14f37b
BLAKE2b-256 ce1f1a5566a8f52cede5b537fcb55a77275f5f06628772e6edd87f4a8637da42

See more details on using hashes here.

Provenance

The following attestation bundles were made for syshealth-0.0.3.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.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: syshealth-0.0.3-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.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 9b79c7aa4ffd581f0c74b3af83e56859f3be8973fd7c6982758973bc2e969902
MD5 9e70aa5bdd9c2c21e9e25dd1c8378621
BLAKE2b-256 7fa0e827669168ca8c097bf8624d7afe72b6a1628daf7166b26b2d844042c90a

See more details on using hashes here.

Provenance

The following attestation bundles were made for syshealth-0.0.3-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.3-cp312-cp312-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for syshealth-0.0.3-cp312-cp312-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 60c82ddb17847c4ed8f5e8c67ede9ebc69926befbf63f507409f0e0a0c3d19ea
MD5 131ae1dba30e0e1ee4f335e928754260
BLAKE2b-256 286b72ae48f27ba5ec4638b272e2d8ad977b2eb41ec5232d0fa7fcdacdaf9007

See more details on using hashes here.

Provenance

The following attestation bundles were made for syshealth-0.0.3-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