Welle 1 · Vorhersage „voll in etwa N Tagen“: Pool, NAS, Systemplatte, Container, VMs und die Platte der KI-Box
Aus dem Verlauf der Woche (Tagesmittel, Schutz gegen einmalige Sprünge, schneller werdendes Volllaufen zählt sofort): gelb unter 14, rot unter 3 Tagen. Der Wächter meldet es, auch wenn der Füllstand selbst noch unauffällig ist; Speicherkarte, Geräte-Tabelle, Instrumente der Übersicht und die KI-Box-Seite zeigen es an. Jeder Bericht des Ausführers schreibt dafür die Belegungen in die Messreihe „speicher“. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
34360c9644
commit
f7a9b8ad50
@@ -9,7 +9,7 @@ gesehen. Dieser Wächter schaut deshalb breiter hin:
|
||||
• Timer-Läufe Einmal-Dienste hinter Timern (projekte-sync, Sicherung)
|
||||
• Hermes-Jobs Status der Cron-Jobs + Werkzeugfehler im letzten Lauf (errors.log)
|
||||
• Kern Engine, Hirn, Hermes, Hör-Dienst, MC2, Gateway antworten per HTTP
|
||||
• Platte Füllstand des Modell-Laufwerks
|
||||
• Platte Füllstand des Modell-Laufwerks, seit 25.09.2026 auch das Tempo („in etwa N Tagen voll“)
|
||||
• Updates Bausteine, die der Sonntags-Lauf nach einem Fehlschlag festhält
|
||||
• Probe monatliche Probe-Wiederherstellung der Sicherung (rot oder zu alt = gelb)
|
||||
|
||||
@@ -44,7 +44,7 @@ from pathlib import Path
|
||||
import httpx
|
||||
import psutil
|
||||
from config import HERMES_API_KEY, HERMES_API_URL, HERMES_HOME, VOICE_SERVICE_URL
|
||||
from kern import partner
|
||||
from kern import partner, prognose
|
||||
from kern.einstellungen import einstellungen
|
||||
from kern.zeit import LOCAL_TZ
|
||||
|
||||
@@ -454,19 +454,29 @@ def pruefe_kern() -> list[Befund]:
|
||||
|
||||
|
||||
def pruefe_platte() -> list[Befund]:
|
||||
"""Füllstand der eigenen Platte (gelb ab DISK_GELB_PCT, rot ab DISK_ROT_PCT). Auf der KI-Box seit 25.09.2026
|
||||
auch das Tempo des Modell-Laufwerks (kern/prognose.py): in weniger als 14 Tagen voll = gelb, unter 3 Tagen rot —
|
||||
als eigener Hinweis, wenn er ernster ist als der Füllstand."""
|
||||
befunde, stufe = [], "ok"
|
||||
try:
|
||||
pct = psutil.disk_usage(str(DATEN_DIR) if DATEN_DIR.exists() else os.getcwd()).percent
|
||||
except Exception:
|
||||
return []
|
||||
if pct >= DISK_ROT_PCT:
|
||||
stufe = "rot"
|
||||
elif pct >= DISK_GELB_PCT:
|
||||
stufe = "gelb"
|
||||
else:
|
||||
return []
|
||||
return [Befund(id="platte", stufe=stufe, titel=f"Die Platte ist zu {pct:.0f} % voll",
|
||||
text="Es wird eng für Modelle und Sicherungen. Alte Modelldateien löschen hilft am meisten.",
|
||||
quelle="platte", sofort=True)]
|
||||
pct = None
|
||||
if pct is not None and pct >= DISK_GELB_PCT:
|
||||
stufe = "rot" if pct >= DISK_ROT_PCT else "gelb"
|
||||
befunde.append(Befund(id="platte", stufe=stufe, titel=f"Die Platte ist zu {pct:.0f} % voll",
|
||||
text="Es wird eng für Modelle und Sicherungen. Alte Modelldateien löschen hilft am meisten.",
|
||||
quelle="platte", sofort=True))
|
||||
if ROLLE == "box":
|
||||
from services import messwerte
|
||||
v = prognose.aus_messreihe(messwerte.QUELLE, "platte")
|
||||
kuenftig, kommend = prognose.schlimmer(stufe, v)
|
||||
if kommend:
|
||||
befunde.append(Befund(
|
||||
id="platte:tempo", stufe=kuenftig, titel=f"Die Platte ist {prognose.in_tagen(v['tage'])} voll",
|
||||
text=f"{prognose.tempo(v)} Alte Modelldateien löschen hilft am meisten: KI-Box → Modelle → Aufräumen.",
|
||||
quelle="platte"))
|
||||
return befunde
|
||||
|
||||
|
||||
def pruefe_probe_wiederherstellung() -> list[Befund]:
|
||||
@@ -563,28 +573,38 @@ def _gb_komma(n: float) -> str:
|
||||
|
||||
def pruefe_gast_platten() -> list[Befund]:
|
||||
"""Homelab: Läuft die Platte eines Containers voll? Am 24.09.2026 stand AdGuard bei 100 %: Das Abfrageprotokoll
|
||||
schrieb nicht mehr, die Paketsuche scheiterte — und keine Anzeige sagte es."""
|
||||
from services.homelab import apps, kanal
|
||||
schrieb nicht mehr, die Paketsuche scheiterte — und keine Anzeige sagte es. Seit 25.09.2026 auch nach dem Tempo
|
||||
(kern/prognose.py): in weniger als 14 Tagen voll = gelb, unter 3 Tagen rot."""
|
||||
from services.homelab import apps, kanal, speicher
|
||||
daten = kanal.bericht()
|
||||
befunde = []
|
||||
for g in (daten or {}).get("bericht", {}).get("gaeste") or []:
|
||||
platte = g.get("platte") or {}
|
||||
gesamt, belegt = platte.get("gesamt"), platte.get("belegt") or 0
|
||||
if not gesamt or belegt / gesamt < GAST_PLATTE_GELB:
|
||||
if not gesamt:
|
||||
continue
|
||||
app = apps.app_fuer((g.get("app") or {}).get("kennung"), g.get("name"))
|
||||
name = app.name if app else str(g.get("name") or g["vmid"])
|
||||
anteil = belegt / gesamt
|
||||
# Seit 25.09.2026 kennt der Bericht auch die Platte der VMs (über den Gast-Agenten).
|
||||
vm = g.get("art") != "lxc"
|
||||
zid = f"{'vm' if vm else 'ct'}-{g['vmid']}"
|
||||
v = speicher.platten_vorhersage(zid)
|
||||
jetzt_stufe = "rot" if anteil >= GAST_PLATTE_ROT else "gelb" if anteil >= GAST_PLATTE_GELB else "ok"
|
||||
stufe, kommend = prognose.schlimmer(jetzt_stufe, v)
|
||||
if stufe == "ok":
|
||||
continue
|
||||
app = apps.app_fuer((g.get("app") or {}).get("kennung"), g.get("name"))
|
||||
name = app.name if app else str(g.get("name") or g["vmid"])
|
||||
vergroessern = ("VM → Hardware → Festplatte → Aktion → Größe ändern, danach in der VM das Dateisystem "
|
||||
"mitwachsen lassen" if vm else "Container → Ressourcen → Laufwerk → Größe ändern")
|
||||
befunde.append(Befund(
|
||||
id=f"gast-platte:{g['vmid']}", stufe="rot" if anteil >= GAST_PLATTE_ROT else "gelb",
|
||||
titel=f"Platte von {name} zu {min(100, round(anteil * 100))} % voll",
|
||||
text=(f"{_gb_komma(belegt)} von {_gb_komma(gesamt)} GB belegt ({'VM' if vm else 'Container'} {g['vmid']}). "
|
||||
f"Platz schaffen oder in Proxmox die Platte vergrößern: {vergroessern}."),
|
||||
quelle=f"{'vm' if vm else 'ct'}-{g['vmid']}"))
|
||||
id=f"gast-platte:{g['vmid']}", stufe=stufe,
|
||||
titel=(f"Platte von {name} {prognose.in_tagen(v['tage'])} voll" if kommend
|
||||
else f"Platte von {name} zu {min(100, round(anteil * 100))} % voll"),
|
||||
text=((f"{prognose.tempo(v)} " if kommend else "")
|
||||
+ f"{_gb_komma(belegt)} von {_gb_komma(gesamt)} GB belegt ({'VM' if vm else 'Container'} {g['vmid']})."
|
||||
+ ("" if kommend else prognose.dazu(v))
|
||||
+ f" Platz schaffen oder in Proxmox die Platte vergrößern: {vergroessern}."),
|
||||
quelle=zid))
|
||||
return befunde
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user