【发布时间】:2015-02-23 04:08:21
【问题描述】:
在我的代码中,我使用logging.info(...,在此之前我使用logging.basicConfig(filename=... 进行配置。是否可以在不做任何事情的情况下将日志记录行保留在代码中?
【问题讨论】:
在我的代码中,我使用logging.info(...,在此之前我使用logging.basicConfig(filename=... 进行配置。是否可以在不做任何事情的情况下将日志记录行保留在代码中?
【问题讨论】:
你可以使用:
logging.disable(logging.CRITICAL)
发送至disable all logging calls,其级别为 CRITICAL 或以下。实际上,这会禁用所有日志记录调用。
您可以通过执行以下操作再次启用所有记录器的日志记录(在它们自己的日志记录级别):
logging.disable(logging.NOTSET)
【讨论】:
编辑:disabled 似乎不应该供公众使用。查看 Maggyero 对替代解决方案的回答。
只需禁用日志处理程序,它就不会再写入任何内容了。
logging.getLogger().disabled = True
请注意,每个记录器都可以有处理程序,因此可能会有更多。
【讨论】:
removeHandler 方法,它使用threading.RLock() 实例来实现)。其次,因为logging.lastResort 处理程序将在没有处理程序的情况下使用。相反,您应该添加一个logging.NullHandler() 实例(以避免logging.lastResort 处理程序)并将propagate 设置为False 以避免日志记录传播到父记录器的处理程序。
lastResort 处理程序在 Python 2 中不存在(它是在 3.2 中添加的)所以在 5 年前写这篇文章时我不知道它;)docs.python.org/3.2/library/logging.html#logging.lastResort 至于线程安全,这在这里完全无关紧要。替换变量没有锁定安全问题。不过,我将删除第一个解决方案,使用 lastResort 处理程序不再是一个好的解决方案。
lastResort处理程序不存在,"No handlers could be found for logger X"消息也会打印在sys.stderr上,这不是所谓的“完全禁用日志记录”。
raiseExceptions 时才会出现这种情况(对于 Python 2),不建议在生产系统上使用。所以消息会被系统吞下。
disabled 属性并不是一个好主意,因为它实际上不是公共 API 的一部分(参见 my discussion 与 logging 库的作者 Vinay Sajip 的合影)。因此正确的解决方案是使用lambda record: False 过滤器或logging.NullHandler() 处理程序而不进行传播。
logging.WARNING,非根记录器默认为logging.NOTSET)和一个有效级别(非根记录器的父记录器的有效级别,级别为logging.NOTSET,否则为记录器的级别);logging.NOTSET);Logging 有the following process(用流程图表示):
因此,要禁用特定记录器,您可以采用以下策略之一:
将记录器的级别设置为logging.CRITICAL + 1。
使用主 API:
import logging
logger = logging.getLogger("foo")
logger.setLevel(logging.CRITICAL + 1)
使用配置 API:
import logging.config
logging.config.dictConfig({
"version": 1,
"loggers": {
"foo": {
"level": logging.CRITICAL + 1
}
}
})
向记录器添加过滤器lambda record: False。
使用主 API:
import logging
logger = logging.getLogger("foo")
logger.addFilter(lambda record: False)
使用配置 API:
import logging.config
logging.config.dictConfig({
"version": 1,
"filters": {
"all": {
"()": lambda: (lambda record: False)
}
},
"loggers": {
"foo": {
"filters": ["all"]
}
}
})
删除记录器的现有处理程序add a handler logging.NullHandler() to the logger(以防止事件被处理程序logging.lastResort处理,这是一个logging.StreamHandler使用当前流sys.stderr和一个级别logging.WARNING)和@987654325 @(防止事件被记录器的祖先记录器的处理程序处理)。
使用主 API:
import logging
logger = logging.getLogger("foo")
for handler in logger.handlers.copy():
try:
logger.removeHandler(handler)
except ValueError: # in case another thread has already removed it
pass
logger.addHandler(logging.NullHandler())
logger.propagate = False
使用配置 API:
import logging.config
logging.config.dictConfig({
"version": 1,
"handlers": {
"null": {
"class": "logging.NullHandler"
}
},
"loggers": {
"foo": {
"handlers": ["null"],
"propagate": False
}
}
})
警告。 - 与策略 1 和 2 相反,策略 3还可以防止由记录器(例如logging.getLogger("foo.bar"))的后代记录器记录的事件被记录器及其祖先记录器的处理程序发出。
注意。 — 将记录器的属性 disabled 设置为 True 不是另一种策略,因为它不是公共 API 的一部分(参见 https://bugs.python.org/issue36318):
import logging
logger = logging.getLogger("foo")
logger.disabled = True # DO NOT DO THIS
【讨论】:
filter() 方法有一个小警告。它不会像处理程序和级别那样传播:saltycrane.com/blog/2014/02/… 所以如果你想过滤你需要遍历所有处理程序的所有内容。
NullHandler() 仅在没有现有处理程序的情况下才有效。否则完全是徒劳的。
logging.NullHandler()并将propagate属性设置为True;如果您使用第二种解决方案启用了日志记录,请删除 lambda record: False 过滤器。
如果你想完全禁用日志首先应该在 logging.basicConfig() 中设置 levelevl 等于 logging.NOTSET 因为是零级别,然后是 logging.getLogger( ).disabled 设置 True 或 False。 https://docs.python.org/2/library/logging.html
完全禁用示例:
import logging
if __name__ == '__main__':
logging.disable(logging.NOTSET)
logging.basicConfig(
format="%(levelname) -10s %(asctime)s %(filename)s:%(lineno)s %(message)s",
level=logging.NOTSET)
logging.getLogger().disabled = True # True, False
logging.critical("Critical")
logging.error("Error")
logging.warning("Warning")
logging.info("Info")
logging.debug("Debug")
【讨论】: