From 48f25cf2a7b6a9aced2311113aa6dca4dd5812b6 Mon Sep 17 00:00:00 2001 From: Dima Gerasimov Date: Sun, 15 Jan 2023 01:23:36 +0100 Subject: [PATCH] core/logging: set exc_info during logging automatically --- src/promnesia/__main__.py | 2 +- src/promnesia/logging.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/promnesia/__main__.py b/src/promnesia/__main__.py index cef5e8ba..4d140d36 100644 --- a/src/promnesia/__main__.py +++ b/src/promnesia/__main__.py @@ -106,7 +106,7 @@ def do_index( if len(errors) > 0: logger.error('%d errors, printing them out:', len(errors)) for e in errors: - logger.error(' %s', e, exc_info=e) + logger.exception(e) logger.error('%d errors, exit code 1', len(errors)) sys.exit(1) diff --git a/src/promnesia/logging.py b/src/promnesia/logging.py index 6a09eea5..df5af4c4 100755 --- a/src/promnesia/logging.py +++ b/src/promnesia/logging.py @@ -72,6 +72,7 @@ def setup_logger(logger: logging.Logger, level: LevelIsh) -> None: formatter = logging.Formatter(fmt=FORMAT_NOCOLOR, datefmt=DATEFMT) use_logzero = False + logger.addFilter(AddExceptionTraceback()) if use_logzero and not COLLAPSE_DEBUG_LOGS: # all set, nothing to do # 'simple' setup logzero.setup_logger(logger.name, level=lvl, formatter=formatter) @@ -104,6 +105,24 @@ def isEnabledFor_lazyinit(*args, logger=logger, orig=logger.isEnabledFor, **kwar return cast(LazyLogger, logger) +# by default, logging.exception isn't logging traceback +# which is a bit annoying since we have to +# also see https://stackoverflow.com/questions/75121925/why-doesnt-python-logging-exception-method-log-traceback-by-default +# tod also amend by post about defensive error handling? +class AddExceptionTraceback(logging.Filter): + def filter(self, record): + s = super().filter(record) + if s is False: + return False + if record.levelname == 'ERROR': + exc = record.msg + if isinstance(exc, BaseException): + if record.exc_info is None or record.exc_info == (None, None, None): + exc_info = (type(exc), exc, exc.__traceback__) + record.exc_info = exc_info + return s + + # todo also save full log in a file? class CollapseDebugHandler(logging.StreamHandler): '''