ADR-0021: Agent-Intervall 6h+Jitter, Debug-Modus, Health-Monitoring
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
eb828fcd06
commit
a48ef99739
104
adr/0021-agent-intervall-debug-modus-health-monitoring.md
Normal file
104
adr/0021-agent-intervall-debug-modus-health-monitoring.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# ADR-0021: Agent-Standardintervall 6h+Jitter, Debug-Modus, Health-Monitoring
|
||||||
|
|
||||||
|
**Status:** Beschlossen
|
||||||
|
**Datum:** 26.08.2026
|
||||||
|
|
||||||
|
## Kontext
|
||||||
|
|
||||||
|
Der Provisioning-Agent (`provisioning-agent/agent.py`) checkte bislang alle
|
||||||
|
5 Minuten ein (`AGENT_POLL_INTERVAL_SECONDS`, fest über eine
|
||||||
|
Server-Umgebungsvariable) — sinnvoll für die Entwicklungsphase, aber bei
|
||||||
|
einer wachsenden Geräteflotte unnötig häufig für den Normalbetrieb. Es gab
|
||||||
|
außerdem keine Möglichkeit, ein einzelnes Gerät gezielt kurzfristig
|
||||||
|
engmaschiger abzufragen (z.B. um eine frisch zugewiesene Rolle zeitnah zu
|
||||||
|
beobachten), ohne das Intervall global zu ändern. Und: der Agent sammelte
|
||||||
|
nur einmalig bei der Installation eine statische Hardware-Inventur
|
||||||
|
(`hardware_snapshots`, siehe `10_hardware.sh`) — es gab keine periodische
|
||||||
|
Sicht auf den *aktuellen* Gerätezustand (Diskbelegung, Auslastung, Uptime).
|
||||||
|
|
||||||
|
Der Boot-Checkin selbst (Agent meldet sich direkt beim Start) war entgegen
|
||||||
|
der ursprünglichen Annahme bereits vorhanden — `agent.py:main()` ruft
|
||||||
|
`run_once()` grundsätzlich vor der ersten `sleep()`-Anweisung auf, daher
|
||||||
|
hier nicht angefasst.
|
||||||
|
|
||||||
|
## Entscheidung
|
||||||
|
|
||||||
|
**Standardintervall:** `AGENT_POLL_INTERVAL_SECONDS`-Default von 300 auf
|
||||||
|
21600 (6 Stunden) angehoben. **Jitter** kommt bewusst aus dem Agenten
|
||||||
|
selbst, nicht vom Server (der kennt keinen sinnvollen Zufallszustand pro
|
||||||
|
Gerät): `agent.py`s `main()`-Loop addiert 0–30 Minuten zufällig auf das
|
||||||
|
zurückgelieferte Intervall, aber **nur** wenn es „groß" ist
|
||||||
|
(`JITTER_THRESHOLD_SECONDS = 3600`) — der kurze Debug-Modus (60s) und der
|
||||||
|
Fallback-Retry bei Fehlern (`FALLBACK_INTERVAL_SECONDS = 60`) bleiben
|
||||||
|
bewusst unverjittert, sonst würde Jitter genau den Zweck des schnellen
|
||||||
|
Debug-Zyklus untergraben.
|
||||||
|
|
||||||
|
**Debug-Modus:** neue Spalte `devices.debug_mode_until` (Migration
|
||||||
|
`0022_agent_debug_mode_und_health.sql`) ist der einzige Zustand — kein
|
||||||
|
separates Enum, kein Cron-Job zum Zurücksetzen. `agent_checkin()`
|
||||||
|
vergleicht bei jeder Anfrage `debug_mode_until` mit der aktuellen Zeit und
|
||||||
|
liefert `poll_interval_seconds` entsprechend (60s im Debug-Modus, sonst
|
||||||
|
6h) — das automatische Zurückfallen nach Ablauf passiert rein durch
|
||||||
|
Zeitvergleich, ohne dass irgendetwas aktiv zurückgesetzt werden muss.
|
||||||
|
Aktivieren (`POST /api/v1/devices/{id}/debug-mode`, setzt `now()+6h`) und
|
||||||
|
Deaktivieren (`DELETE`, setzt `NULL`) sind eigene, dünne Endpunkte, gegen
|
||||||
|
`require_service_token()` wie üblich — Organisationszugehörigkeitsprüfung
|
||||||
|
bleibt Aufgabe der aufrufenden Kundenplattform
|
||||||
|
(`find_device_in_organization()`), nicht dieses Endpunkts. Bewusst **kein
|
||||||
|
zusätzliches Rechte-Gate**: jeder eingeloggte Nutzer der eigenen
|
||||||
|
Organisation darf den Debug-Modus für die eigenen Geräte umschalten,
|
||||||
|
gleiches Muster wie die bestehenden Auftragskatalog-Aktionen.
|
||||||
|
|
||||||
|
**Health-Monitoring:** sechs neue, nullable `devices`-Spalten
|
||||||
|
(`health_disk_used_percent`, `health_ram_used_percent`,
|
||||||
|
`health_uptime_seconds`, `health_load_1m/5m/15m`, `health_collected_at`) —
|
||||||
|
halten bewusst nur den jeweils letzten Stand, keine wachsende Historie
|
||||||
|
(konsistent mit dem Plattenplatz-Bewusstsein an anderer Stelle, siehe
|
||||||
|
`iso_builds`-Aufräumung). Der Agent sammelt die Werte bei jedem Checkin
|
||||||
|
rein über Python-Stdlib (`shutil.disk_usage("/")`, `/proc/meminfo`,
|
||||||
|
`/proc/uptime`, `os.getloadavg()`) — keine neue Abhängigkeit, jeder
|
||||||
|
Einzelwert einzeln per `try/except`, damit ein fehlschlagender Wert (z.B.
|
||||||
|
Load Average auf einem ungewöhnlichen System) die übrigen nicht
|
||||||
|
verhindert. Bewusst ausgeschlossen: Temperatur/SMART-Werte — hätten
|
||||||
|
zusätzliche Pakete/Berechtigungen gebraucht, war nicht Teil der
|
||||||
|
25./26.08.-Planung.
|
||||||
|
|
||||||
|
`agent_checkin()` schreibt `agent_last_checkin` und die Health-Felder in
|
||||||
|
einem kombinierten `UPDATE ... RETURNING debug_mode_until` statt separater
|
||||||
|
Round-Trips. Fehlt das `health`-Objekt in einem einzelnen Checkin (z.B.
|
||||||
|
Sammel-Fehler im Agenten), bleiben die zuvor gespeicherten Health-Werte
|
||||||
|
unverändert stehen statt auf `NULL` zurückzufallen — ein `CASE WHEN`
|
||||||
|
pro Spalte statt eines bedingungslosen Überschreibens.
|
||||||
|
|
||||||
|
`fetch_devices_for_organization()`/`fetch_all_devices()` liefern
|
||||||
|
`debug_mode_until` und `health` jetzt mit aus (gemeinsame SQL-Spaltenliste
|
||||||
|
`GERAETE_HEALTH_SPALTEN_SQL`, gemeinsame Aufbereitung
|
||||||
|
`_health_felder_aus_row()`) — Kundenplattform braucht dafür keinen
|
||||||
|
zusätzlichen Request, das Device-Dict aus der ohnehin schon vorhandenen
|
||||||
|
Besitz-Validierung (`find_device_in_organization()`) trägt die Felder
|
||||||
|
direkt mit.
|
||||||
|
|
||||||
|
**Kundenplattform-UI:** neue Sektion „Debug-Modus" auf der
|
||||||
|
Auftragskatalog-Seite (Kunden- **und** Admin-Bereich, gleiches
|
||||||
|
`zurueck_url`-Präfix-Muster wie die bestehenden Select/Deselect-Formulare
|
||||||
|
aus ADR-0015), neue Sektion „Aktueller Zustand (letzter Checkin)" auf der
|
||||||
|
Hardware-Seite (klar getrennt von der bestehenden statischen
|
||||||
|
Install-Zeit-Inventur), Debug-Badge in beiden Geräte-Listen, und „Zuletzt
|
||||||
|
gemeldet" jetzt auch auf der Log-Seite (vorher nur in der Geräteliste
|
||||||
|
sichtbar, nicht in der Detail-Historie).
|
||||||
|
|
||||||
|
## Konsequenzen
|
||||||
|
|
||||||
|
Migration `0022_agent_debug_mode_und_health.sql` (8 neue `devices`-Spalten,
|
||||||
|
alle nullable, kein Backfill nötig). Kein neuer Cron/Scheduler-Prozess für
|
||||||
|
den Debug-Modus-Rückfall — reine Zeitvergleichslogik im bestehenden
|
||||||
|
Checkin-Pfad.
|
||||||
|
|
||||||
|
Live auf anode verifiziert: `agent_checkin()` mit Health-Payload
|
||||||
|
durchlaufen, `debug_mode_until` korrekt in `poll_interval_seconds`
|
||||||
|
übersetzt (Debug-Endpunkt aktiviert → nächster Checkin liefert 60s, nach
|
||||||
|
Ablauf/Deaktivieren wieder 21600s). `collect_health()` gegen ein echtes
|
||||||
|
Linux-System (enterprise) getestet, liefert plausible Werte ohne
|
||||||
|
Zusatzpaket. UI-Änderungen lokal mit gemocktem Kontext gerendert
|
||||||
|
(Debug-Toggle in beiden Zuständen, Health-Sektion mit/ohne Daten, Log-Seite
|
||||||
|
mit Zeitstempel).
|
||||||
Loading…
x
Reference in New Issue
Block a user