我正在尝试使用python logging模块,但在这里有点困惑.下面是一个标准的脚本来创建一个logger第一,然后创建并添加file handler和console handler到logger.
import logging
logger = logging.getLogger('logging_test')
logger.setLevel(logging.DEBUG)
print(len(logger.handlers)) # output: 0
# create file handler which logs even debug messages
fh = logging.FileHandler('/home/Jian/Downloads/spam.log', mode='w')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)
print(len(logger.handlers)) # output: 2
# write some log messages
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
Run Code Online (Sandbox Code Playgroud)
我在新启动的内核上运行它.file handler按预期工作.但是在控制台输出中,我有一些重复的消息:
2015-07-14 10:59:26,942 - logging_test - DEBUG - debug message
DEBUG:logging_test:debug message
2015-07-14 10:59:26,944 - logging_test - INFO - info message
INFO:logging_test:info message
2015-07-14 10:59:26,944 - logging_test - WARNING - warn message
WARNING:logging_test:warn message
2015-07-14 10:59:26,945 - logging_test - ERROR - error message
ERROR:logging_test:error message
2015-07-14 10:59:26,946 - logging_test - CRITICAL - critical message
CRITICAL:logging_test:critical message
Run Code Online (Sandbox Code Playgroud)
我想那些带有时间戳的日志消息来自用户定义的console handler,但重复的消息来自哪里?我可以摆脱它们,比如说,只保留其他所有线路吗?任何帮助表示赞赏.
观察结果如下:在普通的python或IPython控制台中,在根记录器本身用于发出日志消息之前,没有安装根记录器的处理程序:
In [1]: import logging
In [2]: logging.getLogger().handlers
Out[2]: []
In [3]: logging.warn('Something happened!')
WARNING:root:Something happened!
In [4]: logging.getLogger().handlers
Out[4]: [<logging.StreamHandler at 0x42acef0>]
Run Code Online (Sandbox Code Playgroud)
但是,在IPython笔记本中,立即安装了默认的stderr根记录器:
In [1]: import logging
In [2]: logging.getLogger().handlers
Out[2]: [<logging.StreamHandler at 0x35eedd8>]
Run Code Online (Sandbox Code Playgroud)
也许我错过了一些东西,但我认为在笔记本中,不应该自动安装处理程序,原因有很多:
propagate属性设置为False,以便日志消息不会传播到根记录器,但这不仅会禁止调试输出进入笔记本,还会禁用更严重的消息.此外,它还可以防止用户在需要时实际捕获所有日志输出.另一种方法是添加一个配置选项,为自动添加的流处理程序指定日志级别,以便可以忽略不太严重的消息自动显示在笔记本中.但这仍然会使IPython控制台和IPython笔记本之间的行为不同.
确保没有默认处理程序集的唯一缺点是,正在使用的某些库/笔记本可能依赖于此行为并积极解决它,例如,如果它们检测到它们在ipython中运行,则禁用它们自己的处理程序笔记本.这种情况可能会因这种变化而破裂.
因此,设置logger.propagate到False或使用reload(logging)将防止重复输出,但根据会有副作用.
请注意,reload在较新版本的python中不可用(3.4,可能更早).从3.1开始,请参阅importlib.reload
| 归档时间: |
|
| 查看次数: |
4199 次 |
| 最近记录: |