Package: logging-exceptions
Source on GitHubInstallationUse setup.py :pythonsetup.pyinstallWarningThis module modifiessys.excepthookwhen it is imported!UsageSelf-logging exceptionsAttach a log message to an exception:importloggingimportlogging_exceptionsasexloge=ValueError("Wrong value")logger=logging.getLogger(__name__)withexlog.log_to_exception(logger,e):logger.critical("This is a%slog mressage","long")raisee# The exception can also be raised inside the with statementIf the error is not caught, the log message will be displayed upon program
termination.Catch the error and display the log message at a costum log-level:importlogging_exceptionsasexlogimportloggingtry:e=ValueError("Wrong value")logger=logging.getLogger(__name__)withexlog.log_to_exception(logger,e):logger.critical("This is a%slog mressage","long")raiseeexceptValueErroraserr:exlog.log(err,level=logging.DEBUG,with_stacktrace=False)Here,exlog.logis a synonym forexlog.log_exceptionLogging from a different function name and line numberThe code in log_exception calls the_logfunction of a Logger object.
To avoid recording the function name and line number oflog_to_exception,logging_exceptioncallslogging.setLoggerClass(ExlogLogger)to set the
class for all loggers created after import oflogging_exceptiontoExlogLogger.ExlogLoggeris a subclass oflogging.Loggerdefined by this module. It
overridesfindCallerto have more control over the recorded caller.
In addition to ignoring functions defined insidelogging_exceptions,ExlogLoggerclasses have the public attributeignored_functions.By adding function names toignored_functions, it is possible to record
matching function’s parents instead of matching functions as the caller.In particular, the context managerlogging_exceptions.log_at_callercan be used
in helper functions to temporarily update a logger’signored_functionsin order to record a function’s caller instead of the function.The following code will emit a log message with the function name set tofoo, nothelper_function:importlogging_exceptionsasexloglogger=logging.get_logger(__name__)defhelper_function():withexlog.log_at_caller(logger):logger.log("This is a log message")deffoo():helper_function()Commandline convenience functionsThe following convenience functions are not directly related to exceptions,
but useful if you use argparse.Add the ‘–verbose’, ‘–debug’ and ‘–quiet’ options to an
argparse.Argumentparser instance.importargparseimportlogging_exceptionsasexlogparser=argparse.ArgumentParser("Some help text")exlog.update_parser(parser)args=parser.parse_args()logging.basicConfig()# The following call updates the log levels of the root logger# and potential some other loggers.exlog.config_from_args(args)Now the script can be used from the commandline like this:# Set the log-level for the loggers with the names `path.to.module1`
# and `path.to.module2` to DEBUG.pythonscript.py--debugpath.to.module1,path.to.module2ExamplesSee the file ‘logging_exceptions_examples.py’Comparison to logging.handlers.MemoryHandlerThe logging.handlers module contains a handler for a similar purpose: The MemoryHandler.
It buffers log messages and only emits them, if a log record of severity error or above is encountered.
I will quickly explain the differences between MemoryHandler and my module:MemoryHandler is great if you know that an event of severity ERROR may occur
in the future (typically in the same function) and you want to prepare for
this potential exception. Typically, you know the scope for which the exceptions
have to be buffered and you know when the buffered exceptions are no longer needed and can be discarded.While for MemoryHandler the error condition is rather unspecific, the scope in
which we have to decide between discarding and emitting the log messages is well
known.Thelog_to_exceptiondecorator, on the other hand, is useful if the exception
is well specified (it is already created/ caught), but the the scope in which
the exception may or may not be caught is unspecified. Examples would be
library functions that raise an error.A typical example would be the following:importloggingfromlogging_exceptionsimportlog_to_exception# Whoever calls public_function may want to catch the ValueError and hide# the log messages or change their level to logging.DEBUGdefpublic_function():logger=logging.getLogger(__name__)a=some_complex_calculation(12)try:some_function(a)exceptValueErrorase:withlog_to_exception(logger,e):log.error("While calling `some_function` with%s, ""which is result of `some_complex_calculation`(%d),"" an error occurred",a,12)raiseCompatibilityCompatible with python 2.7 and python 3