如何在Python中禁用标准错误流的日志记录?这行不通:

import logging

logger = logging.getLogger()
logger.removeHandler(sys.stderr)
logger.warning('foobar')  # emits 'foobar' on sys.stderr

当前回答

完全禁用日志记录:

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3

启用日志记录:

logging.disable(logging.NOTSET)

其他答案提供的工作并不能完全解决问题,例如

logging.getLogger().disabled = True

当n大于50时,

logging.disable(n)

第一个解决方案的问题是它只适用于根日志记录器。使用logging.getLogger(__name__)创建的其他记录器不会被此方法禁用。

第二个解决方案确实会影响所有日志。但是它将输出限制在给定级别之上,因此可以通过记录级别大于50的日志来覆盖它。

这可以通过

logging.disable(sys.maxint)

据我所知(在查看源代码后),这是完全禁用日志记录的唯一方法。

其他回答

我不是很了解日志模块,但是我使用它的方式是我通常只希望禁用调试(或信息)消息。您可以使用Handler.setLevel()将日志级别设置为CRITICAL或更高。

此外,您还可以替换sys。Stderr和sys。打开用于写入的文件的标准输出。见http://docs.python.org/library/sys.html # sys.stdout。但我不建议这样做。

你还可以:

handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
import logging

log_file = 'test.log'
info_format = '%(asctime)s - %(levelname)s - %(message)s'
logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'info_format': {
            'format': info_format
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'info_format'
        },
        'info_log_file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'level': 'INFO',
            'filename': log_file,
            'formatter': 'info_format'
        }
    },
    'loggers': {
        '': {
            'handlers': [
                'console',
                'info_log_file'
            ],
            'level': 'INFO'
        }
    }
})


class A:

    def __init__(self):
        logging.info('object created of class A')

        self.logger = logging.getLogger()
        self.console_handler = None

    def say(self, word):
        logging.info('A object says: {}'.format(word))

    def disable_console_log(self):
        if self.console_handler is not None:
            # Console log has already been disabled
            return

        for handler in self.logger.handlers:
            if type(handler) is logging.StreamHandler:
                self.console_handler = handler
                self.logger.removeHandler(handler)

    def enable_console_log(self):
        if self.console_handler is None:
            # Console log has already been enabled
            return

        self.logger.addHandler(self.console_handler)
        self.console_handler = None


if __name__ == '__main__':
    a = A()
    a.say('111')
    a.disable_console_log()
    a.say('222')
    a.enable_console_log()
    a.say('333')

控制台输出:

2018-09-15 15:22:23,354 - INFO - object created of class A
2018-09-15 15:22:23,356 - INFO - A object says: 111
2018-09-15 15:22:23,358 - INFO - A object says: 333

Test.log文件内容:

2018-09-15 15:22:23,354 - INFO - object created of class A
2018-09-15 15:22:23,356 - INFO - A object says: 111
2018-09-15 15:22:23,357 - INFO - A object says: 222
2018-09-15 15:22:23,358 - INFO - A object says: 333

这里有一些非常好的答案,但显然没有考虑太多最简单的答案(只从无穷开始)。

root_logger = logging.getLogger()
root_logger.disabled = True

这将禁用根日志记录器,从而禁用所有其他日志记录器。 我还没有真正测试过,但它应该是最快的。

从python 2.7的日志代码中,我看到了这一点

def handle(self, record):
    """
    Call the handlers for the specified record.

    This method is used for unpickled records received from a socket, as
    well as those created locally. Logger-level filtering is applied.
    """
    if (not self.disabled) and self.filter(record):
        self.callHandlers(record)

这意味着当它被禁用时,不会调用任何处理程序,并且它应该比过滤到一个非常高的值或设置一个no-op处理程序更有效。

使用上下文管理器-[最简单]

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"}