Hallo!
Sorry, Python Dummy!
Gibt es irgendeine Möglichkeit beim ALLEN möglichen Absturzursachen eines Python-Progs mir eine Fehlermail senden zu lassen?
Wie das mit der Fehlermail durch Aufruf einer entsprechenden Routine im gleichen Pythonprog geht, weiß ich, aber ich müßte dazu try..except an vielen Stellen einbauen. Oder kann / sollte ich dazu bei Absturz ein ANDERES Prog aufrufen?
Gruß, wonk
Abfangen ALLER Fehler
- __blackjack__
- User
- Beiträge: 14268
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@wonk: Innerhalb des Programms selbst ist das nicht möglich. Da kann man nur am Einstiegspunkt einen ``try``/``except``-Block setzen, der alle Ausnahmen behandelt die bis dort hin durchkommen. Aber man kann keine echten Abstürze in einem Programm behandeln, das ja gerade abgestürzt ist. Das ist als wenn Du jemandem sagst, sag bitte Bescheid wenn Du gestorben bist. 
Aus dem gleichen Grund kannst Du bei Absturz kein anderes Programm aufrufen. Was man machen kann ist das Programm von Anfang an von einem anderen Programm aus aufzurufen und dort darauf reagieren wie Programm endet. Das ist plattformabhängig ob und wie genau man welche Ursachen ermitteln kann.
Aus dem gleichen Grund kannst Du bei Absturz kein anderes Programm aufrufen. Was man machen kann ist das Programm von Anfang an von einem anderen Programm aus aufzurufen und dort darauf reagieren wie Programm endet. Das ist plattformabhängig ob und wie genau man welche Ursachen ermitteln kann.
“Programming is partially an artform and, like artists, programmers will do it even if they don't get money.” — Linus Torvalds
- DeaD_EyE
- User
- Beiträge: 1309
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Exceptions haben die Eigenschaft, dass die nach oben poppen, wenn sie nicht abgefangen werden. Ausnahme sind Threads.
In main() kannst die Exception von func1() abfangen.
In der REPL sieht das dann so aus:
Man sollte aber nicht den Fehler machen und Exceptions abfangen und nichts ausgeben. Dann braucht man für die Fehlersuche länger, da dann die ursprünglichen Probleme nicht angezeigt werden, das aber zu Folgeproblemen führt.
Code: Alles auswählen
def func1():
1 / 0
def func2():
func1()
def main():
func2()In main() kannst die Exception von func1() abfangen.
In der REPL sieht das dann so aus:
Code: Alles auswählen
Python 3.14.2 (tags/v3.14.2:df79316, Dec 5 2025, 17:18:21) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
... def func1():
... 1 / 0
...
... def func2():
... func1()
...
...
... def main():
... func2()
...
>>> main()
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
main()
~~~~^^
File "<python-input-0>", line 10, in main
func2()
~~~~~^^
File "<python-input-0>", line 6, in func2
func1()
~~~~~^^
File "<python-input-0>", line 3, in func1
1 / 0
~~^~~
ZeroDivisionError: division by zero
>>> try:
... main()
... except ZeroDivisionError:
... print("Division durch 0")
...
Division durch 0
>>>
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
- noisefloor
- User
- Beiträge: 4276
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
in welchem Kontext brauchst du das denn? Eine alternative zum selber implementieren ist, sowas wie Sentry zu benutzen, dass genau da drauf spezialisiert ist. Gibt es auch in einer kostenfreien Variante, habe ich selber allerdings auch noch nicht aktiv genutzt.
Gruß, noisefloor
in welchem Kontext brauchst du das denn? Eine alternative zum selber implementieren ist, sowas wie Sentry zu benutzen, dass genau da drauf spezialisiert ist. Gibt es auch in einer kostenfreien Variante, habe ich selber allerdings auch noch nicht aktiv genutzt.
Gruß, noisefloor
Hallo,
es ist eine Heizungssteuerung, die rund um die Uhr läuft.
Der wesenliche Teil ist eine Schleife, in der Temperatursensoren abgefragt werden, Werte in eine Datenbank geschrieben und gelesen werden, und ein Ausgang des Raspi gesetzt wird.
Bei einem Absturz wird es bei mir kalt, ich merke das oft erst Stunden später und brauche dann lange zum Wiederaufheizen.
Gruß, wonk
es ist eine Heizungssteuerung, die rund um die Uhr läuft.
Der wesenliche Teil ist eine Schleife, in der Temperatursensoren abgefragt werden, Werte in eine Datenbank geschrieben und gelesen werden, und ein Ausgang des Raspi gesetzt wird.
Bei einem Absturz wird es bei mir kalt, ich merke das oft erst Stunden später und brauche dann lange zum Wiederaufheizen.
Gruß, wonk
Gruss, wonk
Wenn das öfters vor kommt, dann würde ich mich erst mal um ein sauberes logging kümmern und wenn es dann immer die gleiche Ursache ist, die den Service zum abstürzen bringt, dann genau diese eine Ursache beheben.
Im Vorfeld alles auf Verdacht mit `try`/`except` zu versehen, sieht für mich nicht nach einem robusten Programm aus.
Gerne kannst du hier den Code auch zeigen, dann wirst du bestimmt ein paar Ratschläge bekommen.
Grüße
Dennis
Im Vorfeld alles auf Verdacht mit `try`/`except` zu versehen, sieht für mich nicht nach einem robusten Programm aus.
Gerne kannst du hier den Code auch zeigen, dann wirst du bestimmt ein paar Ratschläge bekommen.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Nur in die *.serviceSirius3 hat geschrieben: Samstag 17. Januar 2026, 11:30 Dafür benutzt man systemd, dass der abgestürzte Service automatisch neu gestartet wird. eintragen
Restart= always
RestartSec=10s eintragen?
Kann ich den Service dann noch mit systemctl stoppen?
Das Prog stüzt nicht häufig ab, aber der Absturz ist sehr unschön. Ich habe ein Log und kann die Fehlermeldung nachher sehen und den Fehler beheben. Das Listing ist länglich.
Gruß, wonk
Gruss, wonk
- noisefloor
- User
- Beiträge: 4276
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
nee, musst du nicht. Das geht auch mit systemd. system kennt für den `Unit` Abschnitt die Direktive OnFailure, mit der du eine andere Unit ausführen kannst - wie eine Mail schicken. Alternative kannst du in der Service Unit im Abschnitt `Service` die Direktive `ExecStartPost` nutzen, mit der du z.B. eine Mail verschicken kannst, wenn die Unit erfolgreich gestartet wurde. Dann kriegst du halt eine Mail, wenn die Unit regulär startet, z.B. bei einem geplanten Neustart des Systems - aber halt auch bei jedem anderen (Neu-) Start der Unit.
Wenn du Fehler mit `try... except` abfängst / wegbügelst, landen die halt auch _nicht_ im systemd Log und die findest sie nicht. Von daher sollte man beim robuster machen des Skripts eher wenig Fehler abfangen, um an den Kern der Fehlerursache zu kommen.
Gruß, noisefloor
nee, musst du nicht. Das geht auch mit systemd. system kennt für den `Unit` Abschnitt die Direktive OnFailure, mit der du eine andere Unit ausführen kannst - wie eine Mail schicken. Alternative kannst du in der Service Unit im Abschnitt `Service` die Direktive `ExecStartPost` nutzen, mit der du z.B. eine Mail verschicken kannst, wenn die Unit erfolgreich gestartet wurde. Dann kriegst du halt eine Mail, wenn die Unit regulär startet, z.B. bei einem geplanten Neustart des Systems - aber halt auch bei jedem anderen (Neu-) Start der Unit.
Wenn du Fehler mit `try... except` abfängst / wegbügelst, landen die halt auch _nicht_ im systemd Log und die findest sie nicht. Von daher sollte man beim robuster machen des Skripts eher wenig Fehler abfangen, um an den Kern der Fehlerursache zu kommen.
Gruß, noisefloor
Hallo!
Das muss ich mal alles mit provozierten Abstürzen testen.
Gruß, wonk
Das wäre natürlich Klasse. Aber was heißt hier "eine andere unit ausführen"? Kann ich damit ein gesondertes Python-Prog aufrufen, das die Fehlermail sendet?Das geht auch mit systemd. system kennt für den `Unit` Abschnitt die Direktive OnFailure, mit der du eine andere Unit ausführen kannst - wie eine Mail schicken.
Das muss ich mal alles mit provozierten Abstürzen testen.
Gruß, wonk
Gruss, wonk
- noisefloor
- User
- Beiträge: 4276
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Genau. Eine andere (Service) Unit ausführen heißt genau das: eine anderes Skript / Python Program etc. aufrufen, nur halt über eine Service Unit. Unit deshalb, weil man dann z.B. auch Abhängigkeiten definieren kann. Wenn du z.B. eine Mail versenden willst, sollte das `network-online.target` erreicht sein (was es bei laufendem System i.d.R. ist).Aber was heißt hier "eine andere unit ausführen"? Kann ich damit ein gesondertes Python-Prog aufrufen, das die Fehlermail sendet?
Gruß, noisefloor
Hallo,
ich habe es jetzt mal getestet, klappt leider nicht.
Ich habe eine "fritz.service" mit folgendem Inhalt:
In fritz.py tritt etwa 3s nach dem Start ein Divison/ 0 Fehler auf, sie stüzt ab, entsprechende Ausgaben sehe ich im Log.
fehlermail.py versendet eine mail, wenn ich sie einzeln starte. Sie wird aber nicht aus der *.service gestartet. Besitzer der Dateien ist pi, der *.service root, es gibt jeweils alle Rechte.
Woran kann das liegen?
Gruss, wonk
ich habe es jetzt mal getestet, klappt leider nicht.
Ich habe eine "fritz.service" mit folgendem Inhalt:
Code: Alles auswählen
[Unit]
Description=fritz.py
After=syslog.target network.target ntp.service rc-local.service
OnFailure=/home/pi/fehlermail.py
#OnFailure='/home/pi/python3 fehlermail.py' alternativ
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/
ExecStart=/home/pi/fritz.py
StandardOutput=file:/home/pi/zaehler.log
#StandardOutput=null
[Install]
WantedBy=multi-user.target
fehlermail.py versendet eine mail, wenn ich sie einzeln starte. Sie wird aber nicht aus der *.service gestartet. Besitzer der Dateien ist pi, der *.service root, es gibt jeweils alle Rechte.
Woran kann das liegen?
Gruss, wonk
Gruss, wonk
- noisefloor
- User
- Beiträge: 4276
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
`OnFailure` startet eine andere Unit, _kein_ Skript. Das kann so also auf keinen Fall funktionieren. Du musst hat das Python-Skript zum Mailen in eine Unit packen, die dann 1x gestartet wird und so konfiguriert ist, dass sie beendet ist, wenn das darin gestartete Skript durch ist.
Gruß, noisefloor
`OnFailure` startet eine andere Unit, _kein_ Skript. Das kann so also auf keinen Fall funktionieren. Du musst hat das Python-Skript zum Mailen in eine Unit packen, die dann 1x gestartet wird und so konfiguriert ist, dass sie beendet ist, wenn das darin gestartete Skript durch ist.
Gruß, noisefloor
