Watchdog-Integration gegen Produktivserver verifiziert und korrigiert
- 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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
3a82397651
commit
725746d204
@@ -15,8 +15,13 @@ binden zwei eigenständige Schwester-Projekte an:
|
|||||||
`Services/WatchdogHeartbeatService.cs` sendet alle *n* Sekunden einen
|
`Services/WatchdogHeartbeatService.cs` sendet alle *n* Sekunden einen
|
||||||
`POST /api/heartbeat` an den Watchdog. Bleiben die Heartbeats aus — weil die App
|
`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.
|
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=stopping` raus,
|
Beim regulären Schließen geht ein `POST /api/event` mit `kind=stopped_graceful`
|
||||||
damit ein geplantes Beenden nicht als Crash alarmiert wird.
|
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.
|
**Wichtig:** Ein Ausfall des Watchdogs darf Predictalytics nie beeinträchtigen.
|
||||||
Alle Aufrufe sind best effort; der erste Fehlschlag wird als Warnung geloggt,
|
Alle Aufrufe sind best effort; der erste Fehlschlag wird als Warnung geloggt,
|
||||||
@@ -29,7 +34,7 @@ Folgefehler nur noch auf Debug-Level (keine Log-Flut).
|
|||||||
| `Enabled` | `true` | Heartbeats an/aus |
|
| `Enabled` | `true` | Heartbeats an/aus |
|
||||||
| `Server URL` | `https://watchdog.mhdf.de` | Basis-URL |
|
| `Server URL` | `https://watchdog.mhdf.de` | Basis-URL |
|
||||||
| `API Key` | *(leer)* | `X-Watchdog-Key` — Shared Key **oder** Agent-Token. Ohne Key passiert nichts. |
|
| `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) |
|
| `Source` | `Predictalytics` | Monitor-Name im Dashboard (Auto-Registrierung beim ersten Beat) |
|
||||||
| `Instance` | `default` | falls mehrere Instanzen laufen |
|
| `Instance` | `default` | falls mehrere Instanzen laufen |
|
||||||
| `Interval (Sekunden)` | `60` | Sende-Takt; Alarm nach ca. `Intervall × 1,5 + 30 s` |
|
| `Interval (Sekunden)` | `60` | Sende-Takt; Alarm nach ca. `Intervall × 1,5 + 30 s` |
|
||||||
|
|
||||||
@@ -60,13 +65,16 @@ einen gefälschten Lizenzserver zu zeigen.
|
|||||||
- **Härtung:** `VerifyChecksum` (HMAC über State + Key + Hardware-ID) gegen Memory-Patches;
|
- **Härtung:** `VerifyChecksum` (HMAC über State + Key + Hardware-ID) gegen Memory-Patches;
|
||||||
Nonce-Reflexion und Signaturprüfung übernimmt das SDK
|
Nonce-Reflexion und Signaturprüfung übernimmt das SDK
|
||||||
|
|
||||||
### Einmalige Server-Schritte
|
### Status
|
||||||
|
|
||||||
1. Im Admin-Backend von `license.mhdf.de` das Produkt mit Slug **`predictalytics`** anlegen
|
Produkt `predictalytics` und Lizenzschlüssel sind angelegt; die Aktivierung wurde
|
||||||
(ohne den Eintrag liefert der Server `not_found`).
|
am 2026-07-30 gegen den Produktivserver verifiziert (`Valid`, gültig bis
|
||||||
2. Lizenzschlüssel ausstellen und beim ersten Start im Dialog eingeben.
|
2040-12-31, Checksum-Prüfung bestanden). Der einkompilierte Public Key passt zum
|
||||||
3. Prüfen, dass der einkompilierte Public Key in `LicenseGuard.PublicKeyBase64`
|
`signing.pub` des Servers — sonst käme `TamperSuspected` statt `Valid`.
|
||||||
dem `signing.pub` des Servers entspricht.
|
|
||||||
|
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
|
### Deaktivierung bei PC-Wechsel
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ public class AppSettings
|
|||||||
[Category("Watchdog")]
|
[Category("Watchdog")]
|
||||||
[DisplayName("Source")]
|
[DisplayName("Source")]
|
||||||
[Description("Eindeutiger Monitor-Name dieses Dienstes im Watchdog-Dashboard.")]
|
[Description("Eindeutiger Monitor-Name dieses Dienstes im Watchdog-Dashboard.")]
|
||||||
[DefaultValue("predictalytics")]
|
[DefaultValue("Predictalytics")]
|
||||||
public string WatchdogSource { get; set; } = "predictalytics";
|
public string WatchdogSource { get; set; } = "Predictalytics";
|
||||||
|
|
||||||
[Category("Watchdog")]
|
[Category("Watchdog")]
|
||||||
[DisplayName("Instance")]
|
[DisplayName("Instance")]
|
||||||
|
|||||||
@@ -49,7 +49,11 @@ public sealed class WatchdogHeartbeatService : IDisposable
|
|||||||
_baseUrl, _source, _intervalSeconds);
|
_baseUrl, _source, _intervalSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sends a lifecycle event (e.g. "stopping") so a planned shutdown is not alarmed as a crash.</summary>
|
/// <summary>
|
||||||
|
/// Reports a planned shutdown so it is not alarmed as a crash.
|
||||||
|
/// Must be "stopped_graceful": the server's event_log.kind ENUM has no "stopping"
|
||||||
|
/// value, and that variant fails the insert with HTTP 500 after the state update.
|
||||||
|
/// </summary>
|
||||||
public void NotifyStopping()
|
public void NotifyStopping()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -58,7 +62,7 @@ public sealed class WatchdogHeartbeatService : IDisposable
|
|||||||
{
|
{
|
||||||
source = _source,
|
source = _source,
|
||||||
instance = _instance,
|
instance = _instance,
|
||||||
kind = "stopping",
|
kind = "stopped_graceful",
|
||||||
severity = "info",
|
severity = "info",
|
||||||
message = "Predictalytics wird planmäßig beendet."
|
message = "Predictalytics wird planmäßig beendet."
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user