Co-authored-by: Tom <165781231+GraegelTh@users.noreply.github.com> Reviewed-on: https://git.eckertplayground.de/taarly/PHP_AdminTool_Projekt/pulls/14
298 lines
8.9 KiB
Markdown
298 lines
8.9 KiB
Markdown
# CHANGELOG
|
||
|
||
## 2025-12-03 — SNMP Live-Dashboard (Architektur: Service + API)
|
||
|
||
### Übersicht
|
||
|
||
Implementierung eines **dualen SNMP-Status-Systems**:
|
||
1. **Server-seitig (Initial Load):** `DashboardController` → `SnmpServerStatusService`
|
||
2. **Client-seitig (Live-Updates):** Browser-JavaScript → API-Endpunkt (`snmp_status.php`)
|
||
|
||
Ergebnis: **Beste User Experience** (sofortige Daten beim Laden) + **Redundanz** (Live-Polling läuft weiter, auch wenn Service fehlt).
|
||
|
||
---
|
||
|
||
## Komponente 1: Service (`app/Services/Snmp/SnmpServerStatusService.php`) — modernisiert
|
||
|
||
### Was wurde geändert?
|
||
|
||
Die alte Version ist zu streng gewesen (wirft Exception wenn "Physical Memory" nicht exakt gefunden wird).
|
||
Neue Version hat **intelligente Fallback-Logik**:
|
||
|
||
**RAM-Erkennung (in dieser Reihenfolge):**
|
||
1. Heuristik: Suche nach "Physical Memory" (exakt)
|
||
2. Fallback 1: Suche nach "physical" ODER "memory" ODER "ram" (Case-insensitive)
|
||
3. Fallback 2: Nimm den **kleinsten Storage-Eintrag** (wahrscheinlich RAM)
|
||
4. Falls alles fehlschlägt: Exception → abgefangen im Controller → 0% angezeigt
|
||
|
||
**Disk-Erkennung (in dieser Reihenfolge):**
|
||
1. Heuristik: Suche nach "C:\\" (Windows, exakt)
|
||
2. Fallback 1: Suche nach "C:" ODER "root" ODER "/" (Case-insensitive)
|
||
3. Fallback 2: Nimm den **größten Storage-Eintrag > 1 GB** (wahrscheinlich Hauptlaufwerk)
|
||
4. Falls alles fehlschlägt: Exception → abgefangen im Controller → 0% angezeigt
|
||
|
||
### Featureset
|
||
|
||
- ✅ Robuste Fehlerbehandlung (aussagekräftige `RuntimeException` für Debugging)
|
||
- ✅ Intelligente Fallbacks bei unerwarteten OID-Beschreibungen
|
||
- ✅ Unterstützung Windows + Linux
|
||
- ✅ Prüfung auf SNMP-Erweiterung und Konfiguration
|
||
- ✅ Uptime in lesbares Format konvertieren (z. B. "1 Tage, 10:17:36")
|
||
- ✅ CPU-Durchschnitt über alle Kerne
|
||
|
||
---
|
||
|
||
## Komponente 2: Controller (`app/Controllers/DashboardController.php`) — neu strukturiert
|
||
|
||
### Was wurde geändert?
|
||
|
||
Der Controller hatte nur eine Zeile geändert; jetzt **fehlertolerante Abfrage**:
|
||
|
||
```php
|
||
try {
|
||
$serverStatus = $this->snmpService->getServerStatus();
|
||
} catch (\RuntimeException $e) {
|
||
error_log('SNMP-Fehler beim initialen Laden - ' . $e->getMessage());
|
||
// Fallback-Werte werden verwendet (siehe oben)
|
||
}
|
||
```
|
||
|
||
**Effekt:**
|
||
- Wenn Service fehlschlägt: Dashboard wird trotzdem geladen (mit 0% oder 'n/a')
|
||
- Fehler wird geloggt (PHP Error-Log)
|
||
- Live-Polling (API) läuft trotzdem weiter und kann Daten liefern
|
||
- Bessere User Experience statt "Error 500"
|
||
|
||
---
|
||
|
||
## Komponente 3: API (`public/api/snmp_status.php`)
|
||
|
||
Siehe vorherige CHANGELOG-Einträge. Wichtig:
|
||
- **Identische Fallback-Logik** wie der Service
|
||
- **Session-Validierung** (nur Admins)
|
||
- **Caching** (10 Sekunden)
|
||
- **Detailliertes Logging** in `public/logs/snmp_api.log`
|
||
|
||
---
|
||
|
||
## Komponente 4: View & JavaScript (`public/views/dashboard.php`)
|
||
|
||
Siehe vorherige CHANGELOG-Einträge.
|
||
|
||
---
|
||
|
||
## Architektur: Dual-Layer System
|
||
|
||
### Layer 1: Initial Load (Server-seitig)
|
||
|
||
```
|
||
Nutzer öffnet Dashboard
|
||
↓
|
||
DashboardController::show()
|
||
↓
|
||
SnmpServerStatusService::getServerStatus()
|
||
↓
|
||
SNMP-Abfrage (mit Fallbacks)
|
||
↓
|
||
Daten sofort in View angezeigt
|
||
↓
|
||
(Bei Fehler: Fallback-Werte wie 0%, 'n/a')
|
||
↓
|
||
Logging in PHP Error-Log
|
||
```
|
||
|
||
**Vorteile:**
|
||
- ✅ Daten sind **sofort** sichtbar (gute UX)
|
||
- ✅ Fallbacks verhindern "Error 500"
|
||
- ✅ Service wird nur 1x pro Seitenladung aufgerufen (sparsam)
|
||
|
||
---
|
||
|
||
### Layer 2: Live-Updates (Client-seitig)
|
||
|
||
```
|
||
Browser lädt Dashboard
|
||
↓
|
||
JavaScript addEventListener('DOMContentLoaded')
|
||
↓
|
||
Sofort erste Abfrage: fetch('api/snmp_status.php')
|
||
↓
|
||
Antwort: JSON mit aktuellen Daten
|
||
↓
|
||
updateUI() aktualisiert die Karten
|
||
↓
|
||
Alle 5 Sekunden wiederholt (setInterval)
|
||
↓
|
||
Logging in public/logs/snmp_api.log (Server-seitig)
|
||
```
|
||
|
||
**Vorteile:**
|
||
- ✅ **Live-Updates** ohne Seite zu reload-en
|
||
- ✅ **Session-Schutz** (nur Admins können Endpunkt aufrufen)
|
||
- ✅ **Caching** reduziert SNMP-Last (10s TTL)
|
||
- ✅ **Fallback-Logik** im API unabhängig vom Service
|
||
- ✅ **Redundanz:** Wenn Service fehlt, läuft API trotzdem
|
||
|
||
---
|
||
|
||
## Logging
|
||
|
||
### PHP Error-Log (Service-Fehler)
|
||
|
||
- **Ort:** Abhängig von PHP-Konfiguration (meist `/var/log/php-errors.log` oder Windows Event-Log)
|
||
- **Format:** Standard PHP Error-Log
|
||
- **Inhalt:** SNMP-Fehler beim initialen Laden (z. B. "SNMP-Konfiguration ist unvollständig")
|
||
- **Trigger:** Nur wenn Service-Abfrage fehlschlägt
|
||
|
||
**Beispiel:**
|
||
```
|
||
[03-Dec-2025 12:05:00 UTC] DashboardController: SNMP-Fehler beim initialen Laden - SNMP-Konfiguration ist unvollständig (host fehlt).
|
||
```
|
||
|
||
### SNMP API Log (`public/logs/snmp_api.log`)
|
||
|
||
- **Ort:** `public/logs/snmp_api.log` (wird automatisch angelegt)
|
||
- **Format:** `[YYYY-MM-DD HH:MM:SS] Nachricht`
|
||
- **Inhalt:**
|
||
- Cache-Hits/Misses
|
||
- SNMP-Konfiguration
|
||
- Alle Storage-Einträge
|
||
- Erkannte Disk/RAM mit Prozentsätzen
|
||
- Fallback-Aktionen
|
||
- Finale Werte
|
||
- Fehler
|
||
|
||
**Beispiel:**
|
||
```
|
||
[2025-12-03 12:05:00] --- SNMP-Abfrage gestartet ---
|
||
[2025-12-03 12:05:00] SNMP-Host: 127.0.0.1, Community: public_ro, Timeout: 2s
|
||
[2025-12-03 12:05:00] Uptime OID: 1.3.6.1.2.1.1.3.0, Raw: "Timeticks: (1234567) 14 days, 6:14:27.67"
|
||
[2025-12-03 12:05:00] Storage[1]: Desc='Physical Memory', Size=16777216, Used=8388608, Units=1024
|
||
[2025-12-03 12:05:00] Speicher erkannt (Index 1): Physical Memory → 50.00%
|
||
[2025-12-03 12:05:00] Storage[2]: Desc='C:\\ ', Size=536870912, Used=268435456, Units=512
|
||
[2025-12-03 12:05:00] Datenträger erkannt (Index 2): C:\\ → 50.00%
|
||
[2025-12-03 12:05:00] RESULT: CPU=25, Mem=50.00, Disk=50.00
|
||
[2025-12-03 12:05:00] Cache geschrieben, TTL: 10s
|
||
```
|
||
|
||
---
|
||
|
||
## Fehlerszenarien & Behavior
|
||
|
||
### Szenario 1: SNMP läuft, alles OK
|
||
```
|
||
Service: ✅ Daten sofort angezeigt
|
||
API: ✅ Live-Updates alle 5s
|
||
Logs: ✅ Beide Logs ganz normal
|
||
```
|
||
|
||
### Szenario 2: SNMP-Erweiterung fehlt
|
||
```
|
||
Service: ❌ Exception → abgefangen → 0%, 'n/a' angezeigt
|
||
API: ❌ Exception → abgefangen → {"error": "snmp_extension_missing"}
|
||
Logs: ⚠️ Beide Logs zeigen Fehler
|
||
User-View: "Metriken werden angezeigt (0%), aber nicht aktualisiert"
|
||
Aktion: Admin sieht Fehler im Log und installiert SNMP
|
||
```
|
||
|
||
### Szenario 3: SNMP antwortet, aber Beschreibungen sind unbekannt
|
||
```
|
||
Service: ✅ Fallback-Logik findet RAM/Disk trotzdem
|
||
API: ✅ Fallback-Logik findet RAM/Disk trotzdem
|
||
Logs: ℹ️ `Fallback RAM gefunden` / `Fallback Disk gefunden`
|
||
User-View: ✅ Daten werden angezeigt
|
||
```
|
||
|
||
### Szenario 4: Service fehlt, API läuft
|
||
```
|
||
Service: ❌ Exception beim Laden
|
||
API: ✅ Live-Updates funktionieren normal
|
||
User-View: "Beim Laden: 0%, nach 5s: aktuelle Werte"
|
||
Gut genug!
|
||
```
|
||
|
||
---
|
||
|
||
## Testing-Anleitung
|
||
|
||
### 1. Initialer Load testen
|
||
```bash
|
||
# Browser öffnen, als Admin einloggen
|
||
# Dashboard öffnen
|
||
# → Sollten Werte sichtbar sein (entweder echte oder 0%)
|
||
```
|
||
|
||
### 2. Service-Fehler simulieren
|
||
```php
|
||
// In DashboardController.php: Service-Aufruf kommentieren
|
||
// $serverStatus = [... Fallback-Werte ...];
|
||
// → Dashboard sollte trotzdem laden (mit 0%)
|
||
```
|
||
|
||
### 3. API testen
|
||
```bash
|
||
# Browser DevTools → Network → api/snmp_status.php
|
||
# → Sollte JSON zurückgeben
|
||
# Bei 401 → Session fehlt (erwartet wenn nicht angemeldet)
|
||
# Sollte aber funktionieren wenn angemeldet
|
||
```
|
||
|
||
### 4. Logs prüfen
|
||
```bash
|
||
# PHP Error-Log
|
||
error_log() Output ansehen
|
||
|
||
# SNMP API Log
|
||
cat public/logs/snmp_api.log
|
||
# Sollte Einträge zeigen (mit Timestamps)
|
||
```
|
||
|
||
### 5. Cache prüfen
|
||
```bash
|
||
# Temp-Datei prüfen
|
||
# Windows: %TEMP%\snmp_status_cache.json
|
||
# Linux: /tmp/snmp_status_cache.json
|
||
# → Sollte JSON enthalten
|
||
```
|
||
|
||
---
|
||
|
||
## Known Issues & Limitations
|
||
|
||
1. **Disk/RAM-Heuristik:** Bei sehr ungewöhnlichen Storage-Labels können Fallbacks greifen, die nicht ideal sind
|
||
- **Lösung:** Log prüfen (`Storage[X]:` Einträge) und ggf. Heuristiken anpassen
|
||
|
||
2. **Cache-Speicher:** Erfordert Schreibzugriff auf `sys_get_temp_dir()`
|
||
- **Lösung:** Falls nicht verfügbar → Cache-Code entfernen oder APCu/Redis nutzen
|
||
|
||
3. **OS-Feld:** Hardcoded auf "Windows Server" (TODO: Dynamisch per OID 1.3.6.1.2.1.1.1.0)
|
||
|
||
---
|
||
|
||
## Performance
|
||
|
||
- **Service-Abfrage:** 1x pro Seitenladung (~100-500ms je nach SNMP-Timeout)
|
||
- **API-Abfrage:** Alle 5s, aber gecacht für 10s → effektiv alle 10s eine echte SNMP-Abfrage
|
||
- **JavaScript Polling:** 5s Intervall (Browser-seitig, keine Last auf Server)
|
||
- **Gesamt:** Sehr effizient, auch bei vielen gleichzeitigen Nutzern
|
||
|
||
---
|
||
|
||
## Summary für Kollegen
|
||
|
||
✅ **Live-Dashboard mit zwei Ebenen:**
|
||
1. Initial Load via Service (sofortige Daten)
|
||
2. Live-Polling via API (kontinuierliche Updates)
|
||
|
||
✅ **Robuste Fallback-Logik** für RAM und Disk (findet die Werte auch bei unbekannten Labels)
|
||
|
||
✅ **Dual Logging:**
|
||
- PHP Error-Log für Service-Fehler
|
||
- `public/logs/snmp_api.log` für API-Aktivitäten
|
||
|
||
✅ **Session-Geschützt:** Nur Admins können Status abrufen
|
||
|
||
✅ **Gecacht:** 10 Sekunden TTL reduziert SNMP-Load
|
||
|
||
✅ **Error-tolerant:** Dashboard funktioniert auch wenn SNMP fehlt (zeigt 0%, wartet auf Live-Updates)
|