Python 记录多个模块输出两次

bba*_*kp3 4 python logging

我对 python 日志记录不太熟悉,我试图让它将输出记录到控制台。我已经让它工作了,但似乎输出在控制台中出现了两次,我不知道为什么。我查看了这里提出的有关类似情况的其他问题,但我找不到任何对我有帮助的东西。

我有三个模块,我们称它们为mambmc和 a main。main 导入这 3 个模块并调用它们的函数。

在每个模块中,我设置了一个记录器,如下所示:

映射文件

import logging
logger = logging.getLogger('test.ma') #test.mb for mb.py/test.mc for mc.py
logger.setLevel(logging.DEBUG)

console_log = logging.StreamHandler()
console_log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
console_log.setFormatter(formatter)
logger.addHandler(console_log)
...
...
#right before the end of each module, after I'm finished logging what I need.
logger.removeHandler(console_log)
Run Code Online (Sandbox Code Playgroud)

mb.py

import logging
logger = logging.getLogger('test.mb')
logger.setLevel(logging.DEBUG)

console_log = logging.StreamHandler()
console_log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
console_log.setFormatter(formatter)
logger.addHandler(console_log)
...
...
#end of file
logger.removeHandler(console_log)
Run Code Online (Sandbox Code Playgroud)

mc.py

import logging
logger = logging.getLogger('test.mc')
logger.setLevel(logging.DEBUG)

console_log = logging.StreamHandler()
console_log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
console_log.setFormatter(formatter)
logger.addHandler(console_log)
...
...
#end of file
logger.removeHandler(console_log)
Run Code Online (Sandbox Code Playgroud)

我遇到的主要问题是输出打印两次,并且对于程序的某些部分,它没有格式化。任何帮助将不胜感激,谢谢!

小智 7

使用全局记录器的更好方法是使用一个将调用包装到的函数logging.getLogger

import logging

def get_logger(name):
    logger = logging.getLogger(name)
    if not logger.handlers:
        # Prevent logging from propagating to the root logger
        logger.propagate = 0
        console = logging.StreamHandler()
        logger.addHandler(console)
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
        console.setFormatter(formatter)
    return logger

def main():
    logger = get_logger(__name__)
    logger.setLevel(logging.DEBUG)
    logger.info("This is an info message")
    logger.error("This is an error message")
    logger.debug("This is a debug message")

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

输出

2017-03-09 12:02:41,083 - __main__ - This is an info message
2017-03-09 12:02:41,083 - __main__ - This is an error message
2017-03-09 12:02:41,083 - __main__ - This is a debug message
Run Code Online (Sandbox Code Playgroud)

注意:使用函数还允许我们设置logger.propagateFalse防止日志消息发送到根记录器。这几乎肯定是您看到的重复输出的原因。

更新:调用 后get_logger,必须通过调用 来设置所需的级别logger.setLevel。如果不这样做,则只会看到错误消息。