让我们说我们有这样一个项目结构:
-main.py
-dir_1 / module_log.py
其中设置了module_log.py或帮助程序以避免项目中的冗余代码。
module_log.py的内容如下:
import logging as log
def get_module_logger(module_name):
logger = log.getLogger(module_name)
logger.setLevel(log.INFO)
formatter = log.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s')
file_handler = log.FileHandler('path/to/logfile/logs.log')
file_handler.setFormatter(formatter)
stream_handler = log.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
return logger
def log_info_1():
logger = get_module_logger(__name__)
logger.info('\n____________INFO_1____________')
def log_info_2():
logger = get_module_logger(__name__)
logger.info('\n____________INFO_2____________')
main.py的内容如下:
import module_log as ml
ml.log_info_1()
logger = ml.get_module_logger(__name__)
logger.info('Main log')
ml.log_info_2()
问题在于记录器将第一条和第二条消息正确记录到文件中,但是第三条消息被写入了两次。
有人可以解释我为什么吗?如何避免此类问题?
答案 0 :(得分:1)
之所以这样,是因为您多次向同一记录器注册同一文件\流处理程序。
在dir_1/module_log.py
模块中,定义两个函数log_info_1
和log_info_2
。
每个函数依次调用具有相同模块名称的get_module_logger
函数 (在您的情况下为__name__ = "dir_1.module_log"
)
get_module_logger
将两个带有格式化程序的处理程序注册到同一记录器(具有该名称)。
该记录器名称是在运行程序的python解释器中“全局”定义的。因此,如果您想获得名称为<name>
的记录器定义,则可以从代码中的任意位置调用logging.getLogger(<name>)
并自由使用它。
要更正代码,您需要<一次>为分配处理程序,然后就可以在任何地方使用它了。
def get_module_logger(module_name):
logger = log.getLogger(module_name)
logger.setLevel(log.INFO)
if not len(logger.handlers):
formatter = log.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s')
file_handler = log.FileHandler('path/to/logfile/logs.log')
file_handler.setFormatter(formatter)
stream_handler = log.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
return logger