Skip to content

Provides a simple extension to Python standard library logging which allows for creating log records before a logger (or its handlers) is initiated, yet logging the real creation time.

License

Notifications You must be signed in to change notification settings

means2014/preinitlogger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PreInitLogger

An easy-to-use extension to Python's standard logging library which provides 3 benefits.

Features

Verbosity-based log levels

Many systems accept user-defined verbosity, such as a "-v" flag passed as a command-line argument. For these cases, the programmer is required to make a conversion between increasing verbosity vs decreasing severity. With this package, you can set a verbosity level on either a handler or a logger object, and it will behave as you would expect.

The following verbosity levels are supported: (listed with their corresponding log levels)

- 0: logging.OUTPUT* (only log real output)
- 1: logging.INFO    (log some additional basic info)
- 2: logging.DEBUG   (log some useful debug information)
- 3: logging.DETAIL* (log everything - deep dive)

* levels added within this package

PreInitMessage class

There may be times when a log message is generated before a logger has actually been configured. Perhaps you would like to log the start time for your program/script, then read command line arguments and a config file to determine the log file path. With the standard logging library, you would have to store the message as a string, and log later. If your log format includes the creation time "%(asctime)s", the log would show the message created later than it actually was.

This package overrides the makeRecord method of logging.Logger, allowing users to specify the created time.

With great power comes great responsibility. Overriding a log record's creation date without good cause is a detriment to data integrity

Optional logger functions

Unless you call logging.getLogger(name) in every module, there will likely be scenarios wherein you would like to log a record without knowing for sure that a logger object is available.

Consider library function that takes a logger as an optional parameter:

def brittle_library_function(*args, logger=None, **kwargs):
    """
        raises AttributeError if logger is None...bad!
    """
    result = do_something(args, **kwargs)
    logger.debug(result)
    return result
def safe_library_function(*args, logger=None, **kwargs):
    """
        Standard approach, but quickly makes code unreadable, 
        with many levels of indentation...better
    """
    results = do_something(args, **kwargs)
    if logger is not None:    # works, but adds an unneccessary 
        logger.debug(results) # additional level of indentation
    return result
def preinitlogger_library_function(*args, logger=None, **kwargs):
    """
        Seamless to the programmer, accepts logger objects or 
        the name of a logger (as a string), and will do nothing
        if logger is None...best!
    """
    results = do_something(args, **kwargs)
    debug(results, logger=logger)
    return results

Installation

Recommended: If your project is within a UV environment, you can add this library as a dependency using uv add "preinitlogger @ git+https://github.com/cmeans/preinitlogger.git"

see UV: Managing Dependencies

(see usage below).

Otherwise: Clone this repo and treat as a local package.

Usage examples

# If cloned, these will have to be local imports
from preinitlogger import logging, PreInitMessage
from preinitlogger.config import config

logger = logging.getLogger(__name__)

...

if __name__ == '__main__':
    startup_msg = PreInitMessage(level=logging.DEBUG, msg=f'{__name__} initializing.')
    
    cli_args = parse_args(sys.argv[1:])
    cli_args_msg = PreInitMessage(level=logging.DETAIL, msg=f'{cli_args = }')
    config = parse_config(cli_args.get('cfg_file'))
    ... do_some_more_setup ...
    
    logging.basicConfig()
    logger.verbosity = cli_args.verbosity 
    logger.log_preinit_msgs(startup_msg, cli_args_msg)

About

Provides a simple extension to Python standard library logging which allows for creating log records before a logger (or its handlers) is initiated, yet logging the real creation time.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages