带有多个模块的Python日志记录 [英] Python logging with multiple modules

查看:329
本文介绍了带有多个模块的Python日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多模块,在这些模块中我大量使用Python日志记录.当我将它们导入到Python文档中的主模块中并尝试运行它时,我从日志记录中没有任何输出.有人知道发生了什么吗?

I have got various modules in which I use Python logging heavily. When I import them into the main module like in the Python documentation and try to run it, I don't get any output from the logging. Has anyone got any idea what is happening?

日志记录(这段代码太大,无法在此处放置).下面的代码是整个程序的运行和日志记录的初始化位置:

Logging is called in the module imported by the public module imported below (the piece of code is too large to be put up here). The piece of code below is where the whole program is run and the logging is initialized:

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')

推荐答案

您的问题可能是由import public语句调用logging.debug(...)或类似内容引起的.然后会发生什么:

Your problem is probably being caused by the import public statement making a call to logging.debug(...) or similar. What then happens is this:

  1. import public.作为副作用,这称为logging.debug或类似名称,会自动调用basicConfig,这会在根记录器中添加StreamHandler,但不会更改级别.
  2. 然后您调用basicConfig,但是由于根记录器已经具有处理程序,因此它什么也不做(如所记录).
  3. 由于默认日志记录级别为WARNING,因此您的infodebug调用不会产生任何输出.
  1. You import public. As a side-effect, this calls e.g. logging.debug or similar, which automatically calls basicConfig, which adds a StreamHandler to the root logger, but doesn't change the level.
  2. You then call basicConfig, but as the root logger already has a handler, it does nothing (as documented).
  3. Since the default logging level is WARNING, your info and debug calls produce no output.

您确实应该避免导入方面的副作用:例如,对basicConfig的调用应该在if __name__ == '__main__'子句中.与此public.py:

You really should avoid side-effects on import: for example, your call to basicConfig should be in the if __name__ == '__main__' clause. With this public.py:

import logging

def main():
    logging.debug('Hello from public')

和此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()

您将获得以下输出:

$ 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

从中您将看到Bottle实际上是在一个单独的进程中重新运行脚本,这导致消息数量增加了一倍.您可以使用显示进程ID的格式字符串来说明这一点:如果使用

You'll see from this that Bottle actually re-runs the script in a separate process, which accounts for the doubling up of messages. You can illustrate this by using a format string which shows the process ID: if you use

logging.basicConfig(level=logging.DEBUG,
                    format='%(process)s %(levelname)s %(message)s')

然后您将得到类似的输出

then you get output like

$ 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

请注意,如果您向public.py添加一个产生副作用的语句,如下所示:

Note that if you add a side-effect producing statement to public.py like this:

logging.debug('Side-effect from public')

在模块级别,则根本没有日志记录输出:

at the module level, then you get no logging output at all:

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

^C$ Shutdown...

似乎证实了上述分析.

这篇关于带有多个模块的Python日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