Search code examples
pythonloggingtornado

Why does ioLoop in tornado seem to add root logger handler?


I have used python logging in my system and worked find. My log hierarchy is like below.

  1. Define log A which has handler and formatter.
  2. log A inherit A.B, A.C....(child loggers just use handler and formatter of A)
  3. I don't add root logger handler.

So all logger had worked find, sharing handler of A.

And I needed to add Websocket procedure, so I choose Tornado. But after adding Tornado, suddenly duplicated log appear.

for example.

Time-A : log message  #This is log message I print
INFO:A : log message  #This is duplicated log message

In more detail, If i call ioloop.IOLoop.instance().start() If I block ioloop.IOLoop.instance().start(), the issue is not found.

Seems that root logger handler is added by ioloop.IOLoop.instance().start().

Why? and how can I fix it ?


Solution

  • Event loops must catch exceptions from their callbacks; Tornado uses logging to tell you that an exception has occurred. If there were no handler configured you'd never see these messages, so the IOLoop creates a handler if necessary when it is started. To prevent this, define a handler for either the root logger or the tornado logger before starting the IOLoop.

    When the IOLoop creates a handler, it does so for the root logger instead of the tornado logger because root handlers are automatically created in other places (i.e. the logging module's top-level functions like logging.error), so there would be double logging if the IOLoop created a tornado handler and then some other module called logging.error and created a root handler.