我有以下代码设置记录器:
import logging
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO)
log = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
log.addHandler(handler)
log.info('abc')
运行它时,我得到如下输出:
2020-06-10 13:32:16,245 INFO: abc
abc
我想第一个是控制台输出?如何摆脱重复的?
更新
谢谢大家的回答,现在我知道为什么会得到重复了,之所以这样做是因为默认流处理程序不会输出到stdout,所以我用Google搜索并看到有人添加了stdout处理程序,因此我得到了2流处理程序(控制台和标准输出)。
我现在再次阅读了关于basicConfig()
的文档,并找到了实现所需目标的最简单方法:
import sys
import logging
log = logging.getLogger(__name__)
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout)
log.info('abc')
答案 0 :(得分:1)
对logging.basicConfig
的调用将已经添加了一个流处理程序(到stderr),因此没有理由手动添加另一个流处理程序。这样做会导致重复输出到终端,在您的情况下,每个日志事件都在 stderr和stdout上打印。
如果要让流处理程序代替stderr标准输出,只需通过指定basicConfig
或stream
关键字(docs)相应地调整handlers
调用即可。
您还可以清理另外两件事:使用绑定到模块__name__
上下文的记录器,而不是直接使用根记录器,并避免在导入时配置logging
模块。如果在导入时过于急切地配置日志记录系统,则用户(和测试套件)将无法再进行其他配置。
import logging
# create your logger as module level global
log = logging.getLogger(__name__)
def main():
# configure logging at entry point (so it is not configured at *import* time)
fmt = '%(asctime)s %(levelname)s: %(message)s'
logging.basicConfig(format=fmt, level=logging.INFO) # streamhandler to stderr
log.info('abc')
if __name__ == "__main__":
main()