来自多个模块的Python日志问题
我有三个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
在它的主方法中调用get_log
函数。
Other.py
在全局范围内调用get_log
(在导入之后,任何函数之前)
结果是我所有的日志都会被记录两次,因为为记录器创建了两个处理器。
我错过了什么简单的方法,让get_log
函数返回同一个日志实例呢?
1 个回答
16
logging
模块已经为你实现了一个单例模式——当你调用logger.getLogger(name)
时,如果这个日志记录器还没有被创建,它会自动创建一个并返回给你。虽然这和你问的不是完全一样,但我建议你把get_log()
改名为setup_log()
,因为它的作用就是这样。然后你只需要在代码开始的时候调用一次setup_log()
。之后,当你真正需要使用日志记录器时,只需用logging.getLogger()
,它会返回已经配置好的日志记录器。