如何在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
当前回答
使用装饰器找到了一个优雅的解决方案,它解决了以下问题:如果您正在编写一个具有多个函数的模块,每个函数都有几个调试消息,并且您希望禁用除当前关注的函数之外的所有函数的登录,该怎么办?
你可以使用装饰器:
import logging, sys
logger = logging.getLogger()
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
def disable_debug_messages(func):
def wrapper(*args, **kwargs):
prev_state = logger.disabled
logger.disabled = True
result = func(*args, **kwargs)
logger.disabled = prev_state
return result
return wrapper
然后,你可以这样做:
@disable_debug_messages
def function_already_debugged():
...
logger.debug("This message won't be showed because of the decorator")
...
def function_being_focused():
...
logger.debug("This message will be showed")
...
即使从function_being_focused内部调用function_already_debug,也不会显示来自function_already_debug的调试消息。 这确保您将只看到您所关注的函数的调试消息。
希望能有所帮助!
其他回答
这将防止所有来自第三个库的日志记录,就像这里描述的那样 https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library
logging.getLogger('somelogger').addHandler(logging.NullHandler())
日志有以下结构:
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
我不是很了解日志模块,但是我使用它的方式是我通常只希望禁用调试(或信息)消息。您可以使用Handler.setLevel()将日志级别设置为CRITICAL或更高。
此外,您还可以替换sys。Stderr和sys。打开用于写入的文件的标准输出。见http://docs.python.org/library/sys.html # sys.stdout。但我不建议这样做。
这不是100%的解决方案,但这里没有一个答案解决了我的问题。我有自定义的日志模块,根据严重程度输出彩色文本。我需要禁用stdout输出,因为它复制了我的日志。我对将关键日志输出到控制台很满意,因为我几乎不使用它。我没有测试它是否为stderr,因为我没有在日志中使用它,但它应该与stdout的工作方式相同。它将CRITICAL设置为仅针对stdout的最小严重程度(如果请求则为stderr)。
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# disable terminal output - it is handled by this module
stdout_handler = logging.StreamHandler(sys.stdout)
# set terminal output to critical only - won't output lower levels
stdout_handler.setLevel(logging.CRITICAL)
# add adjusted stream handler
logger.addHandler(stdout_handler)
不需要转移标准输出。这里有一个更好的方法:
import logging
class MyLogHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger().addHandler(MyLogHandler())
一个更简单的方法是:
logging.getLogger().setLevel(100)