放假的电话

Python logger duplicate messages

刚刚接手公司的测试代码的时候,遇到一个很奇怪的问题。现有的测试代码在运行多个测试用例的时候,会输出很多重复的信息,重复次数跟运行的测试数有关。比如,运行第三个测试的时候,同样的信息会输出3次,而运行第四个测试的时候,同样的信息会输出4次。测试代码是用Python写的,显然问题跟python的logging模块有关。后来看了下测试中使用logging模块的方法,发现了问题的所在。

在我们的代码中,实现了一个wrapper来调用logging模块的getLogger函数,类似于:

1
2
3
4
5
6
7
8
9
def get_logger(app_name):
logger = logging.getLogger(app_name)
fh = logging.FileHandler()
sh = logging.StreamHandler()
logger.addHandler(fh)
logger.addHandler(sh)
return logger

该函数通过app_name来获得一个logger,并为它添加2个handler。在我们的代码中,在调用这个函数的时候,所有的测试用例都会使用一个相同的app_name。问题出在这个相同的app_name上,根据logging模块的文档, getLogger(name)函数实际是通过singleton的设计模式实现的:

All calls to this function with a given name return the same logger instance.

因为这个原因,多个测试用例在使用同一个名字来调用logger的时候,每一次都会添加2个handler,最后导致了重复的信息,并且重复次数跟测试数有关。知道了问题所在,我们可以通过判断logger的handler数量来决定是否要添加handler

1
2
3
4
5
6
logger = logging.getLogger(app_name)
if len(logger.handlers) != 2:
fh = logging.FileHandler()
......
return logger