Python 记录器混淆

Python logger confusion

我想了解 python 日志记录,我有这个:

Main.py:

import logging
from Foo import Foo

logging.basicConfig(level=logging.DEBUG)

fh_formatter = logging.Formatter('[%(asctime)s : %(levelname)s : %(name)s] : %(message)s')
file_handler = logging.FileHandler('logger.log', mode='w')
file_handler.setFormatter(fh_formatter)
file_handler.setLevel(logging.DEBUG)

sh_formatter = logging.Formatter('%(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(sh_formatter)
stream_handler.setLevel(logging.DEBUG)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)

logger.info('Running main')
Foo().print_foo()

Foo.py

import logging
from Bar import Bar

logger = logging.getLogger(__name__)

class Foo():

    def print_foo(self):
        Bar().print_bar()
        logger.info('Inside Foo.foo')

Bar.py:

import logging

logger = logging.getLogger(__name__)

class Bar():

    def print_bar(self):
        logger.info('Inside Bar.bar')

当我 运行 代码时,在控制台上我看到这个 output:

Running main
INFO:__main__:Running main
INFO:Bar:Inside Bar.bar
INFO:Foo:Inside Foo.foo

但是当我检查 logger.log 时,我只看到一行

[2019-03-23 18:46:01,276 : INFO : __main__] : Running main

我怎样才能看到两个地方的所有线条?我是否需要为每个文件中的每个记录器设置文件处理程序和流处理程序?如果我有一个 python 项目,并且我想要一个日志文件和控制台输出,那么正确的方法是什么?

问题出在 Foo 和 Bar 的这一行:

logger = logging.getLogger(__name__)

请注意,您仅在 Main.py 中重置了日志记录处理程序,记录器名称为 __name__,如您在输出中所见,它解析为 "__main__"。当您从 Foo.py 获取记录器时,您的记录器名称是 "Foo",因此您设置为 "__main__" 的所有内容都不会应用。

您想做什么:更改 __name__ 部分。例如,您的应用名为 fubar 然后您在 Main.py 中执行此操作:

logger = logging.getLogger("fubar")

并在 Foo.py 中,作为应用程序中的子模块,执行此操作:

logger = logging.getLogger("fubar.Foo")

或者,如果您愿意,您甚至可以使用相同的名称。这样,在更高级别分配的处理程序将传递给子级别。