monitor/README.md
fds2610-bot 2a552342f5 Ping-Check meldet den Systemstatus zusaetzlich per REST an die API
Laufen check_fds.sh und die API auf verschiedenen Rechnern, erreicht der
Legacy-Import die API nie: SystemController::index() liest MONITOR_STATUS_FILE
als lokale Datei, waehrend status.txt auf dem Ping-Host liegt. Der
LegacyStatusFileReader liefert dann stillschweigend ein leeres Array und der
System-Monitor zeigt dauerhaft "Keine Systeme gemeldet" - ohne Fehlermeldung,
die auf die Ursache hinweisen wuerde.

check_fds.sh meldet die Ping-Ergebnisse jetzt zusaetzlich per
POST /api/v1/systems/{id}/status (online -> ok, offline -> error) und schreibt
status.txt unveraendert weiter. Die Zugangsdaten stehen in monitor-api.conf
(Vorlage: monitor-api-sample.conf); fehlt die Datei, bleibt das Verhalten
unveraendert. Eine unerreichbare API bricht den Check nicht ab, sondern
protokolliert nur eine Warnung.

Die System-ID wird aus dem Hostnamen slugifiziert, weil der Router auf dem
rohen, nicht dekodierten Pfad matcht - "Nextcloud(intern)" landete sonst
prozentkodiert in der Datenbank. Der lesbare Name geht im Feld "name" mit.

Das README beschreibt den kombinierten Weg als "Weg 3" und weist bei Weg 1
darauf hin, dass der Legacy-Import eine lokale Datei erwartet.

Ausserdem zwei Fehler im selben Skript behoben:
- Pfade werden relativ zum Skript statt zum Arbeitsverzeichnis aufgeloest.
- Die letzte Zeile der hosts.conf wurde ohne abschliessenden Zeilenumbruch
  stillschweigend verschluckt, ein zuletzt angehaengter Host also nie geprueft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 20:28:11 +02:00

148 lines
8.1 KiB
Markdown

