- Shutdown-Event sendet stopped_graceful statt stopping: der Server kennt "stopping" im Router, aber event_log.kind ist ein ENUM ohne diesen Wert. Folge war HTTP 500 nach dem Zustandswechsel, das Event fehlte in der Historie. - Default-Source auf "Predictalytics" korrigiert (Schreibweise des bereits angelegten Monitors auf dem Server). Heartbeat, Metrics-Payload, Lizenzvalidierung und der Startpfad ueber den Cache sind end-to-end gegen die Produktivserver getestet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
83 lines
3.9 KiB
Markdown
83 lines
3.9 KiB
Markdown
# Betrieb: Watchdog-Überwachung & LicenseLabrador-Lizenzierung
|
||
|
||
Beide Integrationen sitzen im `Predictalytics.WinFormsHost` (dem Produktiv-Host) und
|
||
binden zwei eigenständige Schwester-Projekte an:
|
||
|
||
| Projekt | Pfad | Rolle |
|
||
|---|---|---|
|
||
| Watchdog | `J:\Softwareprojekte\WatchDog` | PHP/MySQL-Server auf `watchdog.mhdf.de`, empfängt Heartbeats |
|
||
| LicenseLabrador | `J:\Softwareprojekte\LicenseLabrador` | PHP-Lizenzserver auf `license.mhdf.de` + C#-SDK |
|
||
|
||
---
|
||
|
||
## 1. Watchdog (Dead-Man's-Switch)
|
||
|
||
`Services/WatchdogHeartbeatService.cs` sendet alle *n* Sekunden einen
|
||
`POST /api/heartbeat` an den Watchdog. Bleiben die Heartbeats aus — weil die App
|
||
abgestürzt ist oder die ganze Maschine weg ist — schlägt der Watchdog Alarm.
|
||
Beim regulären Schließen geht ein `POST /api/event` mit `kind=stopped_graceful`
|
||
raus, damit ein geplantes Beenden nicht als Crash alarmiert wird.
|
||
|
||
> **Nicht auf `kind=stopping` ändern.** Der Watchdog akzeptiert den Wert im
|
||
> Router, aber `event_log.kind` ist ein ENUM ohne `stopping`. Der Server setzt
|
||
> dann zwar noch den Zustand auf `stopped`, scheitert aber am Insert und liefert
|
||
> HTTP 500 — das Event fehlt in der Historie. Verifiziert am 2026-07-30.
|
||
|
||
**Wichtig:** Ein Ausfall des Watchdogs darf Predictalytics nie beeinträchtigen.
|
||
Alle Aufrufe sind best effort; der erste Fehlschlag wird als Warnung geloggt,
|
||
Folgefehler nur noch auf Debug-Level (keine Log-Flut).
|
||
|
||
### Konfiguration (PropertyGrid im Host, Kategorie „Watchdog")
|
||
|
||
| Feld | Default | Bedeutung |
|
||
|---|---|---|
|
||
| `Enabled` | `true` | Heartbeats an/aus |
|
||
| `Server URL` | `https://watchdog.mhdf.de` | Basis-URL |
|
||
| `API Key` | *(leer)* | `X-Watchdog-Key` — Shared Key **oder** Agent-Token. Ohne Key passiert nichts. |
|
||
| `Source` | `Predictalytics` | Monitor-Name im Dashboard (Auto-Registrierung beim ersten Beat) |
|
||
| `Instance` | `default` | falls mehrere Instanzen laufen |
|
||
| `Interval (Sekunden)` | `60` | Sende-Takt; Alarm nach ca. `Intervall × 1,5 + 30 s` |
|
||
|
||
Der Key landet in der `settings.json` neben der Exe (nicht im Git).
|
||
|
||
### PolyTrader-Maschine mit überwachen
|
||
|
||
Der Heartbeat aus Predictalytics deckt nur *diesen* Prozess ab. Damit auch die
|
||
Maschine überwacht wird, auf der PolyTrader läuft, gehört dort zusätzlich der
|
||
OS-Agent hin: `WatchDog\agents\windows\watchdog-agent.ps1` als Scheduled Task
|
||
(inkl. Shutdown-Hook), bzw. `agents/linux/watchdog-agent.sh` per systemd-Timer.
|
||
|
||
---
|
||
|
||
## 2. LicenseLabrador (Kopierschutz)
|
||
|
||
`Services/LicenseGuard.cs` prüft beim Start, ob eine nutzbare Lizenz vorliegt
|
||
(`Program.Main` bricht sonst ab, bevor die MainForm überhaupt entsteht).
|
||
Ohne gültige Lizenz erscheint `Services/LicenseDialog.cs` zur Key-Eingabe.
|
||
|
||
Produkt-Slug, Endpoint und der Ed25519-Public-Key sind **bewusst einkompiliert**
|
||
und nicht konfigurierbar — ein einstellbarer Endpoint würde erlauben, die App auf
|
||
einen gefälschten Lizenzserver zu zeigen.
|
||
|
||
- **Produkt-Slug:** `predictalytics`
|
||
- **Offline-Gnadenfrist:** 168 h (7 Tage) — danach ist Serverkontakt nötig
|
||
- **Revalidierung zur Laufzeit:** alle 12 h; bei Widerruf/Ablauf beendet sich die App
|
||
- **Härtung:** `VerifyChecksum` (HMAC über State + Key + Hardware-ID) gegen Memory-Patches;
|
||
Nonce-Reflexion und Signaturprüfung übernimmt das SDK
|
||
|
||
### Status
|
||
|
||
Produkt `predictalytics` und Lizenzschlüssel sind angelegt; die Aktivierung wurde
|
||
am 2026-07-30 gegen den Produktivserver verifiziert (`Valid`, gültig bis
|
||
2040-12-31, Checksum-Prüfung bestanden). Der einkompilierte Public Key passt zum
|
||
`signing.pub` des Servers — sonst käme `TamperSuspected` statt `Valid`.
|
||
|
||
Die Aktivierung ist an die Hardware-ID der jeweiligen Maschine gebunden. Auf
|
||
einem neuen Rechner erscheint einmalig der Dialog; der Cache liegt danach unter
|
||
`%AppData%\predictalytics\license`.
|
||
|
||
### Deaktivierung bei PC-Wechsel
|
||
|
||
`LicenseClient.DeactivateAsync()` gibt die Aktivierung wieder frei. Aktuell nicht
|
||
in der UI verdrahtet — bei Bedarf als Menüpunkt ergänzen.
|