doku: Monitoring mit Verlauf in ARCHITEKTUR und BETRIEB
Aufbau (Speicher, Taktgeber, Ausfuehrer-Faden, Schnittstellen, Waechter), Ablage und Groesse der Dateien, Aufbewahrung, Handgriffe zum Nachsehen und der Hinweis, dass der Ausfuehrer mit ausfuehrer-einrichten.sh kommt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
704c21d839
commit
f840995078
+70
-5
@@ -58,7 +58,7 @@ Client an MC2 vorbei direkt auf `:8080`. Nur den Radar-Kandidaten startet der Ra
|
|||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `mission-control-2` (`:9001`) | `backend/app.py` | Oberfläche aus `frontend/dist`; 62 `/api`-Routen; reicht `/v1` roh an den Gateway weiter (`MC_V1_UPSTREAM`); reicht das Hermes-Dashboard unter `/hermes-ui/` durch (HTTP und WebSocket); Erinnerungen; startet Update- und Download-Aufträge als eigene systemd-Einheiten `mc2-job-<id>` (`services/jobengine.py`) | Briefkasten, Erinnerungen, Routing-Policy, Hugging-Face-Zugang, ausgeblendete Hinweise |
|
| `mission-control-2` (`:9001`) | `backend/app.py` | Oberfläche aus `frontend/dist`; 62 `/api`-Routen; reicht `/v1` roh an den Gateway weiter (`MC_V1_UPSTREAM`); reicht das Hermes-Dashboard unter `/hermes-ui/` durch (HTTP und WebSocket); Erinnerungen; startet Update- und Download-Aufträge als eigene systemd-Einheiten `mc2-job-<id>` (`services/jobengine.py`) | Briefkasten, Erinnerungen, Routing-Policy, Hugging-Face-Zugang, ausgeblendete Hinweise |
|
||||||
| `mc2-gateway` (`127.0.0.1:9010`) | `backend/gateway_app.py` | `/v1` mit `model: auto` und Bild-Weiche, Kontext-Warnung, `/gw/health` | Token-Zähler (`~/.hermes/token_stats.json`) |
|
| `mc2-gateway` (`127.0.0.1:9010`) | `backend/gateway_app.py` | `/v1` mit `model: auto` und Bild-Weiche, Kontext-Warnung, `/gw/health` | Token-Zähler (`~/.hermes/token_stats.json`) |
|
||||||
| `mc2-steward` | `backend/steward.py` | Re-Warm (alle 90 s, lädt das Hirn nach, wenn nichts geladen ist), Config-Watch (5 s), Wächter (jede Minute) | `mc2-waechter.json` (einziger Schreiber) |
|
| `mc2-steward` | `backend/steward.py` | Re-Warm (alle 90 s, lädt das Hirn nach, wenn nichts geladen ist), Config-Watch (5 s), Wächter (jede Minute), Messwerte (ein Punkt je Minute, seit 24.09.) | `mc2-waechter.json` (einziger Schreiber), `mc2-messwerte/box-*.jsonl` |
|
||||||
| `mc2-radar` (Timer 00:30) | `backend/radar_lauf.py` | Suche und Nachttest neuer Modelle | `mc2-radar.json`, Baseline, `/srv/models/radar/` |
|
| `mc2-radar` (Timer 00:30) | `backend/radar_lauf.py` | Suche und Nachttest neuer Modelle | `mc2-radar.json`, Baseline, `/srv/models/radar/` |
|
||||||
| Bash-Schicht | `deploy/*.sh` | Updates (`autoupdate.sh` mit `update-swap.sh`, `update-engine.sh`, Postchecks, `self-repair.sh`), Sicherung (`backup.sh`, `restore.sh`), Meldungen (`notify.sh`, `morgenmeldung.sh`), Vorwärmen (`warmup.sh`), `projekte-sync.sh`, Deploy (`deploy.sh`, `pruefen.sh`) | Pins, Meldeprotokoll, Nacht-Warteschlange, Deploy-Log |
|
| Bash-Schicht | `deploy/*.sh` | Updates (`autoupdate.sh` mit `update-swap.sh`, `update-engine.sh`, Postchecks, `self-repair.sh`), Sicherung (`backup.sh`, `restore.sh`), Meldungen (`notify.sh`, `morgenmeldung.sh`), Vorwärmen (`warmup.sh`), `projekte-sync.sh`, Deploy (`deploy.sh`, `pruefen.sh`) | Pins, Meldeprotokoll, Nacht-Warteschlange, Deploy-Log |
|
||||||
|
|
||||||
@@ -172,6 +172,7 @@ Fremde Dienste, die der Box-Wart nur steuert oder überwacht: `llama-swap` (Syst
|
|||||||
| `/srv/models/mc2-deploy.log` | `deploy.sh` | eine Zeile je Deploy, auch gescheiterte |
|
| `/srv/models/mc2-deploy.log` | `deploy.sh` | eine Zeile je Deploy, auch gescheiterte |
|
||||||
| `~/mc2-notify.log` | `notify.sh` (anhängen), `morgenmeldung.sh` (über 3 MB auf 2 MB kürzen) | Quelle des Update-Verlaufs für Läufe vor dem 24.09.; der Wortlaut „QUEUED für Morgen-Digest" muss bleiben |
|
| `~/mc2-notify.log` | `notify.sh` (anhängen), `morgenmeldung.sh` (über 3 MB auf 2 MB kürzen) | Quelle des Update-Verlaufs für Läufe vor dem 24.09.; der Wortlaut „QUEUED für Morgen-Digest" muss bleiben |
|
||||||
| `/srv/models/mc2-update-verlauf.jsonl` | `autoupdate.sh`, MC2 (Update-Knöpfe) | nur anhängen, eine JSON-Zeile je Baustein |
|
| `/srv/models/mc2-update-verlauf.jsonl` | `autoupdate.sh`, MC2 (Update-Knöpfe) | nur anhängen, eine JSON-Zeile je Baustein |
|
||||||
|
| `/srv/models/mc2-messwerte/box-JJJJ-MM-TT.jsonl` | nur der Steward (Box); im Homelab `/var/lib/mc2/mc2-messwerte/<gerät>-…` nur MC2 | nur anhängen unter `flock`, eine Zeile je Minute; Tage älter als 8 löscht der Schreiber selbst (siehe „Monitoring“) |
|
||||||
| `~/.hermes/night-queue.txt` | `notify.sh` (anhängen), `morgenmeldung.sh` (übernehmen, senden) | nicht gesendeter Stapel bleibt als `.senden` liegen |
|
| `~/.hermes/night-queue.txt` | `notify.sh` (anhängen), `morgenmeldung.sh` (übernehmen, senden) | nicht gesendeter Stapel bleibt als `.senden` liegen |
|
||||||
|
|
||||||
## Meldeweg
|
## Meldeweg
|
||||||
@@ -201,6 +202,7 @@ Partner-Instanz. In der Rolle `homelab` gibt es nur `/api/health` und die Partne
|
|||||||
| Modelle (`routers/models.py`) | `GET /models`, `GET /discover`, `POST /models/register`, `GET /hf/search`, `GET /hf/quants`, `POST /models/install`, `GET /jobs`, `POST /jobs/{id}/cancel`, `POST /models/{id}/role`, `POST /models/unload`, `POST /models/{id}/unload`, `POST /models/{id}/load`, `DELETE /models/{id}` |
|
| Modelle (`routers/models.py`) | `GET /models`, `GET /discover`, `POST /models/register`, `GET /hf/search`, `GET /hf/quants`, `POST /models/install`, `GET /jobs`, `POST /jobs/{id}/cancel`, `POST /models/{id}/role`, `POST /models/unload`, `POST /models/{id}/unload`, `POST /models/{id}/load`, `DELETE /models/{id}` |
|
||||||
| Wartung (`routers/maintenance.py`) | `GET /maintenance/updates`, `GET /maintenance/update-details`, `POST` `check-updates`, `os-update`, `engine-update`, `swap-update`, `hermes-update`, `update-all`, `restart`; `GET /maintenance/logs`; `GET`/`POST /maintenance/geheimnisse` |
|
| Wartung (`routers/maintenance.py`) | `GET /maintenance/updates`, `GET /maintenance/update-details`, `POST` `check-updates`, `os-update`, `engine-update`, `swap-update`, `hermes-update`, `update-all`, `restart`; `GET /maintenance/logs`; `GET`/`POST /maintenance/geheimnisse` |
|
||||||
| System (`routers/system.py`) | `GET /system/status`, `GET /system/services`, `POST /system/backup`, `GET /system/backups`, `POST /system/restart`, `GET /system/token-stats` |
|
| System (`routers/system.py`) | `GET /system/status`, `GET /system/services`, `POST /system/backup`, `GET /system/backups`, `POST /system/restart`, `GET /system/token-stats` |
|
||||||
|
| Messwerte (`routers/messwerte.py`, seit 24.09.) | `GET /messwerte?zeitraum=1h\|24h\|7d` |
|
||||||
| Lucy und Sprache (`routers/voice.py`) | `POST /alarm`, `POST /voice/announce`, `GET /voice/announcements`, `POST /voice/stt`, `POST /voice/turn`, `POST /voice/chat`, `GET /lucy/stimme/health`, `POST /lucy/stimme/tts`, `POST /lucy/stimme/tts/stream` |
|
| Lucy und Sprache (`routers/voice.py`) | `POST /alarm`, `POST /voice/announce`, `GET /voice/announcements`, `POST /voice/stt`, `POST /voice/turn`, `POST /voice/chat`, `GET /lucy/stimme/health`, `POST /lucy/stimme/tts`, `POST /lucy/stimme/tts/stream` |
|
||||||
| Sonstiges | `GET /health`, `GET /stream` (Live-Strom, SSE), `GET /routing`, `GET`/`POST /reminders`, `DELETE /reminders/{id}`, `GET /zeitmaschine`, `POST /zeitmaschine/restore` |
|
| Sonstiges | `GET /health`, `GET /stream` (Live-Strom, SSE), `GET /routing`, `GET`/`POST /reminders`, `DELETE /reminders/{id}`, `GET /zeitmaschine`, `POST /zeitmaschine/restore` |
|
||||||
| Partner (`routers/partner.py`) | `GET /partner` (Lebenszeichen), `/partner/{pfad}` (Durchreiche, alle Methoden) |
|
| Partner (`routers/partner.py`) | `GET /partner` (Lebenszeichen), `/partner/{pfad}` (Durchreiche, alle Methoden) |
|
||||||
@@ -234,7 +236,7 @@ flowchart LR
|
|||||||
feste Liste von Aktionen aus (`bericht`, `snapshot`, `update`, `os_update`, `suchen`, `zurueck`,
|
feste Liste von Aktionen aus (`bericht`, `snapshot`, `update`, `os_update`, `suchen`, `zurueck`,
|
||||||
`snapshot_loeschen`, `sichern`, `sicherung_zurueck`, `sicherung_loeschen`, `host_update`, `host_neustart`) und
|
`snapshot_loeschen`, `sichern`, `sicherung_zurueck`, `sicherung_loeschen`, `host_update`, `host_neustart`) und
|
||||||
prüft selbst, ob ein Gast das Etikett `community-script` oder `watcher` trägt und nicht `watcher-aus` — dem Server
|
prüft selbst, ob ein Gast das Etikett `community-script` oder `watcher` trägt und nicht `watcher-aus` — dem Server
|
||||||
vertraut er dabei nicht.
|
vertraut er dabei nicht. Seit 24.09. schickt er außerdem jede Minute Messwerte (eigener Faden, siehe „Monitoring“).
|
||||||
- **Bericht** (nur lesend, auch von Hand: `python3 ausfuehrer.py --bericht`): Host-Version und Paket-Updates, je
|
- **Bericht** (nur lesend, auch von Hand: `python3 ausfuehrer.py --bericht`): Host-Version und Paket-Updates, je
|
||||||
Gast Status, IP, Etiketten, Snapshots, ob ein Snapshot geht (Bind-Mounts wie beim PBS verhindern ihn), die
|
Gast Status, IP, Etiketten, Snapshots, ob ein Snapshot geht (Bind-Mounts wie beim PBS verhindern ihn), die
|
||||||
Community-Script-Kennung (aus `/usr/bin/update` im Gast), die App-Version (je App eigener Weg: `/root/.<app>`,
|
Community-Script-Kennung (aus `/usr/bin/update` im Gast), die App-Version (je App eigener Weg: `/root/.<app>`,
|
||||||
@@ -257,7 +259,8 @@ flowchart LR
|
|||||||
`apps.py` (App-Katalog: Name, GitHub-Quelle, Weboberfläche, Update-Weg), `inventar.py` (Bericht + neueste Versionen
|
`apps.py` (App-Katalog: Name, GitHub-Quelle, Weboberfläche, Update-Weg), `inventar.py` (Bericht + neueste Versionen
|
||||||
von GitHub + eigene Webprüfung → Ziele im gemeinsamen Modell; Paketlisten älter als 14 Tage = „unklar“ mit Knopf
|
von GitHub + eigene Webprüfung → Ziele im gemeinsamen Modell; Paketlisten älter als 14 Tage = „unklar“ mit Knopf
|
||||||
„Nach Updates suchen“), `karenz.py` (Wartezeit nach einer Skriptänderung), `updates.py` („Jetzt updaten“),
|
„Nach Updates suchen“), `karenz.py` (Wartezeit nach einer Skriptänderung), `updates.py` („Jetzt updaten“),
|
||||||
`pflege.py` (wöchentliches Suchen). Schnittstellen `routers/homelab.py` unter `/api/homelab/…`.
|
`pflege.py` (wöchentliches Suchen), `messwerte.py` (Minutenpunkte des Ausführers, siehe „Monitoring“).
|
||||||
|
Schnittstellen `routers/homelab.py` unter `/api/homelab/…`.
|
||||||
- **„Jetzt updaten“** (nur per Knopf): Snapshot, wo keiner geht Sicherung (wo auch die nicht geht: ohne Rückweg, mit
|
- **„Jetzt updaten“** (nur per Knopf): Snapshot, wo keiner geht Sicherung (wo auch die nicht geht: ohne Rückweg, mit
|
||||||
Warnung in der Rückfrage; scheitert der Schritt, beginnt das Update nicht) → `update` des Community-Scripts
|
Warnung in der Rückfrage; scheitert der Schritt, beginnt das Update nicht) → `update` des Community-Scripts
|
||||||
(`PHS_SILENT=1`) bzw. Pakete → 20 s warten → frischer Bericht → Prüfung (Gast läuft, Weboberfläche antwortet,
|
(`PHS_SILENT=1`) bzw. Pakete → 20 s warten → frischer Bericht → Prüfung (Gast läuft, Weboberfläche antwortet,
|
||||||
@@ -284,8 +287,9 @@ flowchart LR
|
|||||||
mit `MC_ARCANE_ECHT=1`. Die Arcane-VM braucht dafür kein Etikett, weil der Ausführer nicht beteiligt ist.
|
mit `MC_ARCANE_ECHT=1`. Die Arcane-VM braucht dafür kein Etikett, weil der Ausführer nicht beteiligt ist.
|
||||||
- **Wächter** in der Rolle `homelab`: Platte, Partner (die KI-Box), Ausführer (kein Bericht seit 30 min = rot),
|
- **Wächter** in der Rolle `homelab`: Platte, Partner (die KI-Box), Ausführer (kein Bericht seit 30 min = rot),
|
||||||
jede Weboberfläche der freigegebenen Gäste (außer mitten in ihrem Update-Lauf; das Ergebnis meldet der Lauf), die
|
jede Weboberfläche der freigegebenen Gäste (außer mitten in ihrem Update-Lauf; das Ergebnis meldet der Lauf), die
|
||||||
Platten der laufenden Container (ab 80 % gelb, ab 90 % rot — ext4 hält 5 % für root zurück; der Ausführer schickt `platte` mit) und das
|
Platten der laufenden Container (ab 80 % gelb, ab 90 % rot — ext4 hält 5 % für root zurück; der Ausführer schickt `platte` mit), das
|
||||||
wöchentliche Suchen (gelb, wenn es wiederholt scheitert).
|
wöchentliche Suchen (gelb, wenn es wiederholt scheitert) und seit 24.09. den Proxmox-Host selbst aus den Messwerten
|
||||||
|
(gelb, wenn er 10 Minuten lang über 95 % RAM oder 90 °C CPU liegt).
|
||||||
- **Oberfläche** (Bereich „Homelab“, nur Daten aus `/api/homelab/…`):
|
- **Oberfläche** (Bereich „Homelab“, nur Daten aus `/api/homelab/…`):
|
||||||
- **Cockpit** (`/homelab`): oben die Lage wie das Warnpanel der KI-Box — die große Leuchte (Störung vor Hinweis vor
|
- **Cockpit** (`/homelab`): oben die Lage wie das Warnpanel der KI-Box — die große Leuchte (Störung vor Hinweis vor
|
||||||
laufendem Update vor offenen Updates) und eine Lampe je Gerät —, darunter die Hinweise des Homelab-Wächters und
|
laufendem Update vor offenen Updates) und eine Lampe je Gerät —, darunter die Hinweise des Homelab-Wächters und
|
||||||
@@ -298,3 +302,64 @@ flowchart LR
|
|||||||
(`/etc/mc2/telegram.env`), nachts sammelt eine eigene Morgenmeldung („[Morgenmeldung Homelab]“).
|
(`/etc/mc2/telegram.env`), nachts sammelt eine eigene Morgenmeldung („[Morgenmeldung Homelab]“).
|
||||||
- **Einrichtung** (Reihenfolge, jeder Schritt braucht das User-OK): `container-anlegen.sh` → `ausrollen.sh <ip>` →
|
- **Einrichtung** (Reihenfolge, jeder Schritt braucht das User-OK): `container-anlegen.sh` → `ausrollen.sh <ip>` →
|
||||||
`ausfuehrer-einrichten.sh <ip>` → `box-partner.sh <ip>`; Details in [BETRIEB.md](BETRIEB.md).
|
`ausfuehrer-einrichten.sh <ip>` → `box-partner.sh <ip>`; Details in [BETRIEB.md](BETRIEB.md).
|
||||||
|
|
||||||
|
## Monitoring: Messwerte mit Verlauf (seit 24.09.)
|
||||||
|
|
||||||
|
Der Live-Strom der KI-Box (`/api/stream`, jede Sekunde ein Messpunkt) zeigt nur den Augenblick. Für den Verlauf
|
||||||
|
schreiben beide Bereiche jede Minute einen Punkt, gelesen wird er für die letzte Stunde, den letzten Tag oder die
|
||||||
|
letzte Woche.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
ST["mc2-steward (Box)<br/>jede Minute"] -->|box-…jsonl| MR[("mc2-messwerte/<br/>kern/messreihen.py")]
|
||||||
|
AF["Ausführer (pve)<br/>eigener Faden, jede Minute"] -->|POST …/ausfuehrer/messwerte| HL["Homelab-Teil<br/>services/homelab/messwerte.py"]
|
||||||
|
HL -->|pve-…, ct-…, vm-…jsonl| MR2[("mc2-messwerte/<br/>im Container")]
|
||||||
|
MR -->|GET /api/messwerte| UI["Oberfläche"]
|
||||||
|
MR2 -->|GET /api/homelab/messwerte| UI
|
||||||
|
MR2 -->|RAM, Temperatur| W["Wächter (homelab)"]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Speicher** `backend/kern/messreihen.py` (beide Rollen): je Quelle und Tag eine Datei
|
||||||
|
`<Datenordner>/mc2-messwerte/<quelle>-JJJJ-MM-TT.jsonl` (Tag nach Berliner Zeit), eine JSON-Zeile je Minute
|
||||||
|
(`{"t": Unix-Sekunden, "cpu": …, …}`, `null` = nicht gemessen). Schreiben hängt eine Zeile an, unter Thread-Sperre
|
||||||
|
und `flock`; fehlt am Dateiende der Zeilenumbruch (Absturz), beginnt die neue Zeile auf einer eigenen. Das erste
|
||||||
|
Schreiben eines neuen Tages löscht Dateien, deren Tag mehr als 8 Tage zurückliegt. Lesen verdichtet: `1h` in
|
||||||
|
60-s-Schritten, `24h` als 5-min-Mittel, `7d` als 30-min-Mittel (60, 288 bzw. 336 Werte, Schritte auf vollen
|
||||||
|
Vielfachen, der letzte ist der laufende). Ein Schritt ohne Messung bleibt `null`, nichts wird aufgefüllt; kaputte
|
||||||
|
Zeilen werden übersprungen. Die Summen vergangener Tage merkt sich der Prozess je Datei, solange sie sich nicht
|
||||||
|
ändert. Gemessen wird zur halben Minute, damit jeder 60-s-Schritt genau einen Punkt bekommt.
|
||||||
|
- **KI-Box** (`services/messwerte.py`, Taktgeber im Steward; `MC_MESSWERTE_ENABLED=0` schaltet ab, ein Trocken- oder
|
||||||
|
Probelauf schreibt nie mit): `cpu` = Mittel der Minute (aus eigenen `psutil.cpu_times`-Ständen gerechnet wie
|
||||||
|
`cpu_percent`, denn psutil merkt sich den letzten Aufruf je Thread), `ram` und `platte` (Modell-Laufwerk) beim Messen,
|
||||||
|
`gpu`, `temp_cpu`, `temp_gpu` als Mittel von Proben alle 5 s (`MC_MESSWERTE_PROBE_S`), `netz_rx`/`netz_tx` in
|
||||||
|
Bytes/s über alle Schnittstellen außer `lo`, `tokens` = Prompt- plus Antwort-Tokens pro Minute (Differenz der
|
||||||
|
Gesamtzähler aus `services/token_stats.py`). Ein Zähler, der kleiner wird, ergibt in dieser Minute `null`.
|
||||||
|
- **Homelab:** Der Ausführer schickt in einem eigenen Faden jede Minute `POST /api/homelab/ausfuehrer/messwerte`
|
||||||
|
(gleiche Anmeldung wie seine anderen Endpunkte), unabhängig vom 10-min-Bericht und von Aufträgen, die bis zu einer
|
||||||
|
Stunde laufen. Host-Werte liest er selbst aus `/proc` (`stat` für das CPU-Mittel der Minute, `meminfo`, `loadavg`,
|
||||||
|
`uptime`) und `statvfs("/")`, denn `pvesh get /nodes/<node>/status` liefert in einem frischen pvesh-Prozess immer
|
||||||
|
`cpu: 0` (nachgesehen am 24.09.); belegt wie bei Proxmox: RAM = gesamt − verfügbar, rootfs = gesamt − frei. Netz des
|
||||||
|
Hosts = Summe der physischen Schnittstellen aus `/proc/net/dev` (wie die Knoten-Anzeige in Proxmox; `vmbr0` sähe den
|
||||||
|
Verkehr der Gäste nach draußen nicht), ohne physische Schnittstelle `vmbr0`. CPU-Temperatur aus hwmon (`k10temp`
|
||||||
|
bzw. `zenpower` mit Tdie vor Tctl, `coretemp` mit „Package id 0“), sonst `null`; auf dem Proxmox-PC gibt es nur
|
||||||
|
`k10temp`/Tctl, kein `thermal_zone` und kein lm-sensors. Die Gäste kommen aus einem einzigen Aufruf
|
||||||
|
`pvesh get /cluster/resources --type vm` (`cpu` schon auf die eigenen Kerne gerechnet, `mem`, `disk`, …), ihre
|
||||||
|
Netz-Zähler aber aus denselben `/proc/net/dev`-Zeilen (`veth<vmid>iN`, `tap<vmid>iN`; die Stände in
|
||||||
|
`/cluster/resources` sind bis zu 10 s alt und verzerrten die Minutenrate). Fehler bleiben still; ein Fehler steht
|
||||||
|
einmal im Journal, bis wieder ein Punkt durchgeht. Von Hand: `python3 ausfuehrer.py --messwerte`.
|
||||||
|
- **Homelab-Teil** (`services/homelab/messwerte.py`): rechnet die kumulativen Zähler in Bytes/s um. Keine Rate
|
||||||
|
(`null`) gibt es, wenn der Zähler oder die Laufzeit kleiner wurde (Neustart von Gast oder Host), der vorige Stand
|
||||||
|
fehlt (Neustart des Homelab-Teils; die Stände liegen nur im Speicher) oder mehr als 5 Minuten zurückliegt, oder der
|
||||||
|
Sprung über 5 GB/s liegt. Gestoppte Gäste haben keine Messwerte (`null`, keine Nullen); die Platte einer VM sieht
|
||||||
|
Proxmox nicht (`null`). Der eigene Container (Etikett `mc2`) wird wie im Inventar nicht erfasst. Quellen `pve`,
|
||||||
|
`ct-<vmid>`, `vm-<vmid>`.
|
||||||
|
- **Schnittstellen:** `GET /api/messwerte?zeitraum=1h|24h|7d` (nur Rolle `box`) liefert
|
||||||
|
`{zeitraum, schritt_s, reihen: {cpu, ram, gpu, temp_cpu, temp_gpu, platte, netz_rx, netz_tx, tokens}, aktuell}`;
|
||||||
|
`GET /api/homelab/messwerte?zeitraum=…` liefert `{zeitraum, schritt_s, geraete: [{id, name, art, reihen, aktuell}]}`
|
||||||
|
mit den Geräten wie im Inventar (Host, dann die Gäste nach Nummer; Namen aus `apps.py`). Jede Reihe ist eine Liste
|
||||||
|
`[t, wert]` (t = Beginn des Schritts); `temp_cpu` gibt es als Reihe nur beim Host, in `aktuell` stehen `temp_cpu`
|
||||||
|
und `load1` bei Gästen auf `null`. `aktuell` ist der letzte Minutenpunkt, solange er höchstens 3 Minuten alt ist,
|
||||||
|
sonst lauter `null`. Ein unbekannter Zeitraum ergibt 400. Neue Punkte stößt der Live-Strom nicht an: Die Oberfläche
|
||||||
|
fragt die Messwerte selbst nach (einmal je Minute genügt).
|
||||||
|
- **Wächter** (Rolle `homelab`, `pruefe_host`): gelb, wenn der Proxmox-Host in den letzten 10 Minuten (mindestens 8
|
||||||
|
Minutenpunkte) durchgehend über 95 % RAM (`MC_WAECHTER_HOST_RAM`) oder über 90 °C CPU (`MC_WAECHTER_HOST_TEMP`) lag.
|
||||||
|
|||||||
+41
-4
@@ -81,11 +81,13 @@ soll kein Alarm sein).
|
|||||||
| Festgehaltene Updates | – | jeder Pin |
|
| Festgehaltene Updates | – | jeder Pin |
|
||||||
| Partner-Instanz (nur mit `MC_PARTNER_URL`) | „<Name> antwortet nicht" | – |
|
| Partner-Instanz (nur mit `MC_PARTNER_URL`) | „<Name> antwortet nicht" | – |
|
||||||
| Sicherung (seit 24.09.) | – | `pbs-backup` scheitert; Probe-Wiederherstellung rot, älter als 40 Tage oder noch nie gelaufen (sobald ihr Timer eingerichtet ist) |
|
| Sicherung (seit 24.09.) | – | `pbs-backup` scheitert; Probe-Wiederherstellung rot, älter als 40 Tage oder noch nie gelaufen (sobald ihr Timer eingerichtet ist) |
|
||||||
|
| Proxmox-Host (nur Rolle `homelab`, seit 24.09.) | – | 10 Minuten lang über 95 % RAM oder über 90 °C CPU (aus den Messwerten, mindestens 8 Minutenpunkte) |
|
||||||
| Abgestürzte Prüfung | – | „Eine Prüfung des Wächters lief nicht" |
|
| Abgestürzte Prüfung | – | „Eine Prüfung des Wächters lief nicht" |
|
||||||
|
|
||||||
In der Rolle `homelab` prüft der Wächter Platte, Partner, den Ausführer und die Weboberflächen der freigegebenen
|
In der Rolle `homelab` prüft der Wächter Platte, Partner, den Ausführer, die Weboberflächen der freigegebenen
|
||||||
Gäste (einen Gast mitten in seinem Update-Lauf nicht: Das Ergebnis meldet der Lauf selbst) und meldet mit
|
Gäste (einen Gast mitten in seinem Update-Lauf nicht: Das Ergebnis meldet der Lauf selbst) und seit 24.09. RAM und
|
||||||
„[Homelab-Problem]". Im selben Takt stößt er das wöchentliche Suchen an (siehe „Homelab-Teil im Betrieb“); scheitert
|
CPU-Temperatur des Proxmox-Hosts (gelb, Schwellen über `MC_WAECHTER_HOST_RAM` und `MC_WAECHTER_HOST_TEMP` in
|
||||||
|
`/etc/mc2/homelab.env`) und meldet mit „[Homelab-Problem]". Im selben Takt stößt er das wöchentliche Suchen an (siehe „Homelab-Teil im Betrieb“); scheitert
|
||||||
es für einen Gast zweimal hintereinander, gibt es einen gelben Hinweis „<App>: Die Suche nach Updates scheitert“.
|
es für einen Gast zweimal hintereinander, gibt es einen gelben Hinweis „<App>: Die Suche nach Updates scheitert“.
|
||||||
|
|
||||||
- **Selbstreparatur:** Nur ein abgestürzter Dienst (`ActiveState=failed`) wird neu gestartet, höchstens 2× je Stunde
|
- **Selbstreparatur:** Nur ein abgestürzter Dienst (`ActiveState=failed`) wird neu gestartet, höchstens 2× je Stunde
|
||||||
@@ -257,6 +259,41 @@ laufen lassen. Achtung: `ausfuehrer-einrichten.sh` schreibt `/etc/mc2-ausfuehrer
|
|||||||
nach dem Start. Stand in `/var/lib/mc2/homelab-pflege.json` (Nacht, je Gast: letzter Tag, Fehlschläge, letzter
|
nach dem Start. Stand in `/var/lib/mc2/homelab-pflege.json` (Nacht, je Gast: letzter Tag, Fehlschläge, letzter
|
||||||
Fehler). Schreibt nur der Steward; zum Zurücksetzen die Datei löschen und `systemctl restart mc2-homelab-steward`.
|
Fehler). Schreibt nur der Steward; zum Zurücksetzen die Datei löschen und `systemctl restart mc2-homelab-steward`.
|
||||||
|
|
||||||
|
## Messwerte (Monitoring, seit 24.09.)
|
||||||
|
|
||||||
|
Jede Minute ein Punkt je Gerät, gelesen als letzte Stunde, letzter Tag oder letzte Woche (Aufbau in
|
||||||
|
[ARCHITEKTUR.md](ARCHITEKTUR.md), Abschnitt „Monitoring“).
|
||||||
|
|
||||||
|
- **Wo:** Box `/srv/models/mc2-messwerte/box-JJJJ-MM-TT.jsonl` (schreibt `mc2-steward`). Homelab
|
||||||
|
`/var/lib/mc2/mc2-messwerte/pve-…`, `ct-<vmid>-…`, `vm-<vmid>-…` (schreibt `mc2-homelab`, was der Ausführer jede Minute
|
||||||
|
schickt; Eigentümer `mc2`). Je Tag (Berliner Zeit) eine Datei, eine JSON-Zeile je Minute.
|
||||||
|
- **Wie groß:** eine Zeile hat rund 140 Bytes (Box, Gäste) bzw. 175 Bytes (Proxmox-Host), am Tag 1440 Zeilen. Box:
|
||||||
|
rund 0,2 MB je Tag, höchstens rund 2 MB. Homelab mit Host und 7 Gästen: rund 1,7 MB je Tag, höchstens rund 15 MB;
|
||||||
|
jeder weitere Gast rund 0,2 MB je Tag.
|
||||||
|
- **Wie lange:** Das erste Schreiben eines neuen Tages löscht die Tagesdateien, deren Tag mehr als 8 Tage zurückliegt;
|
||||||
|
es bleiben höchstens 9 je Gerät (heute und die 8 Tage davor). Nicht in der Sicherung (`backup.sh` nimmt nur
|
||||||
|
`mc2-*.json`); das Aufräumen der Modell-Platte bietet den Ordner nie zum Löschen an. Den Ordner von Hand zu löschen
|
||||||
|
ist harmlos: Er entsteht mit dem nächsten Punkt neu, der Verlauf beginnt von vorn.
|
||||||
|
- **Lücken:** Läuft der Steward, die Box oder der Ausführer nicht, bleiben die Minuten leer (`null`) und werden nicht
|
||||||
|
aufgefüllt. Nach einem Neustart des Homelab-Teils fehlt für eine Minute die Netz-Rate; nach dem Neustart eines Gasts
|
||||||
|
oder des Hosts ebenso (die Zähler beginnen von vorn).
|
||||||
|
- **Ansehen:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -n 3 /srv/models/mc2-messwerte/box-$(date +%F).jsonl # Box: die letzten Minuten
|
||||||
|
curl -s 'http://127.0.0.1:9001/api/messwerte?zeitraum=1h' | jq '.aktuell' # Box: letzter Punkt
|
||||||
|
curl -s 'http://192.168.178.31:9001/api/homelab/messwerte?zeitraum=1h' | jq '.geraete[] | {id, aktuell}'
|
||||||
|
python3 /usr/local/lib/mc2/ausfuehrer.py --messwerte # auf pve: ein Punkt, nur lesend (CPU über eine Sekunde)
|
||||||
|
journalctl -u mc2-ausfuehrer -n 50 | grep Messwerte # auf pve: steht hier etwas, gingen Punkte nicht durch
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Ausführer:** Ein neuer Stand kommt nicht mit dem Deploy, sondern mit `bash deploy/homelab/ausfuehrer-einrichten.sh
|
||||||
|
<ip>` (danach ein von Hand gesetztes `sicherung_speicher` wieder eintragen, siehe oben). Ein alter Ausführer schickt
|
||||||
|
keine Messwerte; dann bleibt der Homelab-Verlauf leer, sonst ändert sich nichts.
|
||||||
|
- **Schalter:** `MC_MESSWERTE_ENABLED=0` im Steward der Box schaltet das Schreiben ab; `MC_MESSWERTE_PROBE_S` (Standard
|
||||||
|
5) ist der Abstand der Proben für GPU-Last und Temperaturen. Ein Trocken- oder Probelauf (`MC_WAECHTER_TROCKEN=1`,
|
||||||
|
`MC_PROBELAUF=1`) schreibt nie mit.
|
||||||
|
|
||||||
## Sicherung
|
## Sicherung
|
||||||
|
|
||||||
- **Wann:** `mc2-backup.timer` täglich 03:30 (+≤5 min); außerdem vor jedem Hermes-Update, vor jedem Zurückspielen und
|
- **Wann:** `mc2-backup.timer` täglich 03:30 (+≤5 min); außerdem vor jedem Hermes-Update, vor jedem Zurückspielen und
|
||||||
@@ -383,7 +420,7 @@ Update erneut.
|
|||||||
| `~/mission-control-v2` | Checkout von `main` (nur über `deploy.sh` ändern) |
|
| `~/mission-control-v2` | Checkout von `main` (nur über `deploy.sh` ändern) |
|
||||||
| `~/mission-control-v2/backend/.venv` | Python-Umgebung des Box-Warts (Python 3.14) |
|
| `~/mission-control-v2/backend/.venv` | Python-Umgebung des Box-Warts (Python 3.14) |
|
||||||
| `~/.config/systemd/user/` | User-Units und Drop-ins |
|
| `~/.config/systemd/user/` | User-Units und Drop-ins |
|
||||||
| `/srv/models/` | Modelle, Box-Wart-Zustand (`mc2-*.json`, darunter `mc2-einstellungen.json` und `mc2-stand.json`), Sicherungen (`mc2-backups/`), Radar-Downloads (`radar/`) |
|
| `/srv/models/` | Modelle, Box-Wart-Zustand (`mc2-*.json`, darunter `mc2-einstellungen.json` und `mc2-stand.json`), Sicherungen (`mc2-backups/`), Radar-Downloads (`radar/`), Messwerte (`mc2-messwerte/`) |
|
||||||
| `~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf` | Update-Zeitfenster aus der Oberfläche (nur MC2 schreibt es) |
|
| `~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf` | Update-Zeitfenster aus der Oberfläche (nur MC2 schreibt es) |
|
||||||
| `/etc/llama-swap/config.yaml` | lebende llama-swap-Config (+ `.bak-*`) |
|
| `/etc/llama-swap/config.yaml` | lebende llama-swap-Config (+ `.bak-*`) |
|
||||||
| `/opt/llamacpp-vulkan/`, `/usr/local/bin/llama-server` | Motor (llama.cpp Vulkan) |
|
| `/opt/llamacpp-vulkan/`, `/usr/local/bin/llama-server` | Motor (llama.cpp Vulkan) |
|
||||||
|
|||||||
Reference in New Issue
Block a user