Robot监听器中logger hasHandlers()返回True但无处理器问题求助
问题:Robot监听器中logging的hasHandlers()行为异常
我写了一段Python代码,作为独立脚本运行时,hasHandlers()能正常返回False(因为日志器确实没有绑定处理器);但作为Robot Framework的测试监听器运行时,明明打印出logger.handlers是空列表,hasHandlers()却返回True,导致我的日志处理器加不进去。加if not logger.hasHandlers()本来是为了避免多次执行测试时重复打印日志,现在反而出问题了。
代码如下:
def end_test(name, attrs): set_logging() some_stuff_logging() def set_logging(): global logger logger = logging.getLogger(__name__) print(logger.handlers) print ("Has handlers: {}".format(logger.hasHandlers())) if not logger.hasHandlers(): logger.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s | %(module)s | %(levelname)s | %(message)s") stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) def some_stuff_logging(): # use logger to print stuff logger.info("Test log message") if __name__ == '__main__': set_logging() some_stuff_logging()
原因与解决方案
核心原因
Python的logging模块采用层级继承机制,hasHandlers()方法会递归检查当前日志器及其所有父日志器(包括根日志器)是否存在处理器。Robot Framework启动时会初始化自身的logging配置,给根日志器添加了处理器。
当你在监听器中创建__name__对应的日志器时,它会默认继承根日志器的处理器,因此hasHandlers()返回True,但当前日志器自己的handlers列表是空的——处理器存在于父级(根日志器)而非当前日志器。
解决方案
有两种可行的处理方式:
方案一:直接检查当前日志器的handlers列表
替换hasHandlers()判断,直接检查当前日志器自身的handlers是否为空,跳过父级处理器的检查:def set_logging(): global logger logger = logging.getLogger(__name__) print(logger.handlers) print ("Has handlers: {}".format(not not logger.handlers)) if not logger.handlers: # 替换原有的hasHandlers()判断 logger.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s | %(module)s | %(levelname)s | %(message)s") stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler)方案二:关闭日志传播特性
禁用当前日志器向父级传播日志的功能,这样hasHandlers()只会检查当前日志器自身的处理器:def set_logging(): global logger logger = logging.getLogger(__name__) logger.propagate = False # 关闭日志传播到父级 print(logger.handlers) print ("Has handlers: {}".format(logger.hasHandlers())) if not logger.hasHandlers(): logger.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s | %(module)s | %(levelname)s | %(message)s") stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler)注意:使用该方案前要确认不需要当前日志器的日志被根日志器处理,否则会导致部分日志无法输出到Robot的默认日志中。
内容的提问来源于stack exchange,提问作者jay
相关产品推荐
相关产品推荐

