Как отключить и снова включить консольное ведение журнала в Python? - PullRequest
129 голосов
/ 15 февраля 2010

Я использую модуль 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, а не другую?

Ответы [ 12 ]

174 голосов
/ 15 февраля 2010

Я нашел решение для этого:

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

Это предотвратит отправку журналов на верхний регистратор, который включает журналирование консоли.

80 голосов
/ 25 июня 2010

Я использую:

logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False
60 голосов
/ 15 февраля 2010

Вы можете использовать:

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

Установка your_level на logging.DEBUG покажет всеуровни ведения журнала.

Для получения более подробной информации ознакомьтесь с примерами ведения журнала.

Таким же образом, чтобы изменить уровень для каждого обработчика, используйте обработчик .Функция 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)
44 голосов
/ 23 июня 2011

(длинный мертвый вопрос, но для будущих искателей)

Ближе к исходному коду / намерению автора, это работает для меня под 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, если нет обработчиков.

35 голосов
/ 27 ноября 2013

Диспетчер контекста

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()
25 голосов
/ 13 декабря 2011

Здесь есть несколько действительно хороших ответов, но, видимо, самое простое не принимается во внимание (только из 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)

Это означает, что когда он отключен, никакой обработчик не вызывается, и он должен быть более эффективным, чем фильтрация с очень высоким значением или установка, например, неоперативного обработчика.

23 голосов
/ 21 мая 2017

Чтобы полностью отключить ведение журнала :

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)

, насколько я могу судить (после просмотра источника ), это единственный способ полностью отключить ведение журнала.

10 голосов
/ 15 февраля 2010

Нет необходимости перенаправлять стандартный вывод. Вот лучший способ сделать это:

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

logging.getLogger().addHandler(MyLogHandler())

Еще более простой способ:

logging.getLogger().setLevel(100)
2 голосов
/ 11 марта 2015

Вы также можете:

handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
2 голосов
/ 15 февраля 2010

Я не очень хорошо знаю модуль ведения журнала, но я использую его так, как обычно хочу отключить только сообщения отладки (или информацию). Вы можете использовать Handler.setLevel(), чтобы установить уровень ведения журнала на КРИТИЧЕСКИЙ или выше.

Также вы можете заменить sys.stderr и sys.stdout файлом, открытым для записи. См. http://docs.python.org/library/sys.html#sys.stdout. Но я бы не советовал.

...