在多个模块中使用Python日志记录

10

我正在尝试为我已经开发了一段时间的代码添加日志记录(输出到控制台而不是文件)。通过阅读一些资料,我得出了一个应该有效的模式,但我不太确定哪里出了问题。

我有以下三个文件(显然是简化版):

controller.py

import my_module    
import logging
from setup_log import configure_log

def main():
    logger = configure_log(logging.DEBUG, __name__)
    logger.info('Started logging')
    my_module.main()

if __name__ == "__main__":
    main()

设置日志.py

import logging

def configure_log(level=None, name=None):
    logger = logging.getLogger(name)
    logger.setLevel(level)
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    chFormatter = logging.Formatter('%(levelname)s - %(filename)s - Line: %(lineno)d - %(message)s')
    console_handler.setFormatter(chFormatter)
    logger.addHandler(console_handler)
    return logger

我的模块.py

import logging

def main():    
    logger = logging.getLogger(__name__)
    logger.info("Starting my_module")
    print "Something"

if __name__ == "__main__":
    main()
当我运行它们时,只有第一次调用日志记录才会产生输出到控制台 -“开始日志记录”。对于第二次调用日志记录 - “启动我的模块”,它只是被忽略了。
我误解/搞砸了什么?

1
如果你想以完全相同的方式配置它们,为什么要在第一次配置时配置两个单独的记录器(__main__my_module)?为什么不只使用getLogger()进行一次配置并在所有地方都使用它呢? - abarnert
2个回答

20

根据文档,看起来您可以通过以下更简单的设置来实现:

如果您的程序由多个模块组成,以下是如何在其中组织日志记录的示例:

# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()

# mylib.py
import logging

def do_something():
    logging.info('Doing something')

如果您运行myapp.py,您应该在myapp.log中看到这个:

INFO:root:Started
INFO:root:Doing something
INFO:root:Finished

看起来你模块中的 logger = logging.getLogger(__name__) 调用正在创建一个单独的跟踪器(级别为NOTSET,但没有父关系导致日志条目)。


1
谢谢,我对文档感到有些困惑。而要将输出发送到控制台,看起来只需要不指定文件名参数,像这样:logging.basicConfig(level=logging.INFO) - Jamie Bull
一旦您按照上述步骤设置了日志记录,您可能还想将其记录到控制台。这是一种非常简单的方法,可以向所有记录器添加额外的处理程序,

将控制台处理程序添加到根记录器,因此添加到所有记录器实例。

logging.getLogger('').addHandler(logging.StreamHandler(sys.stdout))
- MathKid

3
实际的错误可以通过添加以下代码行来查看:

print '__name__', __name__

在你的主函数的开头,使用both关键字,得到以下结果:
$ python controller.py 
__name__ __main__
INFO - controller.py - Line: 8 - Started logging
__name__ my_module
Something

你正确地配置了一个名为__main__的记录器,但名为my_module的记录器没有被配置。

更深层次的问题是你有两个main方法,这可能会让你感到困惑(我也是如此)。


1
有没有推荐的方法来解决更深层次的问题? - baxx
baxx,建议的方法是不要使用两个名为main的函数。 - Michael Currie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接