Skip to content

Repository files navigation

grainx

CI Rust License: MIT

A Rust terminal system monitor for CPU, memory, disks, network activity, processes, and host metadata.

grainx is a pre-1.0 project. The repository documents the implemented behavior and the checks that run in CI; it does not publish unsupported runtime or benchmark numbers.

What it does

  • Interactive terminal dashboard with Unicode/Braille charts.
  • Local system collection through sysinfo: CPU, memory, disks, network counters, processes, OS, kernel, and uptime.
  • Optional analytics: z-score anomaly detection, Pearson correlation, moving-average estimates, and a deliberately simple arithmetic formula evaluator.
  • Adaptive refresh and frame skipping when CPU load is high.
  • Optional HTTP metrics service with GET /health and GET /metrics.
  • JSON and CSV snapshots from local or remote metrics.
  • JSON configuration with environment-variable and CLI overrides.
  • Shell completion generation for Bash, Elvish, Fish, PowerShell, and Zsh.

The term agent in this repository means the HTTP metrics process. It is not an AI or LLM agent.

Quick start

Prerequisites:

  • Stable Rust 1.88 or newer. The crate uses Rust edition 2024. This minimum is checked against the committed dependency lockfile.
  • An interactive terminal for the monitor command.
git clone https://github.com/rustfuture/grainx.git
cd grainx

# Run the local dashboard
cargo run --locked

# Build an optimized binary
cargo build --locked --release

The default command is monitor. In a headless environment, use the agent or export command instead.

Commands

# Interactive dashboard
cargo run --locked -- monitor

# Local HTTP metrics service; the bind address must be loopback
cargo run --locked -- agent --bind 127.0.0.1 --port 9090

# Export one snapshot without starting the TUI
cargo run --locked -- export

# Export from a running remote agent
cargo run --locked -- export --remote http://127.0.0.1:9090

# Read metrics in the terminal
curl http://127.0.0.1:9090/health
curl http://127.0.0.1:9090/metrics

# Connect the TUI to a remote agent
cargo run --locked -- monitor --remote http://127.0.0.1:9090

# Generate shell completions
cargo run --locked -- completions bash

The agent exposes host metrics without authentication, TLS, or rate limiting, so it refuses to start on any address that is not loopback: --bind 0.0.0.0 and a LAN address exit with an error instead of listening. That boundary is enforced in the program, not only in this document. Loopback is still not a complete protection — it does not separate users or processes on the same machine, and anything that can reach localhost can read the metrics. Remote metrics access is out of scope for this version; if you need it, put an authenticated transport in front of the agent.

Configuration

The monitor reads dashboard_config.json. If the file is missing, grainx creates a default configuration. The precedence order is:

  1. dashboard_config.json
  2. Environment variables
  3. Monitor CLI flags

Supported environment overrides include GRAINX_REFRESH_INTERVAL_MS, GRAINX_CPU_WARNING_THRESHOLD, GRAINX_MEMORY_WARNING_THRESHOLD, and GRAINX_COLOR_THEME. See dashboard_config.json and src/config.rs for the current schema.

Controls

Key Action
q or Esc Quit
Up / Down Select a process
p Pause or resume
k Request process termination
r Refresh the view
a Toggle adaptive refresh
s Save a snapshot

Process termination is subject to the operating system permissions of the user running grainx.

Metrics Semantics

  • CPU Usage: System-wide CPU utilization is calculated as the average utilization across all logical cores since the last refresh. The default refresh interval is 1 second (1000ms), which provides a balanced sampling window.
  • Memory Usage: Physical memory utilization reported by the operating system, excluding swap.
  • Network I/O: network_rx_bytes and network_tx_bytes are the bytes received and transmitted during the most recent sampling interval (a per-interval delta reported by sysinfo). They are not cumulative counters and are not rates. The TUI labels the same values as kilobytes for the last interval.
  • Sampling Interval: By default, the system monitor samples state every 1000ms. This is configurable via GRAINX_REFRESH_INTERVAL_MS. Adaptive refresh can increase this interval (slowing down the sampling rate) up to 2000ms when system CPU usage exceeds the configured warning threshold (default 80%).

Demos

