# Fenris — NVMe Wear Monitor & Live Dashboard Created by Bongbetic. Periodically reads your NVMe drive's SMART health data, logs it over time, and serves a self-contained HTML dashboard estimating SSD lifespan from your actual daily usage trend. ## Requirements - **Python 3.7+** - **smartmontools** (`smartctl`) installed - Root access to read NVMe SMART logs ### Setting up passwordless smartctl Fenris runs `sudo -n smartctl ...` (no-prompt sudo). Either run with sudo or allow passwordless access: ```bash sudo visudo # Add this line (replace youruser with your username): youruser ALL=(root) NOPASSWD: /usr/sbin/smartctl ``` ## Quick Start ### Interactive Menu ```bash ./fenris.sh ``` ### CLI ```bash # Start daemon + dashboard in background python3 fenris.py start # Check status and latest wear stats python3 fenris.py status # Take one sample now python3 fenris.py sample # Stop the daemon python3 fenris.py stop ``` Dashboard available at: `http://localhost:8420` ## CLI Reference ### fenris.py start Start monitoring in background (daemon + dashboard). ```bash python3 fenris.py start [OPTIONS] Options: --device PATH NVMe device (default: auto-detect, e.g. /dev/nvme0) --interval SEC Seconds between samples (default: 300) --port PORT Dashboard HTTP port (default: 8420) ``` ### fenris.py stop Stop background monitoring and clean up PID file. ### fenris.py status Show daemon status and latest wear statistics. ### fenris.py sample Take one sample immediately and print it. ```bash python3 fenris.py sample [--device /dev/nvme0] ``` ### fenris.py run Run in foreground (used internally by `start`). Not intended for direct use. ## Interactive Menu Run `./fenris.sh` for a guided interface: ``` 1) Start monitoring (background daemon + dashboard) 2) Stop monitoring 3) Status / current wear stats 4) Take one sample right now 5) Open dashboard URL --- h) Help / how this works q) Exit ``` ## Data Collected | Field | Description | |-------|-------------| | `percentage_used` | SSD's own wear indicator (0-100%) | | `bytes_written` / `bytes_read` | Total data written/read | | `available_spare` | Remaining spare capacity (%) | | `media_errors` | Number of uncorrectable errors | | `power_on_hours` | Total power-on hours | | `temperature_c` | Current temperature | | `critical_warning` | NVMe critical warning flags | ## Dashboard Features - Real-time wear level + projected life remaining in **hours / days / years** from the actual **rolling-24h write rate** and implied TBW endurance - Exact **GB written in the last 24 hours** + GB/h and GB/day rate (updates every poll interval) - Wear-over-time chart + **trailing-24h per-hour write bars** - Dense layout with sticky header, ETag-cached polling synced to the daemon interval, countdown and live badge, stale/preliminary banners - API: `GET /api/data`, `/api/hourly`, `/api/summary`, `/api/config`, `/api/status` ## File Structure ``` fenris/ ├── fenris.py # Main Python script ├── fenris.sh # Interactive menu wrapper ├── README.md └── data/ ├── history.jsonl # Raw sample log (JSONL) ├── hourly.jsonl # Per-hour aggregates (rebuilt from history on restart) ├── fenris.pid # Daemon PID file └── fenris.log # Daemon log output ``` ## Troubleshooting **"smartctl not found"** ```bash sudo apt install smartmontools # Debian/Ubuntu sudo pacman -S smartmontools # Arch ``` **"needs root" / permission denied** Set up passwordless sudo (see Requirements) or run with sudo. **Dashboard shows "stale"** Daemon not running. Check with `python3 fenris.py status` and restart if needed.