diff --git a/.gitignore b/.gitignore index 7cb6e98..41befde 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,17 @@ skoda.conf *.conf secrets.conf +# Ausnahme von der Zeile darueber: hier stehen keine Zugangsdaten, sondern +# die Rotationsregeln, und die gehoeren zum Betrieb wie die Startskripte. +!logrotate.conf + # Protokolle. wattpilotshell.log ist allein 329 MB gross, die Logs machen # 93 Prozent des Verzeichnisses aus. *.log +# Die rotierten Staende dazu - *.log.1, *.log.2.gz und so fort. +*.log.* +# Merkzettel von logrotate: wann welche Datei zuletzt dran war. +logrotate.state # Python __pycache__/ diff --git a/autoActions/README.md b/autoActions/README.md index 9e819e0..8c680c1 100644 --- a/autoActions/README.md +++ b/autoActions/README.md @@ -256,6 +256,14 @@ dieselbe Client-Kennung benutzen. Genau davor schützt das Beenden am Anfang. Ausgabe landet in `autoActions.log` neben `solarOutput.log`. `SIGTERM` fängt der Runner ab und fährt geordnet herunter. +Nachzulesen ist beides im Dashboard unter **Protokolle** — die Seite liest die +Dateien direkt, filterbar nach Text und Level. Klein gehalten werden sie von +`logs_rotieren.sh` samt `logrotate.conf` eine Ebene höher: täglich, vierzehn +Stände, alles über 20 MB sofort. Weil die Prozesse monatelang durchlaufen, +arbeitet die Rotation mit `copytruncate` — deshalb leiten die Startskripte mit +`>>` um und nicht mehr mit `&>`. Wer das zurückdreht, bekommt nach der +nächsten Rotation eine Logdatei, die vorn aus Nullbytes besteht. + `fetch_calendar.py` gehört einmal jährlich in den Cron: ``` diff --git a/logrotate.conf b/logrotate.conf new file mode 100644 index 0000000..7671c37 --- /dev/null +++ b/logrotate.conf @@ -0,0 +1,42 @@ +# Rotation der Logdateien des SolarManagers. +# +# Aufgerufen wird das ueber logs_rotieren.sh, einmal taeglich aus dem +# Aufgabenplaner. Nicht in /etc/logrotate.d abgelegt: das ist DSM-Gebiet und +# waere beim naechsten Systemupdate weg. Hier steht es neben den Prozessen, +# zu denen es gehoert, und liegt im selben Repository. +# +# copytruncate ist der Kern der Sache. Die Prozesse laufen monatelang durch +# und halten ihre Logdatei offen; niemand will sie fuer eine Rotation neu +# starten. Also wird der Inhalt weggeschrieben und die Datei geleert, statt +# sie umzubenennen - der Prozess merkt nichts davon. Voraussetzung ist, dass +# die Startskripte mit ">>" umleiten und nicht mit "&>", sonst schreibt der +# Prozess nach dem Leeren an seiner alten Stelle weiter und die Datei +# bekommt ein Loch aus Nullbytes. Genau deshalb wurde das dort umgestellt. +# +# Der Preis von copytruncate sind die Zeilen, die zwischen Kopieren und +# Leeren hereinkommen - die gehen verloren. Bei einem Betriebslog ist das +# der guenstigere Handel. + +/volume1/homes/wagner/SolarManager/solarOutput.log +/volume1/homes/wagner/SolarManager/autoActions.log +/volume1/homes/wagner/SolarManager/wattpilotshell.log +/volume1/homes/wagner/SolarManager/wsMQTTbridge.log +/volume1/homes/wagner/SolarManager/wecker.log +{ + daily + # Zwei Wochen zurueck. Weiter zurueck hat noch nie jemand gesucht, und + # was aelter ist, steht ohnehin als Messwert in der Datenbank. + rotate 14 + # Zusaetzlich zur Tagesgrenze: was ueber 20 MB geht, wird sofort + # rotiert. Sonst koennte ein Prozess, der in eine Fehlerschleife + # geraet, an einem einzigen Tag das Volume fuellen. + maxsize 20M + compress + # Eine leere Datei zu rotieren bringt nichts ausser vierzehn leeren + # Archiven - der Wecker meldet an den meisten Tagen gar nichts. + notifempty + # Fehlt eine Datei, ist das kein Fehler: nicht jeder Prozess laeuft + # auf jedem System. + missingok + copytruncate +} diff --git a/logs_rotieren.sh b/logs_rotieren.sh new file mode 100755 index 0000000..a389852 --- /dev/null +++ b/logs_rotieren.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Rotiert die Logdateien des SolarManagers. +# +# Gehoert einmal taeglich in den Aufgabenplaner (Benutzer wagner genuegt, +# root ist nicht noetig - alle Dateien gehoeren wagner). Die Regeln stehen in +# logrotate.conf daneben. +# +# Der Zustand kommt ausdruecklich nicht aus /var/lib/logrotate: dort liegt +# der von DSM, und ein zweiter Aufrufer haette sich dort mit dem System in +# die Quere gebracht. Die eigene Datei bleibt unter unserer Kontrolle und +# ist bei Bedarf einfach zu loeschen - dann faengt die Rotation von vorn an. +# +# Ein Lauf dauert ein bis zwei Minuten, auch wenn nichts zu tun ist. Das +# liegt nicht an uns: Synologys logrotate zaehlt bei jedem Start erst den +# Platzverbrauch unter /var/log zusammen und stolpert dabei ueber Ordner, +# die wagner nicht lesen darf. Die Meldungen "Permission denied" von /bin/du +# sind harmlos und gehoeren dazu. +# +# ./logs_rotieren.sh normaler Lauf +# ./logs_rotieren.sh -f sofort rotieren, auch wenn noch nichts faellig +# ./logs_rotieren.sh -d nur zeigen, was passieren wuerde + +BASIS="/volume1/homes/wagner/SolarManager" + +exec /usr/bin/logrotate \ + --state "$BASIS/logrotate.state" \ + "$@" \ + "$BASIS/logrotate.conf" diff --git a/startMQTTbridge.sh b/startMQTTbridge.sh old mode 100644 new mode 100755 index 59ccd09..62b69da --- a/startMQTTbridge.sh +++ b/startMQTTbridge.sh @@ -16,4 +16,8 @@ fi # Start the script cd "/volume1/homes/wagner/SolarManager/" -/usr/bin/python3 "$SCRIPT_NAME" &> "$LOG_FILE" & \ No newline at end of file +# Angehaengt statt ueberschrieben: logrotate leert diese Datei mit +# copytruncate, waehrend der Prozess sie offen haelt. Ohne Anhaengemodus +# schriebe er danach an seiner alten Stelle weiter, und die Datei bekaeme ein +# Loch aus Nullbytes in der Groesse des bisherigen Inhalts. +/usr/bin/python3 "$SCRIPT_NAME" >> "$LOG_FILE" 2>&1 & \ No newline at end of file diff --git a/startSolarServer.sh b/startSolarServer.sh old mode 100644 new mode 100755 index fcbeb0f..c8e7b46 --- a/startSolarServer.sh +++ b/startSolarServer.sh @@ -46,7 +46,13 @@ beenden() { starte() { beenden "$1" echo "Starte $1, Ausgabe nach $2" - "$PYTHON" "$1" &> "$2" & + # Angehaengt, nicht ueberschrieben. Zwei Gruende: nach einem Neustart + # will man sehen, warum der alte Lauf aufgehoert hat, und logrotate + # arbeitet hier mit copytruncate - es leert die Datei, waehrend der + # Prozess sie offen haelt. Beim Ueberschreiben stuende dessen + # Schreibmarke danach weit hinten, und die Datei bekaeme ein Loch aus + # Nullbytes in der Groesse des bisherigen Inhalts. + "$PYTHON" "$1" >> "$2" 2>&1 & } starte "solarManager.py" "solarOutput.log" diff --git a/startWattpilotMQTT.sh b/startWattpilotMQTT.sh old mode 100644 new mode 100755 index b4f716a..a7f73fa --- a/startWattpilotMQTT.sh +++ b/startWattpilotMQTT.sh @@ -42,4 +42,10 @@ fi # Start the script cd "$BASIS" -/var/services/homes/wagner/.local/bin/wattpilotshell server &> "$LOG_FILE" & +# Angehaengt statt ueberschrieben: logrotate leert diese Datei mit +# copytruncate, waehrend der Prozess sie offen haelt. Ohne Anhaengemodus +# schriebe er danach an seiner alten Stelle weiter, und die Datei bekaeme ein +# Loch aus Nullbytes in der Groesse des bisherigen Inhalts. Bei dieser Datei +# faellt das besonders ins Gewicht - die wattpilotshell meldet einen +# Verbindungsfehler im Sekundentakt und hatte es so auf 329 MB gebracht. +/var/services/homes/wagner/.local/bin/wattpilotshell server >> "$LOG_FILE" 2>&1 & diff --git a/startWecker.sh b/startWecker.sh old mode 100644 new mode 100755 index 0652294..94e11df --- a/startWecker.sh +++ b/startWecker.sh @@ -16,4 +16,9 @@ fi # Start the script cd "/volume1/homes/wagner/SolarManager/" -/usr/bin/python3 "$SCRIPT_NAME" &> "$LOG_FILE" & \ No newline at end of file +# Angehaengt statt ueberschrieben. Dieses Skript laeuft jede Nacht um drei, +# und mit "&>" war die Datei danach jedes Mal leer - was der Wecker am +# Vortag gemeldet hat, war morgens nicht mehr nachzulesen. Ausserdem braucht +# logrotate den Anhaengemodus: es leert die Datei mit copytruncate, waehrend +# der Prozess sie offen haelt. +/usr/bin/python3 "$SCRIPT_NAME" >> "$LOG_FILE" 2>&1 & \ No newline at end of file