See demos/ for verified captures with build identity, artifact hashes, a privacy review, and reproduction commands:

  • tui_capture_2026-09-12-contract-80x24.* and -110x50.* — the enforced bounded-capture contract at two terminal sizes, showing the current Network I/O: ... (last interval) label.
  • http_capture_2026-09-11.txt — real GET /health and GET /metrics output plus a local export run from the built binary.
  • verification_2026-09-11-remote-export.md — CLI-boundary verification of the remote-export fix: exit 0 against a live grainx agent, and controlled non-zero errors for unreachable, malformed, and http://127.0.0.1:0 endpoints with no panic text.
  • verification_2026-09-12-braille-termination.md — PTY proof that braille rendering and frame completion are bounded.

The older 2026-09-06 captures are kept and marked historical.

cargo build --locked
python3 -m venv /tmp/grainx-render-venv && /tmp/grainx-render-venv/bin/pip install pyte==0.8.2
/tmp/grainx-render-venv/bin/python demos/capture_tui.py target/debug/grainx /tmp/tui.raw /tmp/tui.txt 5 110 50

See demos/README.md and demos/verification_2026-09-11.md for the full commands, hashes, privacy review, and limitations.

Performance and Microbenchmarks

Microbenchmarks run via cargo bench (Criterion) measure isolated components on the test host; they are not a universal performance claim. A recorded run with its machine, OS, toolchain, command, and base commit is kept in benches/results/2026-09-10-macos-arm64.txt. To reproduce:

cargo bench --locked

Scope notes:

  • system_monitor_refresh constructs a fresh SystemMonitor and performs a single refresh() per iteration. It measures cold construction plus one refresh, and does not measure the CPU or memory cost of a long-running monitor loop.
  • The formula, prediction, and correlation benchmarks measure the analytical functions only. Those functions do allocate (metric substitution and token splitting build String/Vec values); they are not zero-allocation.

Architecture

  • Monitor (SystemMonitor): Gathers raw state using sysinfo.
  • Analytics Engine (analytics::*): Performs formula evaluation and anomaly detection on the collected metrics. evaluate_metric_formula substitutes whitespace-separated tokens and evaluates strictly left-to-right with no operator precedence; see its doc comment for the full contract.
  • Agent Server (agent::*): Exposes collected metrics via an HTTP server using axum. Binds to 127.0.0.1:9090 by default and refuses any non-loopback address, because it serves without TLS or authentication.
  • TUI Renderer (ui::*, tui::*): Renders the terminal dashboard using crossterm. Employs frame-skipping and adaptive refresh intervals to gracefully degrade under heavy load.

Limitations

  • Security: The HTTP agent has no TLS, authentication, or rate limiting. It refuses any non-loopback bind address at runtime, and src/agent.rs tests that 0.0.0.0, ::, and ordinary interface addresses are rejected. Loopback does not isolate users or processes on the same host, and remote metrics access is out of scope for this version.
  • Completeness: Network and disk I/O are aggregates and do not currently drill down into per-socket or per-file statistics.
  • OS Support: CI tests Linux and macOS on stable Rust. Windows is not verified and is not covered by the CI matrix.

Verification

Run the same checks locally that CI runs:

cargo fmt --check
cargo check --locked --all-targets
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
cargo bench --locked --no-run

The Criterion benchmarks can be executed locally with cargo bench. Their results depend on the machine, operating system, and toolchain, so this repository does not present a universal performance claim. See docs/verification.md for the verification contract and docs/architecture.md for the module boundaries.

Compatibility and versioning

grainx follows 0.x semantics: the version number is a statement about scope, not a compatibility promise. While the major version is 0, a breaking change to the CLI, the configuration schema, or the exported JSON/CSV shape bumps the minor version, and a compatible fix bumps the patch version. Every change is recorded in CHANGELOG.md.

Platform Status
Linux Verified by CI on stable Rust, plus an all-target compilation job on the minimum supported version.
macOS Verified by CI, and used for the recorded captures under demos/.
Windows Not verified; the CI matrix does not cover it.

The minimum supported Rust version is 1.88; raising it is a minor-version change. A 1.0 would mean the command surface, the configuration schema, and the exported formats have stopped moving, not that every idea in TODO.md has been implemented.

License

grainx is released under the MIT License. See LICENSE.

About

Rust terminal system monitor with an optional HTTP metrics service and JSON/CSV export

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages