Skip to main content

Add-ons for the logging standard library

Project description

Add-ons for the logging standard library

Why any alternative or add-on to the standard logging lib?

While the std lib provides the essential need, there are situations where you do not get what you might expect. Or, the more you use logging, the more you want to get rid of some boiler-plate.

This package addresses some need for developers.

Alternatives

Usage:

import logging
import logging_alt
logging_alt.enable(<list of patch names>)

When an alternative is enabled, the logging package is patched so that logging behaves in an alternative way. Patches can be enabled individually by providing the patch name or list of names. If nothing is passed to enable() it only enables the recommended list (currently alt_logger only). Or, passing "all" enables all possible patches.

No issue with importing logging_alt several times, or trying to enable a patch multiple times, as any consequent imports or applies will be ignored.

You can switch back to the standard behaviour with

logging_alt.disable()

Run demos to see the difference between standard and alternative behaviour.

Alternative logger propagation flow

The original logging algorithm is a bit confusing.

Log records bubble up the logger hierarchy. The log level or isEnabled settings or filters of ancestor loggers are not checked. E.g. an INFO log record bubbles through ancestor logger even if their level is set to WARNING. Or, the filters of ancestor loggers are not invoked and cannot manipulate passing log records.

While this behaviour is documented, it still can be surprising, if one does not read the documentation carefully.

Let's look at a real-life example that actually motivated me to create this package. My application used a 3rd party package, which created log records with a message including a hard-coded time stamp. I needed to log the messages without these time stamps, and instead use the time-date format specified in my logging.

Not having access to the 3rd party package to fix it there, I had to manipulate the log message when it bubbled up through my application. A filter on my logger was a logical choice, but it was not invoked for 3rd party log records. As a work-around, I could have set the log record modification filter on all handlers of all ancestor loggers (for DB logging, terminal logging, etc) but it would have been cumbersome and error-prone (due to repetition). Also, it would have added unnecessary code execution (log record propagation and manipulation).

So, I could then use the alternative logger, the alt_logger, which changes the algorithm, see alternative algorithm. It is a consistent behaviour throughout the logger hierarchy, where all log levels and filters are consulted the same way in ancestor loggers, as in the originating logger.

Log handler debugger for threads

A new HandlerDebugged class is an enhanced Handler, which prints info, so that the sequence of actions of different LogRecords can be seen and debugged. The HandlerDebugged patch replaces the stock Handler with the new HandlerDebugged class.

Global lock for loggers

Intorduction of a global lock, so that only 1 thread can use logger at a time. This may be useful for programs that cannot make their logging thread-safe. The lock is aquired before LogRecord creation and not released until all filtering, propagation and handling is done for that LogRecord. The GlobalLockedLogger patch replaces the RootLogger with the new RootLoggerGlobalLocked class.

Add-on classes

Define filters in the config

SimpleFilter is a conveniency class for defining logging filters in the config easily as stings. E.g. a filter definition in the config as "text" in record.msg will filter out LogRecords not containing "text". See the class documentation.

NullHandler with filter

A NullHandlerWithFilter class is a NullHandler from emitting point of view, i.e. does not emit, but it flows the LogRecord through the attached filters, as other handlers would do. Filters can manipulate the LogRecord.

While the same result can be achieved by attaching the filters to the loggers themselves, there may be some use of NullHandlerWithFilter as a container of filters. You then need to attach one handler (with its bunch of filters) to the loggers where needed, instead of attaching the same set of filters individually to the loggers.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

logging_addons-0.5.0.tar.gz (7.8 kB view hashes)

Uploaded Source

Built Distribution

logging_addons-0.5.0-py3-none-any.whl (8.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page