Initial commit: Fenris NVMe wear monitor with rolling-24h dashboard
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user