Python记录多个模块

6 python logging bottle

我有各种各样的模块,我大量使用Python日志.当我像在Python文档中一样将它们导入主模块并尝试运行它时,我没有从日志记录中获得任何输出.有谁知道发生了什么?

public下面导入的模块导入的模块中调用日志记录(这段代码太大而无法放在这里).下面的代码段是运行整个程序并初始化日志记录的地方:

import logging
from bottle import run, debug
import public

logging.basicConfig(level=logging.DEBUG)

if __name__ == '__main__':
   logging.info('Started')
   debug(mode=True)
   run(host='localhost', port = 8080, reloader=True)
   logging.info('Finished')
Run Code Online (Sandbox Code Playgroud)

Vin*_*jip 9

您的问题可能是由import public致电logging.debug(...)或类似的声明引起的.然后发生的是:

  1. import public.作为副作用,这会调用例如logging.debug或类似的,自动调用basicConfig,这会StreamHandler向根记录器添加一个,但不会更改级别.
  2. 然后调用basicConfig,但由于根记录器已经有一个处理程序,它什么都不做(如文档所述).
  3. 由于默认日志记录级别为WARNING,您infodebug调用不会产生任何输出.

你真的应该避免导入的副作用:例如,你的调用basicConfig应该在if __name__ == '__main__'子句中.有了这个public.py:

import logging

def main():
    logging.debug('Hello from public')
Run Code Online (Sandbox Code Playgroud)

这个main.py:

import logging
from bottle import run, debug
import public

def main():
    logging.basicConfig(level=logging.DEBUG)
    logging.info('Started')
    debug(mode=True)
    public.main()
    run(host='localhost', port = 8080, reloader=True)
    logging.info('Finished')

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

您将获得以下输出:

$ python main.py
INFO:root:Started
DEBUG:root:Hello from public
INFO:root:Started
DEBUG:root:Hello from public
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

^CINFO:root:Finished
$ Shutdown...
INFO:root:Finished
Run Code Online (Sandbox Code Playgroud)

你会从中看到,Bottle实际上是在一个单独的进程中重新运行脚本,这可以解决消息加倍的问题.您可以使用显示进程ID的格式字符串来说明这一点:如果您使用

logging.basicConfig(level=logging.DEBUG,
                    format='%(process)s %(levelname)s %(message)s')
Run Code Online (Sandbox Code Playgroud)

然后你得到输出

$ python main.py
13839 INFO Started
13839 DEBUG Hello from public
13840 INFO Started
13840 DEBUG Hello from public
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

^C13839 INFO Finished
$ Shutdown...
13840 INFO Finished
Run Code Online (Sandbox Code Playgroud)

请注意,如果您添加副作用生成语句,public.py如下所示:

logging.debug('Side-effect from public')
Run Code Online (Sandbox Code Playgroud)

在模块级别,您根本没有记录输出:

$ python main.py
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

^C$ Shutdown...
Run Code Online (Sandbox Code Playgroud)

这似乎证实了上述分析.