OptiSys is a system profiler and diagnostics tool for Linux. It collects detailed information about hardware, kernel, drivers, services, packages, logs, security posture, and thermal sensor data, and presents it in a structured terminal output. Results can be exported to JSON or YAML for use with external tools or AI-assisted analysis.
- Hardware profiling — CPU, GPU, memory, disks, and network interfaces
- Temperature and sensor monitoring — CPU, GPU, NVMe, thermal zones, fans, and voltage readings with sysfs-first collection
- Kernel information — OS release, kernel version, and system parameters
- Driver analysis — loaded kernel modules and driver status
- Service monitoring — systemd unit health and status
- Package inventory — installed packages from dpkg, snap, and flatpak
- Log analysis — recent journal and kernel log entries with warning and error detection
- Security auditing — firewall status, listening ports, AppArmor/SELinux, fail2ban, sudoers permissions, and key hardening settings
- Plugin system — extend OptiSys with custom collector plugins, no fork required
- Multiple export formats — JSON and YAML output
- Caching — last scan result cached locally for fast re-export
- Local history database — completed scans can also be appended to a local SQLite database for future trend analysis
- Standalone binary — single executable with no runtime dependencies
Download the latest binary from the Releases page:
wget https://github.com/nordicnode/optisys/releases/latest/download/optisys-linux-x86_64
chmod +x optisys-linux-x86_64
sudo mv optisys-linux-x86_64 /usr/local/bin/optisysgit clone https://github.com/nordicnode/optisys.git
cd optisys
pip install -e .pip install optisysoptisys scanoptisys scan -c hardware -c sensors -c kerneloptisys scan --output report.json
optisys scan --output report.yamloptisys scan --no-detailoptisys export --output report.json
optisys export --input previous-scan.json --output report.yamlBy default, completed scans are also appended to a local SQLite history database at ~/.local/share/optisys/history.db.
optisys scanTo disable history recording for a one-off run:
optisys scan --no-record-historyTo store the history database somewhere else, set OPTISYS_HISTORY_DB before running a scan:
OPTISYS_HISTORY_DB=/path/to/optisys-history.db optisys scanIf you already have timestamped JSON reports in ~/.cache/optisys/, you can import them into the SQLite history database:
optisys history backfillThis imports cached historical reports, skips ones that are already present in the database, and prints a summary of imported, skipped, and failed files.
To inspect the most recent scans stored in SQLite:
optisys history listTo limit how many entries are shown:
optisys history list --limit 5This prints recent scan IDs, timestamps, hostnames, tool versions, durations, and recorded categories.
| Category | Description |
|---|---|
hardware |
CPU, GPU, memory, disks, and network interfaces |
sensors |
CPU, GPU, NVMe, thermal zone, fan, and voltage sensor telemetry |
kernel |
OS release, kernel version, and system parameters |
drivers |
Loaded kernel modules and driver status |
services |
Systemd unit health and status |
packages |
Installed packages from all package managers |
logs |
Recent system logs with warning and error detection |
security |
Firewall posture, listening ports, MAC frameworks, fail2ban, sudoers permissions, and kernel hardening settings |
| (plugins) | Additional categories provided by installed plugins |
| Flag | Default | Description |
|---|---|---|
-c, --category |
all | Scan one or more specific categories (repeatable) |
-o, --output |
— | Write report to a file |
-f, --format |
auto | Output format: json or yaml (inferred from extension) |
--log-limit |
200 | Maximum number of log entries to collect |
--detail / --no-detail |
detail | Show per-category detail below the summary table |
--full / --no-full |
no-full | Include large data sets normally omitted for brevity |
--record-history / --no-record-history |
record-history | Append each completed scan to the local SQLite history database |
OptiSys can be extended with custom collector plugins. Plugins are discovered automatically at startup and integrate fully with the scan pipeline, summary table, detail rendering, and JSON/YAML export.
Place a .py file in ~/.config/optisys/plugins/. Any class in that file that subclasses BaseCollector and defines a key and label is loaded automatically.
optisys plugins dir --create# ~/.config/optisys/plugins/my_collector.py
from optisys.collectors.base import BaseCollector
from optisys.models import CategoryResult
class MyCollector(BaseCollector):
key = "my-check"
label = "My Check"
plugin_version = "1.0.0"
plugin_author = "Your Name"
plugin_description = "Does something useful."
def _collect(self, result: CategoryResult, log_limit: int, full: bool) -> None:
result.data["message"] = "Hello from my plugin!"
result.summary = {"status": "ok"}optisys plugins list
optisys scan -c my-checkFor distributable plugins, declare an entry point in your package:
[project.entry-points."optisys.collectors"]
my-check = "my_package.collectors:MyCollector"pip install my-optisys-plugin
optisys plugins list| Command | Description |
|---|---|
optisys plugins list |
List all loaded plugin collectors |
optisys plugins list --verbose |
Include source path and class name |
optisys plugins inspect <key> |
Show detailed metadata for one loaded plugin collector |
optisys plugins dir |
Show the plugin directory path and usage guide |
optisys plugins dir --create |
Create the plugin directory if it does not exist |
See PLUGINS.md for the full developer guide, BaseCollector API reference, and a fully annotated example plugin.
╭──────────────────────────── OptiSys System Profile ─────────────────────────────╮
│ │
│ Host: pop-os │
│ OS: Pop!_OS 24.04 LTS │
│ Kern: 6.18.7-76061807-generic │
│ │
╰──────────────────────────────────────────────────────────────────────────────────╯
Scan Results
╭────────┬──────────────┬────────────┬──────────────────────────────────────────────╮
│ Status │ Category │ Duration │ Key Info │
├────────┼──────────────┼────────────┼──────────────────────────────────────────────┤
│ ✓ │ hardware │ 49ms │ Intel Core i5-9400 · 15.5GB RAM · 1 GPU │
│ ✓ │ sensors │ 12ms │ CPU: 52°C · GPU: 61°C · NVMe: 38°C · fans: 1200rpm │
│ ✓ │ kernel │ 4ms │ Pop!_OS 24.04 LTS · kernel 6.18.7 · up 2.4h │
│ ✓ │ drivers │ 5662ms │ 171 modules · GPU: nvidia · DKMS: 8 │
│ ✓ │ services │ 564ms │ 163 units · active: 68 · failed: 1 │
│ ✓ │ packages │ 264ms │ dpkg: 2268 · snap: 0 · flatpak: 23 │
│ ✓ │ logs │ 46ms │ recent: 200 · warnings: 186 · kernel: 0 │
│ ✓ │ security │ 31ms │ ufw: active · 3 open ports · AppArmor: enforcing · fail2ban: 2 jails │
│ ✓ │ uptime │ 0ms │ 2 hours, 52 minutes · load 0.43/0.86/0.76 │
╰────────┴──────────────┴────────────┴──────────────────────────────────────────────╯
Scan completed in 6595ms Cached to /home/user/.cache/optisys/latest.json Recorded in history DB /home/user/.local/share/optisys/history.db (scan #42)
- Python 3.10 or later (source installation only)
- Linux — tested on Ubuntu, Debian, Pop!_OS, and derivatives
- Root privileges recommended for full system access
| Category | Commands |
|---|---|
| Hardware | lscpu, lsblk, ip, nvidia-smi |
| Sensors | sensors, nvidia-smi (direct sysfs reads are preferred and work without lm-sensors) |
| Kernel | uname, sysctl |
| Drivers | lspci, lsmod |
| Services | systemctl |
| Packages | dpkg, snap, flatpak |
| Logs | journalctl, dmesg |
| Security | ufw, nft, iptables, ss, aa-status, fail2ban-client |
git clone https://github.com/nordicnode/optisys.git
cd optisys
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"pytest tests/pip install pyinstaller
pyinstaller --name optisys --onefile --collect-all optisys optisys/__main__.pyThe binary will be written to dist/optisys.
- No outbound network connections — all data is read locally
- External commands run via
subprocesswith a list argument; no shell injection surface - Read-only system access throughout
- No telemetry or data collection
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'Add my feature' - Push to the branch:
git push origin feature/my-feature - Open a pull request
MIT — see LICENSE for details.