如何在Python中禁用标准错误流的日志记录?这行不通:
import logging
logger = logging.getLogger()
logger.removeHandler(sys.stderr)
logger.warning('foobar') # emits 'foobar' on sys.stderr
如何在Python中禁用标准错误流的日志记录?这行不通:
import logging
logger = logging.getLogger()
logger.removeHandler(sys.stderr)
logger.warning('foobar') # emits 'foobar' on sys.stderr
当前回答
您可以更改特定处理程序的调试模式级别,而不是完全禁用它。
因此,如果你有一个情况,你想停止调试模式的控制台,但你仍然需要保持其他级别,如错误。你可以像下面这样做
# create logger
logger = logging.getLogger(__name__)
def enableConsoleDebug (debug = False):
#Set level to logging.DEBUG to see CRITICAL, ERROR, WARNING, INFO and DEBUG statements
#Set level to logging.ERROR to see the CRITICAL & ERROR statements only
logger.setLevel(logging.DEBUG)
debugLevel = logging.ERROR
if debug:
debugLevel = logging.DEBUG
for handler in logger.handlers:
if type(handler) is logging.StreamHandler:
handler.setLevel (debugLevel)
其他回答
日志有以下结构:
loggers are arranged according to a namespace hierarchy with dot separators; each logger has a level (logging.WARNING by default for the root logger and logging.NOTSET by default for non-root loggers) and an effective level (the effective level of the parent logger for non-root loggers with a level logging.NOTSET and the level of the logger otherwise); each logger has a list of filters; each logger has a list of handlers; each handler has a level (logging.NOTSET by default); each handler has a list of filters.
日志记录有以下过程(由流程图表示):
因此,要禁用特定的记录器,您可以采用以下策略之一:
Set the level of the logger to logging.CRITICAL + 1. Using the main API: import logging logger = logging.getLogger("foo") logger.setLevel(logging.CRITICAL + 1) Using the config API: import logging.config logging.config.dictConfig({ "version": 1, "loggers": { "foo": { "level": logging.CRITICAL + 1 } } }) Add a filter lambda record: False to the logger. Using the main API: import logging logger = logging.getLogger("foo") logger.addFilter(lambda record: False) Using the config API: import logging.config logging.config.dictConfig({ "version": 1, "filters": { "all": { "()": lambda: (lambda record: False) } }, "loggers": { "foo": { "filters": ["all"] } } }) Remove the existing handlers of the logger, add a handler logging.NullHandler() to the logger (to prevent events from being handled by the handler logging.lastResort which is a logging.StreamHandler using the current stream sys.stderr and a level logging.WARNING) and set the attribute propagate of the logger to False (to prevent events from being handled by the handlers of the ancestor loggers of the logger). Using the main 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 Using the config 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"))被记录器的处理程序及其祖先记录器发出。
请注意。—将日志记录器禁用的属性设置为True不是另一种策略,因为它不是公共API的一部分(参见https://bugs.python.org/issue36318):
import logging
logger = logging.getLogger("foo")
logger.disabled = True # DO NOT DO THIS
你还可以:
handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
您可以更改特定处理程序的调试模式级别,而不是完全禁用它。
因此,如果你有一个情况,你想停止调试模式的控制台,但你仍然需要保持其他级别,如错误。你可以像下面这样做
# create logger
logger = logging.getLogger(__name__)
def enableConsoleDebug (debug = False):
#Set level to logging.DEBUG to see CRITICAL, ERROR, WARNING, INFO and DEBUG statements
#Set level to logging.ERROR to see the CRITICAL & ERROR statements only
logger.setLevel(logging.DEBUG)
debugLevel = logging.ERROR
if debug:
debugLevel = logging.DEBUG
for handler in logger.handlers:
if type(handler) is logging.StreamHandler:
handler.setLevel (debugLevel)
使用上下文管理器-[最简单]
import logging
class DisableLogger():
def __enter__(self):
logging.disable(logging.CRITICAL)
def __exit__(self, exit_type, exit_value, exit_traceback):
logging.disable(logging.NOTSET)
使用示例:
with DisableLogger():
do_something()
如果你需要[更复杂的]细粒度的解决方案,你可以看看AdvancedLogger
AdvancedLogger can be used for fine grained logging temporary modifications
How it works:
Modifications will be enabled when context_manager/decorator starts working and be reverted after
Usage:
AdvancedLogger can be used
- as decorator `@AdvancedLogger()`
- as context manager `with AdvancedLogger():`
It has three main functions/features:
- disable loggers and it's handlers by using disable_logger= argument
- enable/change loggers and it's handlers by using enable_logger= argument
- disable specific handlers for all loggers, by using disable_handler= argument
All features they can be used together
AdvancedLogger的用例
# Disable specific logger handler, for example for stripe logger disable console
AdvancedLogger(disable_logger={"stripe": "console"})
AdvancedLogger(disable_logger={"stripe": ["console", "console2"]})
# Enable/Set loggers
# Set level for "stripe" logger to 50
AdvancedLogger(enable_logger={"stripe": 50})
AdvancedLogger(enable_logger={"stripe": {"level": 50, "propagate": True}})
# Adjust already registered handlers
AdvancedLogger(enable_logger={"stripe": {"handlers": "console"}
我找到了一个解决方案:
logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.
这将防止日志被发送到包含控制台日志的上层记录器。