# 🖥️ monitor
**monitor** überwacht mehrere Systeme (per Ping und/oder per REST-API-Meldungen entfernter
Agenten) und zeigt den Zustand als interaktive **Büro-Visualisierung** (Kanban-Board +
Monitor-Wand mit Agenten an Schreibtischen).
Der vollständige Umbauplan steht in [Visualization.md](Visualization.md) (Roadmap Phase 0-7),
die dazugehörigen Klärungen in [Detailfragen.md](Detailfragen.md) und
[Detailantworten.md](Detailantworten.md).
---
## 🚀 Features
- REST-API (`api/`, siehe [API.md](API.md)) für Tickets, Events, Systeme, KPIs und
Agenten-Aktivität, mit statischen API-Keys pro Agent
- Büro-Visualisierung (`html/office.html`) als Vanilla-SVG-Szene: Kanban-Board, Monitor-Wand
(Events/Systeme/KPIs), 8 Schreibtische - zeigt live die Daten aus der REST-API (Push per
Server-Sent Events, Polling-Fallback), Klick auf Board/Monitore öffnet Detail-Modals,
Agenten laufen animiert zwischen Schreibtisch/Board/Monitor-Wand/Kaffee-Ecke (Phase 3-5,
siehe Visualization.md Abschnitt 9). Ist die API nicht erreichbar, zeigt die Szene
ersatzweise Demo-Daten — kenntlich gemacht durch einen roten Banner „API nicht erreichbar!".
Die Basis-URL der API kommt aus `MONITOR_API_BASE` (siehe `.env.example`).
- Klick auf den PO öffnet ein Modal, in dem sich die vom Codeberg-Sync gelesenen Projekte
(Owner/Repo + Farbe) hinzufügen, bearbeiten und löschen lassen (Issue #27) — Änderungen
wirken sofort im laufenden `sync`-Dienst, ohne Neustart. Schreibende Aktionen fragen einmalig
den `MONITOR_ADMIN_API_KEY` ab und merken ihn sich im Browser.
- Codeberg-Sync als Dauerläufer (Compose-Service `sync`): füllt Backlog und Done automatisch
aus den Issues mehrerer konfigurierter Codeberg-Projekte (je Projekt mit eigener
Ticket-Farbe, siehe oben) — periodisch alle `MONITOR_SYNC_INTERVAL` Sekunden und, wenn ein
Webhook eingerichtet ist, innerhalb von Sekunden nach jeder Issue-Änderung
(`POST /api/v1/webhooks/codeberg`, HMAC-signiert per `CODEBERG_WEBHOOK_SECRET`). Siehe
[API.md](API.md) Abschnitt „Codeberg-Sync" — dort steht auch die Einrichtung im Codeberg-Repo.
- Auto-Update auf einem Produktionsserver: Sobald ein PR nach `main` gemergt wird, kann
`deploy-webhook.py` denselben `update.sh` anstoßen, den auch ein manuelles Update aufruft
(Push-Webhook, HMAC-signiert per `MONITOR_DEPLOY_WEBHOOK_SECRET`) — siehe
[README_UPDATE.md](README_UPDATE.md).
- Weiterhin: klassische Ping-Überwachung (`check_fds.sh`, `hosts.conf`, `mail_fds.py`) als
eine Datenquelle für den System-Monitor; die alte tabellarische Statusseite ist mit
Phase 7 entfallen (F16), `status.txt` speist weiterhin den System-Monitor
---
## 📁 Projektstruktur
- `api/` — REST-API (PHP, SQLite), siehe [api/README.md](api/README.md)
- `html/` — Frontend: `office.html` (Büro-Visualisierung), `js/`, `css/`
- `tests/frontend/` — Node-Tests für die Frontend-Layoutlogik (`node --test`)
- `check_fds.sh`, `mail_fds.py`, `hosts-sample.conf`, `monitor-api-sample.conf` — bestehende
Ping-Überwachung (letztere: optionale Zugangsdaten für die Meldung per REST)
- `docker-compose.yml` — komplette Entwicklungsumgebung (siehe unten)
- `update.sh` — holt die neueste Version vom konfigurierten Git-Remote und aktualisiert die
Docker-Compose-Umgebung (Abhängigkeiten, Images, Dienste, Tests)
- `deploy-webhook.py`, `deploy/` — löst `update.sh` auf einem Produktionsserver automatisch
aus, sobald ein PR nach `main` gemergt wird (Push-Webhook); siehe
[README_UPDATE.md](README_UPDATE.md)
- `register-agent.sh` — Hilfsskript, um einen neuen Agenten per `POST /api/v1/agents` zu
registrieren (siehe [API.md](API.md) Abschnitt "Agenten")
---
## 🐳 Entwicklung (nur Docker, kein lokales PHP/Node nötig)
Analog zum NC-Gantt-Projekt läuft die gesamte Ausführung (Bauen, Entwickeln, Testen) in
Docker-Compose-Containern; auf dem Host muss nichts installiert werden.
```bash
cp .env.example .env # einmalig, MONITOR_ADMIN_API_KEY anpassen
docker compose up --build # API auf :8091, Buero-Visualisierung auf :8090, Sync
docker compose run --rm api composer test # PHPUnit (API)
docker compose run --rm frontend # Node-Tests (Frontend-Layoutlogik)
docker compose logs -f sync # Codeberg-Sync mitlesen
```
Der Browser erreicht die API nicht über das Compose-Netzwerk, sondern über die in
`MONITOR_API_BASE` (`.env`) hinterlegte URL — der Default `http://localhost:8091/api/v1` passt
zum Port-Mapping oben. **Wer die Ports in `docker-compose.yml` ändert oder das System hinter
einem Reverse Proxy betreibt, muss `MONITOR_API_BASE` entsprechend nachziehen**, sonst zeigt
die Szene den Banner „API nicht erreichbar!" und fällt auf Demo-Daten zurück. Der Webserver
liefert den Wert zur Laufzeit als `/config.js` aus (`docker/nginx/default.conf.template`), ein
Build-Schritt ist dafür nicht nötig.
Details zur API: [api/README.md](api/README.md). Details zu den Endpunkten: [API.md](API.md).
---
## 🖥️ Einen Server zur Überwachung hinzufügen
Der **System-Monitor** in der Büro-Visualisierung zeigt zunächst keine Kacheln an, solange
kein System gemeldet wurde — dafür gibt es zwei unabhängige Wege:
**Weg 1: Klassische Ping-Überwachung (`hosts.conf`)**
1. `hosts-sample.conf` nach `hosts.conf` kopieren und um den neuen Server erweitern
(eine Zeile pro Server, Format `Hostname IP`):
```
Webserver 192.168.178.10
```
2. Optional, für E-Mail-Alarme bei Ausfall: `credentials-sample.conf` nach `credentials.conf`
kopieren und die SMTP-Zugangsdaten eintragen (wird von `mail_fds.py` benutzt).
3. `check_fds.sh` regelmäßig ausführen, z.B. per Cron alle paar Minuten. Das Skript pingt
jeden Eintrag aus `hosts.conf` dreimal an und schreibt das Ergebnis in `status.txt` (Pfad
über `STATUS_FILE` im Skript einstellbar).
4. Die API liest `status.txt` laufend mit und zeigt die Einträge als Systeme
(`source: "legacy"`) im System-Monitor an — ohne dass etwas neu gestartet werden muss.
> ⚠️ Dieser Import liest `MONITOR_STATUS_FILE` als **lokale Datei**. Läuft `check_fds.sh` auf
> einem anderen Rechner als die API (oder liegt `status.txt` außerhalb des API-Containers —
> der Mount in `docker-compose.yml` ist standardmäßig auskommentiert), erreicht sie die API
> nie und der System-Monitor bleibt bei „Keine Systeme gemeldet". Fehlt die Datei, meldet die
> API keinen Fehler, sondern liefert eine leere Liste. In dem Fall Weg 3 verwenden.
**Weg 2: Status direkt per REST-API melden**
Eigene Server/Skripte können ihren Status auch ohne `hosts.conf` melden:
1. Einen Agenten registrieren (liefert einmalig einen API-Key zurück, siehe
`register-agent.sh` bzw. [API.md](API.md#agenten)).
2. Mit diesem Key den Status senden:
```bash
curl -X POST "$MONITOR_API_BASE/systems/mein-server/status" \
-H "X-Api-Key: <API-Key>" \
-H "Content-Type: application/json" \
-d '{"status": "ok", "name": "Mein Server", "type": "host"}'
```
So gemeldete Systeme (`source: "api"`) haben Vorrang vor dem Legacy-Import aus `status.txt`
und werden von ihm nicht überschrieben. Details zu Feldern/Auth: [API.md](API.md#systeme).
**Weg 3: Ping-Überwachung, die ihre Ergebnisse selbst per REST meldet**
Kombiniert beide Wege und ist der richtige Weg, wenn der Ping-Check auf einem anderen Rechner
läuft als die API — dann fällt der Umweg über die Datei `status.txt` weg:
1. Wie in Weg 1 die `hosts.conf` pflegen und `check_fds.sh` per Cron laufen lassen.
2. Wie in Weg 2 einen Agenten registrieren (Rolle `user`, damit er keinen Schreibtisch in der
Büro-Visualisierung belegt).
3. `monitor-api-sample.conf` nach `monitor-api.conf` neben `check_fds.sh` kopieren, dort
`MONITOR_API_BASE` und `MONITOR_API_KEY` eintragen und die Datei auf `chmod 600` setzen.
`check_fds.sh` meldet dann nach jedem Ping zusätzlich per REST (`online` → `ok`,
`offline` → `error`) und schreibt `status.txt` unverändert weiter für den alten Wandmonitor.
Die System-ID entsteht dabei aus dem Hostnamen (`Nextcloud(intern)` → `nextcloud-intern`),
der Originalname bleibt als Anzeigename erhalten. Ist die API nicht erreichbar, läuft die
Ping-Überwachung normal weiter und protokolliert nur eine Warnung.