2017-03-09 117 views
1

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

我有三个模块,可以称他们为MBMC主要。主要导入这3个模块并调用它们的功能。

在每个模块中我设置像这样的记录程序:

ma.py
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) 

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) 

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) 

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

回答

1

使用全局记录器一个更好的办法是使用包装调用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() 

输出

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 

说明:使用函数还允许我们将logger.propagate设置为False,以防止将日志消息发送到根记录器。这几乎可以肯定是你看到的重复输出的原因。

更新:在致电get_logger后,必须通过调用logger.setLevel来设置所需级别。如果没有这样做,那么只会看到错误消息。

+0

我有一个模块,带有帮助程序所有需要日志记录调用的3个模块的功能。所以我将这个功能添加到该模块(我添加了一些格式化程序/ setLevel更改,我也有上述)。现在在每个模块中,我只是调用'logger = helper.get_logger('test')'。现在,当我运行我的程序时,根本没有日志显示,只有打印语句 – bbakp3

+0

您必须调用'logger.setLevel'将级别设置为'logging.DEBUG'。否则,你只会看到错误信息。我已更新我的代码,使其成为一个完整的示例。 –

+0

我在helper模块的方法中添加了'logger.setLevel'函数,它现在可以工作了,谢谢! – bbakp3

0

要将多个模块登录到一个全局文件,请创建一个日志记录实例,然后使用您喜欢的任何模块获取该实例。因此,例如在主,我会:

import logging 

logging.basicConfig(filename='logfile.log', level=logging.DEBUG) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
logger = logging.getLogger('Global Log') 

然后,我希望能够将追加到该日志的每个模块中,我有:

import logging 
logger = logging.getLogger('Global Log') 

现在每次你访问记录仪在您的模块中,您正在访问相同的日志记录实例。这样,你只需要设置和格式化记录器一次。

更多的文档记录实例: https://docs.python.org/2/library/logging.html#logging.getLogger

+0

我试过了,它似乎工作,但仔细观察后,仍然有一些部分输出两次。第一次只是我的时间/名称/信息的一般格式,它第二次输出它只是说 调试:消息 – bbakp3

+0

根据文档(从我的链接到你的地方的简短方式)它说,使用模块级功能会导致处理程序被多次添加到记录器。这是Python 2.7-3.2的一个问题。我不确定这里的解决方案是什么,我在3.4.2上工作,并没有遇到这个问题(我知道这并没有什么帮助!) –

+0

感谢您的帮助:) – bbakp3