Python记录来自多个模块的问题

时间:2011-09-07 23:14:47

标签: python singleton logging

我有3个python模块。

LogManager.py
Runner.py
Other.py

Runner.py是事件链中的第一个主要模块,并且从该模块中调用Other.py内的函数。

因此,在Runner.py内,我对LogManager.py

进行了函数调用
logger = LogManager.get_log()

从那里,我可以制作简单的日志,例如logger.critical("OHNOES")

我想要get_log函数做什么,类似于单例模式,如果没有设置记录器,它将设置记录器并返回它。否则,它将返回记录器。

LogManager.py的内容:

import logging

def get_log():
    logger = logging.getLogger('PyPro')
    logger.setLevel(logging.DEBUG)

    # create file handler which logs even debug messages
    fh = logging.FileHandler('pypro.log')
    fh.setLevel(logging.DEBUG)

    # create console handler with a higher log level
    ch = logging.StreamHandler()
    ch.setLevel(logging.WARNING)

    # create formatter and add it to the handlers
    fhFormatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    chFormatter = logging.Formatter('%(levelname)s - %(filename)s - Line: %(lineno)d - %(message)s')
    fh.setFormatter(fhFormatter)
    ch.setFormatter(chFormatter)

    # add the handlers to logger
    logger.addHandler(ch)
    logger.addHandler(fh)

    logger.info("-----------------------------------")
    logger.info("Log system successfully initialised")
    logger.info("-----------------------------------")

    return logger

如您所见,LogManager.get_log()将在每次调用时尝试设置日志。真的,我对确切发生的事情感到有点困惑......

Runner.py在它的main方法中调用get_log函数。 Other.py在全局范围内调用get_log(在导入之后,而不是在任何函数中)

结果是我记录的所有日志都记录了两次,因为记录器的处理程序是两次。

我缺少最简单的方法是让get_log函数以其他方式返回相同日志的实例?

1 个答案:

答案 0 :(得分:5)

logging模块已经为您实现了单例模式 - 当您调用logger.getLogger(name)时,如果尚未执行此操作,它将创建记录器并返回它。虽然它不是完全你所要求的,但我建议只将get_log()重命名为setup_log(),因为它就是它的作用。然后,您只需在代码的开头调用setup_log()一次即可。之后,当您确实需要记录器时,只需使用logging.getLogger(),它将返回已配置的记录器。