Python中StreamHandler的setLevel无效
我设置了日志记录,代码如下:
def setUp():
LOG_FORMAT = '%(asctime)s %(levelname)-8s %(name)s %(message)s'
#LOG_FORMAT = '%(asctime)s %(name)s %(message)s'
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
formatter = logging.Formatter(LOG_FORMAT)
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
logging.getLogger().addHandler(ch)
LOG_FILENAME = 'file.log'
fh = logging.FileHandler(LOG_FILENAME, 'w')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logging.getLogger().addHandler(fh)
但是,控制台还是显示了 DEBUG
消息。我是不是漏掉了什么?
需要注意的是,把 fh
的级别设置为 ERROR
是可以正常工作的。
2 个回答
2
来自Python文档关于 logging.basicConfig 的内容:
这个方法用于对日志系统进行基本配置,它会创建一个默认格式的StreamHandler,并将其添加到根日志记录器(root logger)中。
当你把根日志记录器的调试级别设置为 logging.DEBUG
,并且没有关闭向根日志记录器转发消息的功能时,你的DEBUG消息就会通过这个由 basicConfig
创建的StreamHandler被记录下来。
2
我觉得你需要去掉对 logging.basicConfig
的调用。这个函数会添加一个新的 logging.StreamHandler
,可能正是这个处理器在打印你不想看到的消息。
你可以查看根日志记录器的 handlers
属性(这是一个包含所有正在使用的处理器的列表),来检查一下有多少个 logging.StreamHandler
。另外,可能因为有两个 logging.StreamHandler
,所以级别为 logging.ERROR
的消息会被打印两次。
我的最终建议是,如果你打算在代码中明确配置处理器,就尽量不要使用 logging.basicConfig
。
补充一下,logging.BasicConfig
的源代码如下:
if len(root.handlers) == 0:
filename = kwargs.get("filename")
if filename:
mode = kwargs.get("filemode", 'a')
hdlr = FileHandler(filename, mode)
else:
stream = kwargs.get("stream")
hdlr = StreamHandler(stream)
fs = kwargs.get("format", BASIC_FORMAT)
dfs = kwargs.get("datefmt", None)
fmt = Formatter(fs, dfs)
hdlr.setFormatter(fmt)
root.addHandler(hdlr)
level = kwargs.get("level")
if level is not None:
root.setLevel(level)
在这里你可以看到,除非传入 filename
,否则会创建一个 logging.StreamHandler
。