Search code examples
pythonloggingtornado

How do I override an existing logger in another library?


I'm using Python's Tornado library for my web service and I want every log that is created from my code as well as from Tornado to be json formatted. I've tried setting the formatter on the root logger, setting the formatter and all the other loggers. This is the hack I'm currently trying to get working. It seems to me like it should work... However, when I run the app all of the logs from Tornado are still in their standard format.

import logging

from tornado.log import access_log, app_log, gen_log
import logmatic


loggers = [
    logging.getLogger(),
    logging.getLogger('tornado.access'),
    logging.getLogger('tornado.application'),
    logging.getLogger('tornado.general'),
    access_log,
    gen_log,
    app_log
]
json_formatter = logmatic.JsonFormatter()
for logger in loggers:
    for hand in logger.handlers:
        hand.setFormatter(json_formatter)

logging.getLogger('tornado.access').warning('All the things')
# WARNING:tornado.access (172.26.0.6) 0.47ms
# NOT JSON???

NOTE: When I include the loggers for my service logging.getLogger('myservice') in the loggers list and run this they do get the updated formatter and spit out json. This rules out problems with the logmatic formatter. Can't get the formatter to work for the Tornado loggers.


Solution

  • Tornado's loggers don't have any handlers before calling loop.start(), so you should add a handler with predefined formatting to loggers.

    formatter = logging.Formatter(...)
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    
    for l in loggers:
        l.setLevel(logging.WARNING)
        l.addHandler(handler)