smartscan¶
A CLI tool that runs smartctl on all disks, extracts key SMART health metrics, and stores historical results in SQLite for tracking changes over time.
Highlights¶
- Collects SMART data via
smartctl --all --jsonfrom/dev/disk/by-id/ata-*and/dev/disk/by-id/nvme-*. - Displays results as Rich-styled tables with warnings for critical values.
- Sends notifications via Telegram, DingTalk, or Feishu when threshold alerts trigger.
- Stores historical data in SQLite and compacts redundant records automatically (
querysubcommand). - New:
prunesubcommand to clean up unchanged records;query --trendfor LLM-powered trend analysis. - Maps disk devices to their
/dev/disk/identifiers with a Rich tree view (lsblksubcommand). - Supports JSON lines output for scripting.
- Configurable via TOML config file with Pydantic validation.
- Built with
uv,ruff,ty,pytest, andzensical. - CLI uses
argparseandargcompletefor shell completion.
Prerequisites¶
Install smartmontools to provide the smartctl command:
# Debian/Ubuntu
apt install smartmontools
# RHEL/Fedora
dnf install smartmontools
# Arch
pacman -S smartmontools
Install dependencies¶
# install from PyPI
uv tool install smartscan
# install from GitHub
uv tool install git+https://github.com/ak1ra-lab/smartscan.git
Run the CLI¶
smartscan collect requires root to access disk devices via smartctl. Switch to a root shell first:
sudo -i
Once logged in as root, run commands normally:
smartscan collect
smartscan collect "WDC"
smartscan collect --verbose
smartscan collect --llm all # force LLM analysis on every disk
smartscan collect --llm summary # batch LLM analysis across all disks
smartscan collect --notify # always send notifications
smartscan collect --no-save # display only, skip database
smartscan query --since 2024-01-01
smartscan query --last-days 7 --verbose
smartscan query --no-compact # show all raw records (skip deduplication)
smartscan query --compact-window 15 # custom deduplication window (minutes)
smartscan query --trend # LLM trend analysis on compacted results
smartscan prune # remove unchanged records (30min window)
smartscan prune --dry-run # preview what would be deleted
smartscan prune --window 60 --force # 60min window, skip confirmation
smartscan --json collect
smartscan --json query --since 2024-01-01
smartscan lsblk maps block devices to their identifiers under /dev/disk/. It does not require root:
smartscan lsblk
smartscan lsblk "Samsung"
smartscan lsblk --source by-id
smartscan lsblk --source by-id --source by-diskseq
smartscan --exclude '^/dev/(loop|zd)\d+' lsblk
smartscan --json lsblk
Output example:
/dev/sda [WDC WD40EFRX-68N32N0, 3.6 TiB]
├── by-id
│ ├── /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0123456
│ └── /dev/disk/by-id/wwn-0x50014ee26b123456
├── by-path
│ └── /dev/disk/by-path/pci-0000:00:17.0-ata-1
└── by-diskseq
└── /dev/disk/by-diskseq/1
smartscan queryitself does not require root, but the defaultdb_pathis/var/lib/smartscan/smartscan.db— a system directory writable only by root. To share the database across users, set a customdb_pathin the config file pointing to a location readable by all users.
Configuration¶
smartscan reads an optional TOML config file at /etc/smartscan/smartscan.toml. All subcommands, thresholds, and LLM settings are configurable.
See Configuration Reference for the full config file with all defaults, and LLM Examples for provider-specific snippets (DeepSeek, Anthropic, Ollama).
To force LLM analysis on healthy disks (no threshold alerts), use:
sudo smartscan collect --llm all
Shell completion¶
smartscan uses argcomplete for tab completion.
To enable per-shell, add the following line to your ~/.bashrc (or equivalent shell config file):
eval "$(register-python-argcomplete smartscan)"
To enable system-wide completion for all argcomplete-based tools, run:
activate-global-python-argcomplete
See the argcomplete documentation for zsh, fish, and tcsh support.
Development¶
Clone the repository and install development dependencies:
git clone https://github.com/ak1ra-lab/smartscan.git
cd smartscan
uv sync --group dev
Common tasks are scripted as just recipes:
| Command | What it does |
|---|---|
just lint |
Lint and format source code plus tests (ruff check, ruff format) |
just typecheck |
Run static type checking (ty) over src/ |
just test |
Run the pytest suite |
just coverage |
Run tests with HTML coverage report |
just build |
Build the wheel and sdist |
just docs-build |
Build the static docs site with Zensical |
just docs-serve |
Preview docs locally on the configured dev address |
just all |
Run lint, typecheck, test, coverage, build, and docs-build in sequence |