How to get current logging formatter?

Viewed 960

I'm using the logging module from the python standard library and would like to obtain the current Formatter. The reason is that I'm using multiprocessing module and for each process I'd like to assign its logger another file handler to log to its own log file. When I do this in the following way

logger = logging.getLogger('subprocess')
log_path = 'log.txt'
with open(log_path, 'a') as outfile:
        handler = logging.StreamHandler(outfile)
        logger.addHandler(handler)

the messages in log.txt have no formatting at all, but I would like the message to be in the same format as my typical logging format. My typical logging setup is shown below

    logging.basicConfig(
        format='%(asctime)s | %(levelname)s | %(name)s - %(process)d | %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=os.environ.get('LOGLEVEL', 'INFO').upper(),
    )
    logger = logging.getLogger(__name__)

Since it looks like the Formatter object is associated with the Handler object, I tried to obtain handler from the main Logger object which has the correct formatting. So I called

logger.handlers

but I got an empty list [].

So my question is, where do I get the Formatter object which has the same format that my main logger has?

For the record, I'm using python 3.8 on macOS but the code will be deployed to Linux (but still python 3.8).

1 Answers

Judging by the cpython source code on logging.basicConfig, it appears that the formatter object which contains your formatting string is eventually added to a handler that is passed to the root logger (see: here ). So you can obtain the handler (and therefore the formatter) from the root logger object by doing

logging.root.handlers[0].formatter

In particular, to achieve the subprocess logging handler in the question, you can do this instead

        handler = logging.StreamHandler(outfile)
        handler.setFormatter(logging.root.handlers[0].formatter)
        handler.setLevel(logging.root.level)
        logger.addHandler(handler)

which will set your handler to the same logging format (and level as well!) as that of your usual logger object.

Related