Python 日志记录不适用于模块

Python Logging does not work over modules

在我的 main.py 文件中,我按如下方式初始化记录器:

# File: main.py
import logging
logger = logging.getLogger(__name__)

import submodule

#...

def main():
    logger.debug(f'Test')

if __name__ == '__main__':
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter('[%(levelname)s | %(name)s] %(message)s')

    # The handler h1 logs only debug and info to stdout
    h1 = logging.StreamHandler(sys.stdout)
    h1.setLevel(logging.DEBUG)
    h1.addFilter(lambda record: record.levelno <= logging.INFO)
    h1.setFormatter(formatter)

    # The handler h2 logs only warning, error and exception to stderr
    h2 = logging.StreamHandler()
    h2.setLevel(logging.WARNING)
    h2.setFormatter(formatter)

    logger.addHandler(h1)
    logger.addHandler(h2)

    main()

当我在主脚本中使用记录器时,一切正常。 但是当我在这样的子模块中使用它时:

# File: submodule.py
import logging
logger = logging.getLogger(__name__)

#...

logger.info('Test 1')
logger.error('Test 2')

我应该看到以下输出(或类似的内容):

[DEBUG | __main__] Test
[INFO | submodule] Test 1
[ERROR | submodule] Test 2

但我得到了这个输出:

[DEBUG | __main__] Test
Test 2

对我来说,子模块中的记录器似乎没有使用主模块中记录器的配置。如何解决?

这是因为

logger = logging.getLogger(__name__)

将 return 主模块和子模块中的不同记录器(因为 __name__ 是不同的字符串)。您现在只为主模块配置记录器。

但是记录器是分层的,所以最简单的方法是使用处理程序配置根记录器:

root_logger = logging.getLogger('')
...
root_logger.addHandler(h1)

所有其他记录器都是根记录器的子项,因此默认情况下消息将“冒泡”到根并使用那里配置的处理程序和级别。