为什么龙卷风中的 ioLoop 似乎添加了根记录器处理程序?

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

我在我的系统中使用了 python logging 并找到了。 我的日志层次结构如下所示。

  1. 定义具有处理程序和格式化程序的日志 A
  2. log A inherit A.B, A.C.....(child loggers just use handler and formatter of A)
  3. 我没有添加根记录器处理程序。

所以所有记录器都找到了,共享 A 的处理程序。

而且我需要添加Websocket程序,所以我选择了Tornado。 但是添加Tornado后,突然出现重复的日志

例如

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

更详细,如果我调用 ioloop.IOLoop.instance().start() 如果我阻止 ioloop.IOLoop.instance().start(),则找不到问题。

似乎根记录器处理程序是由 ioloop.IOLoop.instance().start() 添加的。

为什么?我该如何解决?

事件循环必须从它们的回调中捕获异常; Tornado 使用日志记录来告诉您发生了异常。如果没有配置处理程序,您永远不会看到这些消息,因此 IOLoop 在启动时会根据需要创建一个处理程序。为防止这种情况,在启动 IOLoop 之前为根记录器或 tornado 记录器定义一个处理程序。

当 IOLoop 创建处理程序时,它是为根记录器而不是 tornado 记录器创建的,因为根处理程序是在其他地方自动创建的(即日志记录模块的顶级函数,如 logging.error),所以如果 IOLoop 创建了一个 tornado 处理程序,然后一些其他模块调用 logging.error 并创建了一个根处理程序,将会有双重日志记录。