-
Notifications
You must be signed in to change notification settings - Fork 0
update readme #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update readme #12
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,283 @@ | ||
| # UniProc | ||
|
|
||
| UniProc is a terminal-first process monitor built with Rust and Ratatui. It monitors one process safely by PID or exact name, with a responsive dashboard and script-friendly exports. | ||
| UniProc is a terminal-first process resource monitor built with Rust, Ratatui, Crossterm, and sysinfo. It monitors one running process by PID or exact process name, displays an interactive TUI dashboard, and can export captured samples as CSV or pretty JSON for scripts, reports, and investigations. | ||
|
|
||
| ## Why UniProc | ||
|
|
||
| Use UniProc when you want a lightweight, focused view of one process instead of a full-system monitor. It is useful for watching local services, CLI tools, development servers, stress tests, and short profiling sessions where you care about CPU, memory, disk I/O, and network activity over time. | ||
|
|
||
| ## Features | ||
|
|
||
| - Live CPU, resident memory, disk I/O, and history charts | ||
| - System-wide network traffic shown alongside the selected process (per-process network I/O is not portable) | ||
| - Pause, clear-history, and quit controls | ||
| - Exact process-name lookup that refuses ambiguous matches | ||
| - Bounded in-memory history and reliable terminal cleanup | ||
| - CSV and pretty JSON export with byte-accurate fields | ||
| - Interactive Ratatui dashboard with CPU, resident memory, disk I/O, network, and history views | ||
| - Safe target selection by PID or exact process name | ||
| - Ambiguous process-name protection, with a prompt to select a PID when multiple processes match | ||
| - Pause, clear-history, and quit controls in the dashboard | ||
| - Bounded in-memory history for long-running TUI sessions | ||
| - CSV export for spreadsheet and shell workflows | ||
| - Pretty JSON export for automation and downstream tooling | ||
| - Byte-accurate raw fields in export files | ||
| - Reliable terminal cleanup when leaving the alternate screen | ||
|
|
||
| ## Status | ||
|
|
||
| UniProc is early but usable. The command-line interface and export fields are intentionally small and stable for the current release, but the project is still pre-1.0, so future versions may refine the dashboard and output formats. | ||
|
|
||
| ## Platform Support | ||
|
|
||
| UniProc is built on cross-platform Rust libraries and should work on common Unix-like systems and Windows. | ||
|
|
||
| Current support notes: | ||
|
|
||
| - macOS: expected to work | ||
| - Linux: expected to work | ||
| - Windows: not tested yet, but it should ideally work because the underlying libraries support Windows | ||
|
|
||
| Some metric values are platform dependent. In particular, disk I/O comes from process refresh data exposed by `sysinfo`, and network traffic is reported system-wide because portable per-process network I/O is not available through the current implementation. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - Rust toolchain with Cargo | ||
| - A terminal that supports alternate-screen TUI applications | ||
| - Permission to inspect the target process | ||
|
|
||
| The crate uses Rust edition `2024`, so use a recent stable Rust toolchain. | ||
|
|
||
| ## Installation | ||
|
|
||
| From the repository root: | ||
|
|
||
| ## Use | ||
| ```bash | ||
| cargo build --release | ||
| ``` | ||
|
|
||
| The optimized binary will be created at: | ||
|
|
||
| ```bash | ||
| target/release/uniproc | ||
| ``` | ||
|
|
||
| You can also run directly during development: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 | ||
| cargo run -- --name my-service --interval 500 | ||
| ``` | ||
|
|
||
| ## Quick Start | ||
|
|
||
| Monitor a process by PID: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 | ||
| ``` | ||
|
|
||
| Monitor a process by exact name: | ||
|
|
||
| ```bash | ||
| cargo run -- --name my-service | ||
| ``` | ||
|
|
||
| Sample more frequently: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 --interval 500 | ||
| ``` | ||
|
|
||
| Capture CSV for a fixed duration: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 --duration 60 --csv metrics.csv | ||
| ``` | ||
|
|
||
| Capture JSON for a fixed duration: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 --duration 60 --json metrics.json | ||
| ``` | ||
|
|
||
| Use `p` or `Space` to pause the dashboard, `c` to clear its history, and `q` or `Esc` to quit. Export modes require `--duration` so they always finish predictably. | ||
| ## CLI Reference | ||
|
|
||
| ```text | ||
| uniproc --pid <PID> [OPTIONS] | ||
| uniproc --name <NAME> [OPTIONS] | ||
| ``` | ||
|
|
||
| Exactly one target is required: | ||
|
|
||
| | Option | Description | | ||
| | --- | --- | | ||
| | `--pid <PID>` | Monitor the process with this process ID. | | ||
| | `--name <NAME>` | Monitor a process by exact process name. If multiple processes match, UniProc exits and prints the matching PIDs so you can choose one explicitly. | | ||
|
|
||
| General options: | ||
|
|
||
| | Option | Default | Description | | ||
| | --- | --- | --- | | ||
| | `--interval <MS>` | `1000` | Sampling interval in milliseconds. Must be at least `1`. | | ||
| | `--duration <SECONDS>` | none | Stop collection after this many seconds. Required when using `--csv` or `--json`. | | ||
| | `--csv <PATH>` | none | Write captured samples as CSV instead of starting the interactive dashboard. | | ||
| | `--json <PATH>` | none | Write captured samples as pretty JSON instead of starting the interactive dashboard. | | ||
| | `--help` | none | Print command help. | | ||
| | `--version` | none | Print the UniProc version. | | ||
|
|
||
| Export modes require `--duration` so the command has a defined end. Without `--csv` or `--json`, UniProc starts the interactive dashboard. | ||
|
|
||
| ## Dashboard Controls | ||
|
|
||
| | Key | Action | | ||
| | --- | --- | | ||
| | `p` | Pause or resume sampling. | | ||
| | `Space` | Pause or resume sampling. | | ||
| | `c` | Clear the in-memory dashboard history. | | ||
| | `q` | Quit and return collected samples to the caller. | | ||
| | `Esc` | Quit and return collected samples to the caller. | | ||
|
|
||
| ## Metrics | ||
|
|
||
| UniProc currently collects these fields for each sample: | ||
|
|
||
| | Field | Unit | Notes | | ||
| | --- | --- | --- | | ||
| | `timestamp_ms` | milliseconds | Unix timestamp in milliseconds. | | ||
| | `pid` | process ID | Target process ID. | | ||
| | `name` | string | Process name reported by the operating system. | | ||
| | `cpu_percent` | percent | CPU usage reported by `sysinfo`. | | ||
| | `memory_bytes` | bytes | Resident memory for the process. | | ||
| | `system_memory_bytes` | bytes | Total system memory at sample time. | | ||
| | `virtual_memory_bytes` | bytes | Virtual memory for the process. | | ||
| | `disk_read_bytes` | bytes | Bytes read since the preceding process refresh, platform dependent. | | ||
| | `disk_written_bytes` | bytes | Bytes written since the preceding process refresh, platform dependent. | | ||
| | `network_received_bytes` | bytes | System-wide network bytes received since the preceding refresh. | | ||
| | `network_transmitted_bytes` | bytes | System-wide network bytes transmitted since the preceding refresh. | | ||
|
Comment on lines
+147
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
fd -t f -e rs -0 | xargs -0 -r rg -n -C 6 \
'disk_read_bytes|disk_written_bytes|network_received_bytes|network_transmitted_bytes|read_bytes|written_bytes|refresh|delta|File::create|OpenOptions'Repository: imsudiproy/uniproc Length of output: 10046 Correct the network metric descriptions.
🤖 Prompt for AI Agents |
||
|
|
||
| The dashboard formats byte values for readability. Export files keep raw byte values. | ||
|
|
||
| ## CSV Output | ||
|
|
||
| CSV export writes a header row followed by one row per sample: | ||
|
|
||
| ```text | ||
| timestamp_ms,pid,name,cpu_percent,memory_bytes,system_memory_bytes,virtual_memory_bytes,disk_read_bytes,disk_written_bytes,system_network_received_bytes,system_network_transmitted_bytes | ||
|
Comment on lines
+147
to
+159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
fd -t f -e rs -0 | xargs -0 -r rg -n -C 6 \
'network_received_bytes|network_transmitted_bytes|system_network_received_bytes|system_network_transmitted_bytes|serialize|write_record'Repository: imsudiproy/uniproc Length of output: 5098 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- README schema and related sections ---'
sed -n '125,205p' readme.md
printf '%s\n' '--- Output modules and tests ---'
fd -t f | rg '(^|/)(csv|json|output|readme|test|tests)' | sort
rg -n -C 5 'serde_json|to_string|write\(|CSV|csv|network_received_bytes|network_transmitted_bytes' src tests 2>/dev/null || trueRepository: imsudiproy/uniproc Length of output: 13577 Use the canonical network field names in the CSV header. The CSV serializer writes 🤖 Prompt for AI Agents |
||
| ``` | ||
|
|
||
| Example: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 --duration 30 --csv metrics.csv | ||
| ``` | ||
|
|
||
| ## JSON Output | ||
|
|
||
| JSON export writes a pretty-printed array of sample objects. | ||
|
|
||
| Example: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 --duration 30 --json metrics.json | ||
| ``` | ||
|
|
||
| Example shape: | ||
|
|
||
| ```json | ||
| [ | ||
| { | ||
| "timestamp_ms": 1760000000000, | ||
| "pid": 1234, | ||
| "name": "my-service", | ||
| "cpu_percent": 12.5, | ||
| "memory_bytes": 104857600, | ||
| "system_memory_bytes": 17179869184, | ||
| "virtual_memory_bytes": 4294967296, | ||
| "disk_read_bytes": 4096, | ||
| "disk_written_bytes": 8192, | ||
| "network_received_bytes": 2048, | ||
| "network_transmitted_bytes": 1024 | ||
| } | ||
| ] | ||
| ``` | ||
|
|
||
| ## Behavior and Limitations | ||
|
|
||
| - UniProc monitors one process per run. | ||
| - `--name` uses exact process-name matching, not substring matching. | ||
| - If the process exits while monitoring, UniProc exits with an error. | ||
| - Dashboard history is bounded to avoid unbounded memory growth. | ||
| - Export collection sleeps for the configured interval between samples. | ||
| - Disk I/O values are platform dependent. | ||
| - Network values are system-wide deltas, not per-process network usage. | ||
| - Export paths are overwritten if the target file already exists. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| `process with PID <pid> was not found` | ||
|
|
||
| The PID does not exist or the process exited before UniProc could start sampling. | ||
|
|
||
| `no running process exactly named "<name>"` | ||
|
|
||
| The process name did not match exactly. Check the process name shown by your operating system and try again. | ||
|
|
||
| `"<name>" matches multiple processes` | ||
|
|
||
| More than one process has the same exact name. Re-run UniProc with `--pid` and one of the PIDs printed in the error message. | ||
|
|
||
| `--duration is required with --csv or --json` | ||
|
|
||
| Export mode needs a fixed end time. Add `--duration <SECONDS>`. | ||
|
|
||
| Terminal display looks broken after exit | ||
|
|
||
| UniProc attempts to restore the terminal on exit. If the terminal is still in a bad state after an unexpected interruption, run: | ||
|
|
||
| ```bash | ||
| reset | ||
| ``` | ||
|
|
||
| ## Development | ||
|
|
||
| Run tests: | ||
|
|
||
| ```bash | ||
| cargo test | ||
| ``` | ||
|
|
||
| Check formatting: | ||
|
|
||
| ```bash | ||
| cargo fmt --check | ||
| ``` | ||
|
|
||
| Build the release binary: | ||
|
|
||
| ```bash | ||
| cargo build --release | ||
| ``` | ||
|
|
||
| Run the dashboard against the current shell or another known process: | ||
|
|
||
| ```bash | ||
| cargo run -- --pid 1234 | ||
| ``` | ||
|
|
||
| Optional local stress-test setup on Debian or Ubuntu: | ||
|
|
||
| ```bash | ||
| sudo apt install -y stress | ||
| stress --cpu 1 --timeout 250 | ||
| ``` | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ```text | ||
| src/main.rs CLI parsing and top-level command flow | ||
| src/core/monitor.rs Target resolution and sample collection loop | ||
| src/datasources/cpu_mem.rs Process sampling through sysinfo | ||
| src/output/tui.rs Interactive Ratatui dashboard | ||
| src/output/csv.rs CSV writer | ||
| src/output/json.rs JSON writer | ||
| tests/ Integration tests | ||
| doc/help.md Extra development notes | ||
| ``` | ||
|
|
||
| ## License | ||
|
|
||
| See `LICENSE`. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: imsudiproy/uniproc
Length of output: 24675
🏁 Script executed:
Repository: imsudiproy/uniproc
Length of output: 12495
🌐 Web query:
clap Rust ArgGroup required args multiple default behavior💡 Result:
In the Rust clap library, an ArgGroup allows you to group multiple arguments together to define specific validation rules [1][2]. The behavior of a required ArgGroup is determined by the interaction between the.required and.multiple settings [3][2]. Default Behavior and Settings: 1..multiple(false) (Default): By default, multiple is set to false [3][4]. When combined with.required(true), this enforces that one and only one argument from the group must be present at runtime [3][2]. Providing more than one argument from the group will result in an error [3][2]. 2..multiple(true): When set to true, this allows more than one argument from the group to be used [3][4]. When combined with.required(true), this enforces that at least one argument from the group must be present, but allows for multiple arguments to be used simultaneously [3][2]. Important Considerations: - Required Groups: When an ArgGroup is marked as required, at least one argument from that group must be present at runtime [2]. If all arguments in the group have default values, the group may behave as if it is always present, which can sometimes lead to issues if requirements are not met or conflicts arise [5][6]. - Conflicting Rules: Setting a group as required is subject to other argument rules; conflicting arguments or overrides can take precedence over the required status [7][2]. - Interaction with Defaults: Be aware that if arguments within a group have default values assigned, it may trigger validation errors regarding the group's requirements, as clap interprets the presence of default values as the argument being "used" [5][6]. By using.multiple(true) in conjunction with.required(true), you change the restriction from "exactly one" to "at least one," providing flexibility when multiple related flags should be accepted together [3][2].
Citations:
🏁 Script executed:
Repository: imsudiproy/uniproc
Length of output: 4339
Align the documented CSV header with the emitted schema. The README uses
system_network_received_bytesandsystem_network_transmitted_bytes, but the output fields arenetwork_received_bytesandnetwork_transmitted_bytes. Update the CSV example to match the generated header.🤖 Prompt for AI Agents