Watchdog Monitoring¶
Datei:
watchdog/run.ts(175 Zeilen) Schedule: Alle 5 Minuten via Cron Alerting: Telegram-Bot
Übersicht¶
Der Watchdog prüft die Systemgesundheit in drei Kategorien:
Watchdog (alle 5 Min)
├── On-Chain Checks
│ ├── C1: Settlement-Status
│ ├── C4: Relayer-ETH-Balance
│ ├── C5: VRF-Seed-Status
│ └── S2: RPC-Erreichbarkeit
│
├── Database Checks
│ ├── D1: Stuck Buy-Intents
│ ├── D4: Settlement-Pipeline
│ ├── D5: DB-Connection
│ └── D6: chain_stats Frische
│
└── Service Checks
└── S1: App-Erreichbarkeit
Check-Details¶
On-Chain Checks¶
Datei:
watchdog/checks/onchain.ts(188 Zeilen)
C1: Settlement-Status¶
// Prüft ob die gestrige Ziehung settled wurde
const lastSettled = await settlement.lastSettledDay();
const expectedDay = currentDayId - 1;
if (lastSettled < expectedDay) {
return { level: "CRITICAL", message: `Settlement fehlt: erwartet ${expectedDay}, letzter ${lastSettled}` };
}
Grace Period: Bis 00:20 UTC werden keine Settlement-Alarme ausgelöst (Settlement läuft noch).
C4: Relayer-ETH-Balance¶
const balance = await provider.getBalance(RELAYER_ADDRESS);
const ethBalance = parseFloat(formatEther(balance));
if (ethBalance < 0.01) return { level: "CRITICAL", message: `Relayer ETH: ${ethBalance}` };
if (ethBalance < 0.05) return { level: "HIGH", message: `Relayer ETH niedrig: ${ethBalance}` };
| Schwelle | Level | Aktion |
|---|---|---|
| < 0.01 ETH | CRITICAL | Sofort ETH nachfüllen |
| < 0.05 ETH | HIGH | ETH bald nachfüllen |
C5: VRF-Seed¶
const vrfSeed = await gameManager.vrfSeed();
if (vrfSeed === 0n) {
return { level: "CRITICAL", message: "VRF Seed ist 0 - keine Tickets möglich!" };
}
S2: RPC-Erreichbarkeit¶
try {
await provider.getBlockNumber();
return { level: "OK" };
} catch (e) {
return { level: "CRITICAL", message: `RPC nicht erreichbar: ${e.message}` };
}
Database Checks¶
Datei:
watchdog/checks/database.ts(177 Zeilen)
D1: Stuck Buy-Intents¶
SELECT COUNT(*) FROM buy_intents
WHERE status IN ('SIGNED', 'EXECUTING')
AND created_at < now() - interval '30 minutes'
| Anzahl | Level |
|---|---|
| 0 | OK |
| 1-5 | MEDIUM |
| > 5 | HIGH |
D4: Settlement-Pipeline¶
| Status | Level |
|---|---|
| DONE | OK |
| RUNNING | INFO (Grace Period) |
| FAILED | CRITICAL |
| Nicht vorhanden | HIGH |
D5: DB-Connection¶
Impliziter Health-Check: Wenn die Query ausführbar ist, ist die DB erreichbar.
D6: chain_stats Frische¶
| Alter | Level |
|---|---|
| < 60 Min | OK |
| 60-120 Min | MEDIUM |
| > 120 Min | HIGH |
Service Checks¶
Datei:
watchdog/checks/service.ts(45 Zeilen)
S1: App-Erreichbarkeit¶
const response = await fetch(`${APP_URL}/api/global-stats`);
if (!response.ok) {
return { level: "HIGH", message: `App nicht erreichbar: HTTP ${response.status}` };
}
Alerting¶
Telegram-Alerts¶
Datei:
watchdog/alerting/telegram.ts(41 Zeilen)
Cooldown-System¶
Verhindert Alert-Spam bei anhaltenden Problemen:
| Level | Cooldown |
|---|---|
| CRITICAL | 5 Minuten |
| HIGH | 30 Minuten |
| MEDIUM | 120 Minuten |
Auto-Resolve¶
Wenn ein Check nach einem Alert wieder OK ist, wird der Alert automatisch aufgelöst:
// watchdog/run.ts:100-115
if (previousAlert && currentResult.level === "OK") {
await pg.query(
`UPDATE watchdog_alerts SET resolved_at = NOW() WHERE id = $1`,
[previousAlert.id]
);
}
Datenbank-Tracking¶
watchdog_runs¶
watchdog_runs (
id SERIAL PRIMARY KEY,
started_at TIMESTAMP,
finished_at TIMESTAMP,
checks_total INT,
checks_ok INT,
checks_warn INT,
checks_fail INT,
duration_ms INT
)
watchdog_alerts¶
watchdog_alerts (
id SERIAL PRIMARY KEY,
run_id INT REFERENCES watchdog_runs(id),
check_id VARCHAR, -- z.B. 'C1', 'D4', 'S1'
level VARCHAR, -- CRITICAL/HIGH/MEDIUM/LOW/INFO/OK
message TEXT,
details JSONB,
notified BOOLEAN, -- Telegram gesendet?
alerted_at TIMESTAMP,
resolved_at TIMESTAMP -- NULL = aktiv, NOT NULL = aufgelöst
)
Check-Übersicht¶
| Check | Kategorie | Beschreibung | Level-Range |
|---|---|---|---|
| C1 | On-Chain | Settlement-Status | OK / CRITICAL |
| C4 | On-Chain | Relayer-ETH-Balance | OK / HIGH / CRITICAL |
| C5 | On-Chain | VRF-Seed | OK / CRITICAL |
| S2 | On-Chain | RPC-Erreichbarkeit | OK / CRITICAL |
| D1 | Database | Stuck Buy-Intents | OK / MEDIUM / HIGH |
| D4 | Database | Settlement-Pipeline | OK / INFO / HIGH / CRITICAL |
| D5 | Database | DB-Connection | OK / CRITICAL |
| D6 | Database | chain_stats Frische | OK / MEDIUM / HIGH |
| S1 | Service | App-Erreichbarkeit | OK / HIGH |
Fehlerbehandlung¶
- Jeder Check ist in try/catch gewrappt
- Einzelne Check-Fehler crashen nicht den gesamten Run
- Check-Fehler werden als CRITICAL-Alert gemeldet
- Watchdog-Run wird immer als Ganzes abgeschlossen