waechter: Werkzeugfehler eines Jobs bis zum naechsten Lauf ausblenden
Heute stand ein schon behobener web_extract-Fehler des News-Jobs bis zum naechsten Lauf (morgen 07:00) im Cockpit. Neuer Knopf "Ausblenden bis zum naechsten Lauf": MC2 merkt sich den Lauf in /srv/models/mc2-quittiert.json, der Waechter blendet genau diesen Lauf aus. Hat der naechste Lauf wieder Fehler, erscheint der Hinweis erneut. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
4cd856bd34
commit
b0c9549a29
@@ -58,6 +58,9 @@ AUTO_MAX_PRO_STUNDE = int(os.environ.get("MC_WAECHTER_AUTO_MAX", "2"))
|
||||
DISK_ROT_PCT = float(os.environ.get("MC_WAECHTER_DISK_ROT", "90"))
|
||||
DISK_GELB_PCT = float(os.environ.get("MC_WAECHTER_DISK_GELB", "80"))
|
||||
STORE_PATH = Path(os.environ.get("MC_WAECHTER_STORE", str(MODELS_DIR / "mc2-waechter.json")))
|
||||
# „Ausblenden bis zum nächsten Lauf“ (24.09.2026): Hinweis-ID → Start des Laufs, der ausgeblendet ist.
|
||||
# Schreibt nur MC2 (Knopf), der Steward liest. Ein neuer Lauf macht den Eintrag wirkungslos.
|
||||
QUITTIERT_PATH = Path(os.environ.get("MC_WAECHTER_QUITTIERT", str(MODELS_DIR / "mc2-quittiert.json")))
|
||||
VERLAUF_MAX = 200
|
||||
# Trockenlauf (Probelauf neben dem echten Betrieb): prüft und führt Hinweise, meldet aber
|
||||
# nichts an Telegram/Lucy und repariert nichts selbst — das macht weiter der echte Wächter.
|
||||
@@ -305,6 +308,24 @@ def _errors_log_ende(max_bytes: int = 400_000) -> list[str]:
|
||||
return []
|
||||
|
||||
|
||||
def _quittiert() -> dict[str, str]:
|
||||
try:
|
||||
daten = json.loads(QUITTIERT_PATH.read_text(encoding="utf-8"))
|
||||
return daten if isinstance(daten, dict) else {}
|
||||
except (OSError, ValueError):
|
||||
return {}
|
||||
|
||||
|
||||
def quittieren(hinweis_id: str, lauf: str) -> None:
|
||||
"""Hinweis bis zum nächsten Lauf ausblenden (atomar schreiben, alte Einträge begrenzen)."""
|
||||
daten = _quittiert()
|
||||
daten[hinweis_id] = lauf
|
||||
daten = dict(list(daten.items())[-50:])
|
||||
tmp = QUITTIERT_PATH.with_suffix(".json.tmp")
|
||||
tmp.write_text(json.dumps(daten, ensure_ascii=False, indent=1), encoding="utf-8")
|
||||
os.replace(tmp, QUITTIERT_PATH)
|
||||
|
||||
|
||||
def pruefe_hermes_jobs() -> list[Befund]:
|
||||
befunde: list[Befund] = []
|
||||
jobs = _hermes_jobs()
|
||||
@@ -340,13 +361,15 @@ def pruefe_hermes_jobs() -> list[Befund]:
|
||||
if alter > 26 * 3600:
|
||||
continue # nur der aktuelle Lauf zählt
|
||||
anzahl, beispiel = werkzeugfehler_im_lauf(log_zeilen, jid, lauf["started_at"])
|
||||
if anzahl:
|
||||
befund_id = f"job:{jid}:werkzeug"
|
||||
if anzahl and _quittiert().get(befund_id) != lauf["started_at"]:
|
||||
befunde.append(Befund(
|
||||
id=f"job:{jid}:werkzeug", stufe="gelb",
|
||||
id=befund_id, stufe="gelb",
|
||||
titel=f"Job „{name}“: {anzahl} Werkzeugfehler im letzten Lauf",
|
||||
text=beispiel or "Einzelne Werkzeuge meldeten Fehler, der Lauf selbst kam durch.",
|
||||
quelle=f"hermes-cron:{jid}",
|
||||
aktionen=[_aktion("protokoll", "Protokoll", job=jid)],
|
||||
aktionen=[_aktion("protokoll", "Protokoll", job=jid),
|
||||
_aktion("ausblenden", "Ausblenden bis zum nächsten Lauf", lauf=lauf["started_at"])],
|
||||
sofort=True))
|
||||
return befunde
|
||||
|
||||
@@ -595,6 +618,10 @@ def fuehre_aktion_aus(hinweis_id: str, aktion_id: str) -> dict:
|
||||
if not update_verlauf.freigeben(aktion["baustein"]):
|
||||
return {"ok": False, "detail": "Der Baustein war schon freigegeben."}
|
||||
return {"ok": True, "text": update_verlauf.FREIGEGEBEN_TEXT}
|
||||
if aktion_id == "ausblenden":
|
||||
quittieren(hinweis_id, str(aktion.get("lauf", "")))
|
||||
return {"ok": True, "text": "Ausgeblendet. Der Hinweis verschwindet in spätestens einer Minute "
|
||||
"und kommt nur wieder, wenn der nächste Lauf erneut Fehler hat."}
|
||||
if aktion_id == "job-wiederholen":
|
||||
try:
|
||||
r = subprocess.run(["hermes", "cron", "run", aktion["job"]],
|
||||
|
||||
Reference in New Issue
Block a user