Gibt es eine einfache Möglichkeit, die Protokollierung eines Ausnahme-Stack-Trace in Python 3 zu deaktivieren, entweder in a Handler
oder Formatter
?
Ich brauche den Stack-Trace in einem anderen Handler
, also ist das Setzen exc_info=False
von, im Aufruf von Logger
nicht möglich. Gibt es einen einfacheren Weg, als nur meinen eigenen zu definieren Formatter
?
Lösung des Problems
Die einfachste Option zum Deaktivieren der Traceback-Ausgabe pro Handler besteht darin, eine benutzerdefinierte logging.Filter
Unterklasse hinzuzufügen, die das Datensatzobjekt ändert (anstatt Datensätze herauszufiltern).
Der Filter muss einfach exc_info
auf Datensätze gesetzt werden auf None
:
class TracebackInfoFilter(logging.Filter):
"""Clear or restore the exception on log records"""
def __init__(self, clear=True):
self.clear = clear
def filter(self, record):
if self.clear:
record._exc_info_hidden, record.exc_info = record.exc_info, None
# clear the exception traceback text cache, if created.
record.exc_text = None
elif hasattr(record, "_exc_info_hidden"):
record.exc_info = record._exc_info_hidden
del record._exc_info_hidden
return True
und fügen Sie diesen Filter zu Ihrem Handler hinzu:
# do not display tracebacks in messages handled with this handler,
# by setting the traceback cache to a non-empty string:
handler_with_no_tracebacks.addFilter(TracebackInfoFilter())
Handler kopieren jedoch keine Protokolldatensätze, und alle anderen Handler, denen später derselbe Protokolldatensatz übergeben wird, ignorieren ebenfalls die Formatierung des Tracebacks. Sie müssen also auch alle anderen Handler konfigurieren, um die Informationen erneut wiederherzustellen:
for handler in logger.handlers:
if not any(isinstance(f, TracebackInfoFilter) for f in handler.filters):
handler.addFilter(TracebackInfoFilter(clear=False))
Wenn jemand alle Traceback-Ausgaben überall deaktivieren möchte, dann wird es vielleicht mühsam, allen Handlern oder Loggern einen benutzerdefinierten Filter hinzuzufügen. In diesem Fall besteht eine weitere Möglichkeit darin, eine benutzerdefinierte Record Factory mit der logging.setLogRecordFactory()
Funktion zu registrieren; Setzen Sie einfach das exc_info
Attribut für Datensätze auf None
, bedingungslos:
record_factory = logging.getLogRecordFactory()
def clear_exc_text(*args, **kwargs):
record = record_factory(*args, **kwargs)
record.exc_info = None
return record
logging.setLogRecordFactory(clear_exc_text)
Beachten Sie, dass die Standardfabrik nur die logging.LogRecord
Klasse ist, aber die obige Funktion tut ihr Bestes, um mit jeder bereits festgelegten benutzerdefinierten Fabrik zu arbeiten.
Natürlich können Sie auch Ihre eigene Handler
Unterklasse erstellen, in der Handler.handle()
das Attribut gesetzt und gelöscht exc_info
wird:
class NoTracebackHandler(logging.Handler):
def handle(self, record):
info, cache = record.exc_info, record.exc_text
record.exc_info, record.exc_text = None, None
try:
super().handle(record)
finally:
record.exc_info = info
record.exc_text = cache
Keine Kommentare:
Kommentar veröffentlichen