如何在Python中禁用和重新启用控制台日志记录?

问题描述 投票:145回答:15

我正在使用Python的logging模块,并且我想禁用控制台日志记录一段时间,但是它不起作用。

#!/usr/bin/python
import logging

logger = logging.getLogger() # this gets the root logger
# ... here I add my own handlers 
#logger.removeHandler(sys.stdout)
#logger.removeHandler(sys.stderr)

print logger.handlers 
# this will print [<logging.StreamHandler instance at ...>]
# but I may have other handlers there that I want to keep

logger.debug("bla bla")

上面的代码在标准输出上显示bla bla,但我不知道如何安全地禁用控制台处理程序。如何确定我暂时删除了控制台StreamHandler而不是另一个?

python logging console stdout
15个回答
190
投票

我为此找到了解决方案:

logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.

这将防止日志发送到包括控制台日志的上层日志。


2
投票

您也可以:


2
投票
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')

2
投票

通过在“ logging.config.dictConfig”中更改一个级别,您可以将整个日志记录级别提高到一个新级别。


1
投票

使用decorators


0
投票

如果要暂时禁用某个记录器,请执行以下操作。


-1
投票

将要暂时禁用的处理程序归类:


-1
投票

将要暂时禁用的处理程序归类:


100
投票

我使用:

logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False

67
投票

您可以使用:

logging.basicConfig(level=your_level)

其中您的等级是其中之一:

      'debug': logging.DEBUG,
      'info': logging.INFO,
      'warning': logging.WARNING,
      'error': logging.ERROR,
      'critical': logging.CRITICAL

因此,如果将您的级别设置为logging.CRITICAL,您将仅收到由以下人员发送的重要消息:

logging.critical('This is a critical error message')

您的级别设置为logging.DEBUG将显示所有级别的日志记录。

有关更多详细信息,请查看logging examples.

以相同的方式更改每个处理程序的级别,请使用Handler.setLevel()函数。

import logging
import logging.handlers

LOG_FILENAME = '/tmp/logging_rotatingfile_example.out'

# Set up a specific logger with our desired output level
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
          LOG_FILENAME, maxBytes=20, backupCount=5)

handler.setLevel(logging.CRITICAL)

my_logger.addHandler(handler)

46
投票

(长期未解决的问题,但对于将来的搜索者而言)

更接近原始海报的代码/意图,这在python 2.6下对我有效

#!/usr/bin/python
import logging

logger = logging.getLogger() # this gets the root logger

lhStdout = logger.handlers[0]  # stdout is the only handler initially

# ... here I add my own handlers 
f = open("/tmp/debug","w")          # example handler
lh = logging.StreamHandler(f)
logger.addHandler(lh)

logger.removeHandler(lhStdout)

logger.debug("bla bla")

我必须解决的问题是删除标准输出处理程序之后添加一个新的;如果没有处理程序,记录器代码似乎会自动重新添加标准输出。


41
投票

上下文管理器

import logging 
class DisableLogger():
    def __enter__(self):
       logging.disable(logging.CRITICAL)
    def __exit__(self, a, b, c):
       logging.disable(logging.NOTSET)

使用示例:

with DisableLogger():
    do_something()

34
投票

要完全禁用日志记录

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)

第一个解决方案的问题在于它仅适用于root记录器。使用logging.getLogger(__name__)创建的其他记录器不受此方法的限制。

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

这可以通过以下方式避免

logging.disable(sys.maxint)

据我所知(查看source之后,这是完全禁用日志记录的唯一方法。


26
投票

这里有一些非常好的答案,但显然最简单的考虑不是太多(仅来自infinito)。


10
投票

无需转移标准输出。这是更好的方法:


2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.