Files
archivmail/features/PROJ-17-system-dashboard.md
T
sysops d360c9a5ba feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen
- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg)
- Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist
- Feature-Status auf In Review gesetzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 11:43:19 +01:00

87 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROJ-17: Admin Dashboard Systemauslastung & Archiv-Übersicht
## Status: In Review
**Created:** 2026-03-14
**Last Updated:** 2026-03-14
## Dependencies
- Requires: PROJ-1 (Authentifizierung) nur Admins sehen das Dashboard
- Requires: PROJ-5 (Speicherung) erste/letzte Mail aus dem Archiv
## User Stories
- Als Admin möchte ich die aktuelle CPU-Auslastung sehen, damit ich Engpässe erkennen kann.
- Als Admin möchte ich die RAM-Auslastung (gesamt / verwendet / frei) sehen.
- Als Admin möchte ich alle eingebundenen Festplatten/Partitionen mit Füllstand sehen (Balken).
- Als Admin möchte ich die älteste und neueste archivierte Mail sehen (Datum, Von, Betreff), damit ich den Archivierungszeitraum auf einen Blick erkenne.
## Acceptance Criteria
- [x] CPU: Load Average (1min / 5min / 15min) aus `/proc/loadavg`
- [x] RAM: MemTotal, MemUsed, MemAvailable aus `/proc/meminfo`; Prozentbalken
- [x] Disk: alle physischen Partitionen (keine tmpfs/proc/sysfs/devtmpfs/overlay) via `syscall.Statfs`; je Partition: Mountpoint, Gesamt, Belegt, Frei, Prozent
- [x] Erste Mail im Archiv: Datum, Von, Betreff (älteste Datei im Store)
- [x] Letzte Mail im Archiv: Datum, Von, Betreff (neueste Datei im Store)
- [x] Endpoint: `GET /api/admin/system/stats` (Admin-only)
- [x] Storage-Erweiterung: `store.FirstAndLastMail()` liefert Metadaten der ältesten und neuesten Mail
## API Response Schema
```json
{
"cpu": {
"load1": 0.42,
"load5": 0.38,
"load15": 0.31,
"num_cpu": 4
},
"ram": {
"total_bytes": 8388608000,
"used_bytes": 3221225472,
"free_bytes": 5167382528,
"used_pct": 38.4
},
"disks": [
{
"mount": "/",
"total_bytes": 53687091200,
"used_bytes": 12884901888,
"free_bytes": 40802189312,
"used_pct": 24.0,
"fstype": "ext4"
}
],
"archive": {
"first_mail": { "id": "abc123", "date": "2024-01-15T08:00:00Z", "from": "...", "subject": "..." },
"last_mail": { "id": "def456", "date": "2026-03-14T10:08:00Z", "from": "...", "subject": "..." }
}
}
```
## Technical Design
### Backend (`internal/api/server.go`)
- Neuer Handler `handleSystemStats`
- CPU: `/proc/loadavg` parsen → load1, load5, load15 + `runtime.NumCPU()`
- RAM: `/proc/meminfo` parsen → MemTotal, MemFree, MemAvailable, Buffers, Cached
- `used = total - available`
- Disks: `/proc/mounts` lesen, für jeden Eintrag `syscall.Statfs()` aufrufen
- Ausschließen: fstype in {tmpfs, proc, sysfs, devtmpfs, cgroup, cgroup2, overlay, squashfs, debugfs, tracefs, securityfs, pstore, efivarfs, bpf, hugetlbfs, mqueue, ramfs}
- Erste/letzte Mail: `store.FirstAndLastMail()` → walk store dir, min/max ModTime
### Storage (`internal/storage/storage.go`)
- Neue Methode `FirstAndLastMail() (*MailRef, *MailRef, error)`
- `MailRef{ID, ModTime}` → ID wird an `handleSystemStats` übergeben, der dann via `mailparser.Parse()` From+Subject+Date extrahiert
### Frontend (`src/app/admin/page.tsx`)
- Neue Kacheln im Dashboard-Tab:
- **CPU-Auslastung**: Load Average mit `num_cpu` Kontext
- **Arbeitsspeicher**: Fortschrittsbalken (used/total), Zahlen darunter
- **Festplatten**: eine Karte pro Partition mit Balken + Zahlen
- **Archivzeitraum**: erste und letzte Mail als kompakte Zeilen (Datum · Von · Betreff)
## Implementation Notes
- **Backend:** `handleSystemStats` in `internal/api/server.go` — CPU via `/proc/loadavg`, RAM via `/proc/meminfo`, alle Disks via `/proc/mounts` + `syscall.Statfs`, Archiv-Zeitspanne via `store.FirstAndLastMail()`
- **Storage:** `FirstAndLastMail()` + `MailRef` in `internal/storage/storage.go` — walkt Store-Verzeichnis, liefert älteste/neueste Mail per ModTime
- **Route:** `GET /api/admin/system/stats` (Admin-only, Token-Auth)
- **Frontend:** Dashboard-Tab in `src/app/admin/page.tsx` mit CPU, RAM, Disk-Partitionen und Archivzeitraum; Auto-Refresh alle 30 Sekunden
- **Bereit für Test auf** `root@192.168.1.131`