Как отключить и снова включить ведение журнала консоли в Python?
Я использую модуль 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, а не другую?
Ответы
Ответ 1
Я нашел решение для этого:
logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.
Это предотвратит отправку журнала в верхний регистратор, который включает ведение журнала консоли.
Ответ 2
Я использую:
logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False
Ответ 3
Вы можете использовать:
logging.basicConfig(level=your_level)
где ваш_уровень является одним из следующих:
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL
Итак, если вы установите your_level на logging.CRITICAL, вы получите только критические сообщения, отправленные:
logging.critical('This is a critical error message')
Настройка your_level на logging.DEBUG отобразит все уровни ведения журнала.
Подробнее см. примеры ведения журнала.
Таким же образом, чтобы изменить уровень для каждого обработчика, используйте функцию 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)
Ответ 4
(длинный мертвый вопрос, но для будущих искателей)
Ближе к исходному коду/намерению плаката, это работает для меня под 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 после добавления нового; появляется код регистратора для автоматического повторного добавления stdout, если нет обработчиков.
Ответ 5
Контекстный менеджер
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()
Ответ 6
Чтобы полностью отключить ведение журнала:
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)
насколько я могу судить (после просмотра источника), это единственный способ полностью отключить ведение журнала.
Ответ 7
Здесь есть несколько действительно хороших ответов, но, по-видимому, простейшие не принимаются слишком много внимания (только от infinito).
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.
Ответ 8
Не нужно переадресовывать stdout. Вот лучший способ сделать это:
import logging
class MyLogHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger().addHandler(MyLogHandler())
Еще проще:
logging.getLogger().setLevel(100)
Ответ 9
Я не очень хорошо знаю модуль протоколирования, но я использую его так, как обычно, я хочу отключить только отладочные (или информационные) сообщения. Вы можете использовать Handler.setLevel()
, чтобы установить уровень ведения журнала на CRITICAL или выше.
Кроме того, вы можете заменить sys.stderr и sys.stdout файлом, открытым для записи. См. http://docs.python.org/library/sys.html#sys. stdout. Но я бы не рекомендовал этого.
Ответ 10
Вы также можете:
handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
Ответ 11
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
Ответ 12
Если вы хотите временно отключить определенный регистратор, вот что было сделано.
Журнал примеров
2019-10-02 21:28:45,663 django.request PID: 8 Internal Server Error: /service_portal/get_all_sites
Код
django_request_logger = logging.getLogger('django.request')
django_request_logger.disabled = True
django_request_logger.disabled = False
Ответ 13
подкласс обработчик, который вы хотите временно отключить:
class ToggledHandler(logging.StreamHandler):
"""A handler one can turn on and off"""
def __init__(self, args, kwargs):
super(ToggledHandler, self).__init__(*args, **kwargs)
self.enabled = True # enabled by default
def enable(self):
"""enables"""
self.enabled = True
def disable(self):
"""disables"""
self.enabled = False
def emit(self, record):
"""emits, if enabled"""
if self.enabled:
# this is taken from the super emit, implement your own
try:
msg = self.format(record)
stream = self.stream
stream.write(msg)
stream.write(self.terminator)
self.flush()
except Exception:
self.handleError(record)
найти обработчик по имени довольно просто:
_handler = [x for x in logging.getLogger('').handlers if x.name == your_handler_name]
if len(_handler) == 1:
_handler = _handler[0]
else:
raise Exception('Expected one handler but found {}'.format(len(_handler))
однажды найден:
_handler.disable()
doStuff()
_handler.enable()