如何在Python中禁用标准错误流的日志记录?

如何在Python中禁用标准错误流的日志记录?,python,logging,console,stdout,Python,Logging,Console,Stdout,如何在Python中禁用标准错误流?这不起作用: 导入日志 logger=logging.getLogger() logger.removeHandler(sys.stderr) logger.warning('foobar')#在sys.stderr上发出'foobar' 我不太了解日志模块,但我使用它的方式通常只想禁用调试(或信息)消息。您可以使用Handler.setLevel()将日志记录级别设置为临界或更高 此外,还可以将sys.stderr和sys.stdout替换为打开以供写入的文

如何在Python中禁用标准错误流?这不起作用:

导入日志
logger=logging.getLogger()
logger.removeHandler(sys.stderr)
logger.warning('foobar')#在sys.stderr上发出'foobar'

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


此外,还可以将sys.stderr和sys.stdout替换为打开以供写入的文件。看见但我不建议这样做。

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


此外,还可以将sys.stderr和sys.stdout替换为打开以供写入的文件。看见但我不建议这样做。

没有必要转移stdout的注意力。以下是更好的方法:

import logging
class MyLogHandler(logging.Handler):
    def emit(self, record):
        pass

logging.getLogger().addHandler(MyLogHandler())
更简单的方法是:

logging.getLogger().setLevel(100)

不需要转移stdout。以下是更好的方法:

import logging
class MyLogHandler(logging.Handler):
    def emit(self, record):
        pass

logging.getLogger().addHandler(MyLogHandler())
更简单的方法是:

logging.getLogger().setLevel(100)
您可以使用:

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')
将您的_级别设置为日志记录。调试将显示所有级别的日志记录

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

以相同的方式更改每个处理程序使用函数的级别

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)
您可以使用:

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')
将您的_级别设置为日志记录。调试将显示所有级别的日志记录

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

以相同的方式更改每个处理程序使用函数的级别

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)

我找到了一个解决方案:

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

这将阻止将日志发送到包含控制台日志的上层记录器。

我找到了解决方案:

logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.
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')
这将阻止将日志发送到包括控制台日志的上层记录器。

我使用:

logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False
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')
我使用:

(这个问题由来已久,但对未来的搜索者而言)

更接近于原始海报的代码/意图,这在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")
我必须解决的问题是在添加一个新的stdout处理程序后删除它;如果没有处理程序,记录器代码似乎会自动重新添加标准输出。

(长期存在的问题,但供将来的搜索者使用)

更接近于原始海报的代码/意图,这在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")

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

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

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

从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)

这意味着当它被禁用时,不会调用任何处理程序,例如,过滤到一个非常高的值或设置一个无操作处理程序应该更有效。

这里有一些非常好的答案,但显然最简单的没有被过多考虑(仅从无穷远处考虑)

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

从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)

这意味着当它被禁用时,不会调用任何处理程序,例如,过滤到一个非常高的值或设置一个无操作处理程序应该更有效。

使用上下文管理器-[最简单的处理程序]

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的用例

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

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

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的用例

# 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"}
你也可以:

handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
你也可以:

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

要完全禁用日志记录

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3
logging.disable(logging.NOTSET)
要启用日志记录

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3
logging.disable(logging.NOTSET)

其他答案提供了无法完全解决问题的变通方法,例如

logging.getLogger().disabled = True
对于大于50的部分
n

logging.disable(n)
第一种解决方案的问题是,它只适用于根记录器。使用(比如)logging.getLogger(\uuuu name\uuuuu)创建的其他记录器不会被此方法禁用

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

这可以通过以下措施加以预防:

logging.disable(sys.maxint)

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

要完全禁用日志记录,请执行以下操作:

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3
logging.disable(logging.NOTSET)
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')
要启用日志记录

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3
logging.disable(logging.NOTSET)

其他答案提供了无法完全解决问题的变通方法,例如

logging.getLogger().disabled = True
对于大于50的部分
n

logging.disable(n)
第一种解决方案的问题是,它只适用于根记录器。使用(比如)logging.getLogger(\uuuu name\uuuuu)创建的其他记录器不会被此方法禁用

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

这可以通过以下措施加以预防:

logging.disable(sys.maxint)
据我所知(查看后),这是完全禁用日志记录的唯一方法

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