mirror of
https://github.com/Jeuners/Logpy-AgentOne.git
synced 2026-09-09 15:02:33 +02:00
feat: Log-Rotation fuer Rohlogs + Aufraeumen alter Verlauf-Archivkopien
Audit ergab: "Tag archivieren" sichert/leert nur verlauf.log. Die rohen stdout/stderr-Logs (telefon/autostart.log vom launchd-Watchdog net.dillenberg.fonagent, alle 5 Min; watcher.log/leitstand.log/monitor.log) wachsen unbegrenzt - autostart.log stand bei 523 KB/16595 Zeilen ohne jede Bereinigung. audit.log ist bewusst permanent (Compliance, unveraendert). starten.sh kuerzt diese vier Dateien jetzt ab 2 MB auf die letzten 2000 Zeilen (in-place, gleiches Inode) - laeuft ohnehin alle 5 Min per Watchdog. Redirects von > auf >> umgestellt (O_APPEND), damit die In-Place-Kuerzung fuer die noch laufenden Prozesse sicher ist (kein Datenverlust durch gecachte Schreib-Offsets). pipe.protokoll.raeume_archiv_auf() loescht verlauf-archiv/*.log aelter als 90 Tage - lief bisher unbegrenzt an. Eingehaengt in pipe.watch's ohnehin taeglichen Check (bisher nur fuer LOESCHFRIST_TAGE), jetzt unabhaengig davon. Getestet: Kuerz-Logik (3,8 MB -> 2000 Zeilen) und raeume_archiv_auf() (gezielt gealterte Testdatei geloescht, Rest unangetastet) isoliert verifiziert, echte Dateien nicht angefasst. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EbdWYnDtyMgxsq4eN1WnrQ
This commit is contained in:
parent
be11baf52b
commit
ab2bd949be
3 changed files with 54 additions and 8 deletions
|
|
@ -12,6 +12,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
@ -79,3 +80,26 @@ def archiviere_und_leere() -> Path | None:
|
||||||
return ziel
|
return ziel
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
ARCHIV_FRIST_TAGE = 90
|
||||||
|
|
||||||
|
|
||||||
|
def raeume_archiv_auf(tage: int = ARCHIV_FRIST_TAGE) -> int:
|
||||||
|
"""Löscht Verlauf-Archivkopien (nicht audit.log!) älter als `tage` Tage.
|
||||||
|
|
||||||
|
Ein neues verlauf_*.log entsteht bei jedem "Tag archivieren" - ohne
|
||||||
|
Aufräumen sammeln sich diese sonst unbegrenzt an. Wirft nie, gibt die
|
||||||
|
Anzahl gelöschter Dateien zurück."""
|
||||||
|
if not ARCHIV_ORDNER.is_dir():
|
||||||
|
return 0
|
||||||
|
grenze = time.time() - tage * 86400
|
||||||
|
geloescht = 0
|
||||||
|
for datei in ARCHIV_ORDNER.glob("verlauf_*.log"):
|
||||||
|
try:
|
||||||
|
if datei.stat().st_mtime < grenze:
|
||||||
|
datei.unlink()
|
||||||
|
geloescht += 1
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
return geloescht
|
||||||
|
|
|
||||||
|
|
@ -152,10 +152,18 @@ def main(argv: list[str] | None = None) -> int:
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
durchlauf(eingang)
|
durchlauf(eingang)
|
||||||
if config.LOESCHFRIST_TAGE and time.monotonic() - letzter_loeschlauf >= LOESCH_TAKT_S:
|
if time.monotonic() - letzter_loeschlauf >= LOESCH_TAKT_S:
|
||||||
anzahl = loeschen.laeuft()
|
if config.LOESCHFRIST_TAGE:
|
||||||
if anzahl:
|
anzahl = loeschen.laeuft()
|
||||||
print(f"🗑 {anzahl} Anruf(e) nach Aufbewahrungsfrist geloescht.")
|
if anzahl:
|
||||||
|
print(f"🗑 {anzahl} Anruf(e) nach Aufbewahrungsfrist geloescht.")
|
||||||
|
# Verlauf-Archivkopien (pipe.protokoll, "Tag archivieren")
|
||||||
|
# sammeln sich sonst unbegrenzt an - unabhaengig von
|
||||||
|
# LOESCHFRIST_TAGE, das nur Anrufe betrifft, nicht Log-Kopien.
|
||||||
|
archiv_geloescht = protokoll.raeume_archiv_auf()
|
||||||
|
if archiv_geloescht:
|
||||||
|
print(f"🗑 {archiv_geloescht} alte Verlauf-Archivkopie(n) geloescht "
|
||||||
|
f"(> {protokoll.ARCHIV_FRIST_TAGE} Tage).")
|
||||||
letzter_loeschlauf = time.monotonic()
|
letzter_loeschlauf = time.monotonic()
|
||||||
time.sleep(TAKT_S)
|
time.sleep(TAKT_S)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,20 @@ if [ -f .env ]; then
|
||||||
done < .env
|
done < .env
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Rohe Prozess-Logs (stdout/stderr von watcher/leitstand/monitor + die
|
||||||
|
# eigene Ausgabe hier, wenn per launchd-Watchdog alle 5 Min aufgerufen)
|
||||||
|
# wachsen sonst unbegrenzt - anders als verlauf.log (protokoll.kuerze(), nach
|
||||||
|
# jedem Anruf) und audit.log (bewusst permanent, siehe pipe/audit.py). Ab
|
||||||
|
# 2 MB auf die letzten 2000 Zeilen kuerzen, in-place (gleiches Inode) - sicher
|
||||||
|
# fuer >>-Redirects (O_APPEND springt bei jedem Schreiben ans Dateiende,
|
||||||
|
# unabhaengig vom vorherigen Offset).
|
||||||
|
LOG_GRENZE_BYTES=2000000
|
||||||
|
for log in telefon/autostart.log telefon/watcher.log telefon/leitstand.log telefon/monitor.log; do
|
||||||
|
if [ -f "$log" ] && [ "$(wc -c < "$log" 2>/dev/null || echo 0)" -gt "$LOG_GRENZE_BYTES" ]; then
|
||||||
|
tail -n 2000 "$log" > "$log.tmp" 2>/dev/null && cat "$log.tmp" > "$log" && rm -f "$log.tmp"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
fehler=0
|
fehler=0
|
||||||
melde() { printf ' %-38s %s\n' "$1" "$2"; }
|
melde() { printf ' %-38s %s\n' "$1" "$2"; }
|
||||||
|
|
||||||
|
|
@ -99,20 +113,20 @@ if [ "${status:-}" = "UP" ]; then
|
||||||
else
|
else
|
||||||
# nice 10: Transkription und Kategorisierung dürfen warten, ein laufendes
|
# nice 10: Transkription und Kategorisierung dürfen warten, ein laufendes
|
||||||
# Telefonat nicht. Auf 16 GB RAM konkurrieren beide sonst um die Maschine.
|
# Telefonat nicht. Auf 16 GB RAM konkurrieren beide sonst um die Maschine.
|
||||||
nohup nice -n 10 python3 -u -m pipe.watch > telefon/watcher.log 2>&1 &
|
nohup nice -n 10 python3 -u -m pipe.watch >> telefon/watcher.log 2>&1 &
|
||||||
echo "Verarbeitung gestartet (Log: telefon/watcher.log)"
|
echo "Verarbeitung gestartet (Log: telefon/watcher.log)"
|
||||||
fi
|
fi
|
||||||
if pgrep -f "[p]ipe.server" >/dev/null; then
|
if pgrep -f "[p]ipe.server" >/dev/null; then
|
||||||
echo "Leitstand laeuft bereits."
|
echo "Leitstand laeuft bereits."
|
||||||
else
|
else
|
||||||
nohup python3 -u -m pipe.server > telefon/leitstand.log 2>&1 &
|
nohup python3 -u -m pipe.server >> telefon/leitstand.log 2>&1 &
|
||||||
sleep 2
|
sleep 2
|
||||||
head -1 telefon/leitstand.log
|
tail -1 telefon/leitstand.log
|
||||||
fi
|
fi
|
||||||
if pgrep -f "[p]ipe.monitor" >/dev/null; then
|
if pgrep -f "[p]ipe.monitor" >/dev/null; then
|
||||||
echo "Stoerungswache laeuft bereits."
|
echo "Stoerungswache laeuft bereits."
|
||||||
else
|
else
|
||||||
nohup python3 -u -m pipe.monitor > telefon/monitor.log 2>&1 &
|
nohup python3 -u -m pipe.monitor >> telefon/monitor.log 2>&1 &
|
||||||
echo "Stoerungswache gestartet (Log: telefon/monitor.log)"
|
echo "Stoerungswache gestartet (Log: telefon/monitor.log)"
|
||||||
fi
|
fi
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue