Wie können Sie dazu führen, dass nicht erfasste Ausnahmen über das logging
Modul ausgegeben werden und nicht über stderr
?
Mir ist klar, dass der beste Weg, dies zu tun, wäre:
try:
raise Exception, 'Throwing a boring exception'
except Exception, e:
logging.exception(e)
Aber meine Situation ist so, dass es wirklich schön wäre, wenn logging.exception(...)
sie automatisch aufgerufen würden, wenn eine Ausnahme nicht abgefangen wird.
python
logging
exception-handling
Jacob Marmor
quelle
quelle
Antworten:
Wie Ned betonte,
sys.excepthook
wird jedes Mal aufgerufen, wenn eine Ausnahme ausgelöst und nicht erfasst wird. Die praktische Implikation davon ist, dass Sie in Ihrem Code das Standardverhalten überschreiben können, umsys.excepthook
zu tun, was Sie wollen (einschließlich der Verwendunglogging.exception
).Als Strohmann Beispiel:
Überschreiben
sys.excepthook
:Übernehmen Sie einen offensichtlichen Syntaxfehler (lassen Sie den Doppelpunkt weg) und erhalten Sie benutzerdefinierte Fehlerinformationen zurück:
Weitere Informationen zu
sys.excepthook
: http://docs.python.org/library/sys.html#sys.excepthookquelle
type
als Funktionsargument verwenden, obwohl IDEs sich über das Ausblenden des Globalen beschwerentype
(ähnlich wie bei der Verwendungvar self = this
in Javascript). Es spielt keine Rolle, es sei denn, Sie müssen auf dastype
Objekt in Ihrer Funktion zugreifen. In diesem Fall können Sietype_
stattdessen als Argument verwenden.sys.excepthook
NICHT aufgerufen, wenn eine Ausnahme "ausgelöst" wird. Es wird aufgerufen, wenn das Programm aufgrund einer nicht erfassten Ausnahme beendet wird, die nur einmal auftreten kann.Hier ist ein komplettes kleines Beispiel, das auch einige andere Tricks enthält:
Ignorieren Sie KeyboardInterrupt, damit ein Konsolen-Python-Programm mit Strg + C beendet werden kann.
Verlassen Sie sich beim Formatieren der Ausnahme vollständig auf das Protokollierungsmodul von Python.
Verwenden Sie einen benutzerdefinierten Logger mit einem Beispielhandler. Dieser ändert die nicht behandelte Ausnahme so, dass sie zu stdout und nicht zu stderr wechselt. Sie können dem Logger-Objekt jedoch alle Arten von Handlern in demselben Stil hinzufügen.
quelle
logger.critical()
innerhalb des Excepthook-Handlers verwenden, da eine nicht erfasste Ausnahme ziemlich kritisch ist, würde ich sagen.logging.basicConfig(level=logging.DEBUG, filename="debug.log", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
aber nicht geholfen.Die Methode
sys.excepthook
wird aufgerufen, wenn eine Ausnahme nicht erfasst wird: http://docs.python.org/library/sys.html#sys.excepthookquelle
type
die Instanz aufrufen ?Warum nicht:
Hier ist die Ausgabe mit
sys.excepthook
wie oben gezeigt:Hier ist die Ausgabe mit dem
sys.excepthook
auskommentierten:Der einzige Unterschied ist, dass der erstere
ERROR:root:Unhandled exception:
am Anfang der ersten Zeile steht.quelle
sys.stderr
.Um auf Jacindas Antwort aufzubauen, aber ein Logger-Objekt zu verwenden:
quelle
functools.partial()
anstelle von Lambda zu verwenden. Siehe: docs.python.org/2/library/functools.html#functools.partialSchließen Sie Ihren App-Eintrag in einen
try...except
Block ein , damit Sie alle nicht erfassten Ausnahmen abfangen und protokollieren (und möglicherweise erneut auslösen) können. ZB statt:Mach das:
quelle
Vielleicht könnten Sie oben in einem Modul etwas tun, das stderr in eine Datei umleitet, und diese Datei dann unten protokollieren
quelle
Obwohl mir die Antwort von @ gnu_lorien einen guten Ausgangspunkt gab, stürzt mein Programm bei der ersten Ausnahme ab.
Ich kam mit einer angepassten (und / oder) verbesserten Lösung, die Ausnahmen von Funktionen, mit denen dekoriert ist, stillschweigend protokolliert
@handle_error
.quelle
Um die Frage von Herrn Zeus zu beantworten, die im Kommentarbereich der akzeptierten Antwort besprochen wurde, verwende ich diese, um nicht erfasste Ausnahmen in einer interaktiven Konsole zu protokollieren (getestet mit PyCharm 2018-2019). Ich fand heraus,
sys.excepthook
dass es in einer Python-Shell nicht funktioniert, also schaute ich tiefer und stellte fest, dass ichsys.exc_info
stattdessen verwenden könnte. Jedochsys.exc_info
nimmt im Gegensatz zu keine Argumentesys.excepthook
zu, dass drei Argumente annimmt.Hier benutze ich beide
sys.excepthook
undsys.exc_info
, um beide Ausnahmen in einer interaktiven Konsole und einem Skript mit einer Wrapper-Funktion zu protokollieren. Um beiden Funktionen eine Hook-Funktion zuzuweisen, habe ich zwei verschiedene Schnittstellen, je nachdem, ob Argumente angegeben werden oder nicht.Hier ist der Code:
Das Protokollierungssetup finden Sie in der Antwort von gnu_lorien.
quelle
In meinem Fall (mit
python 3
) bei Verwendung von @Jacindas Antwort wurde der Inhalt des Tracebacks nicht gedruckt. Stattdessen wird nur das Objekt selbst gedruckt :<traceback object at 0x7f90299b7b90>
.Stattdessen mache ich:
quelle