#python #python-3.x #logging
#python #python-3.x #ведение журнала
Вопрос:
Я ожидал, что следующий код выведет обе строки журнала
import logging
log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)
print(log.getEffectiveLevel())
log.debug('debug log')
log.critical('critical log')
Вывод
10
critical log
Уровень правильно установлен на 10
(что соответствует DEBUG
) и, несмотря на это log.debug('debug log')
, ничего не выводит — почему?
Комментарии:
1. вы имеете в виду печать журнала в
stdout
илиstderr
?2. @MiguelTrejo: в чем разница? сообщения отладки будут печататься в другом месте, кроме критических? И на это в другом месте не повлияет
.setLevel()
?3. Вы устанавливаете уровень только в самом регистраторе, а не в начальном обработчике, который будет использоваться для печати сообщения журнала со стандартной ошибкой. Обработчики и регистраторы имеют разные уровни, так что (например) один регистратор может записывать отладочные сообщения на консоль, но только серьезные ошибки в обработчик SMTP, чтобы уведомить кого-то о проблеме, которую необходимо решить.
Ответ №1:
Вы не настроили систему ведения журнала, поэтому она по-прежнему использует значения по умолчанию (предупреждение об уровне для корневого регистратора).
https://docs.python.org/3/library/logging.html#logging.basicConfig говорит basicConfig
Выполняет базовую конфигурацию для системы ведения журнала, создавая StreamHandler с форматером по умолчанию и добавляя его в корневой регистратор.
Настройка системы ведения журнала с basicConfig
помощью first создаст обработчик и форматировщик, которые будет использовать ваш регистратор:
logging.basicConfig()
log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)
print(log.getEffectiveLevel())
log.debug('debug log')
log.critical('critical log')
Выводит:
10
DEBUG:hello:debug log
CRITICAL:hello:critical log
В Logger.callHandlers каждый обработчик сравнивает уровень записи журнала со своим уровнем. Если обработчиков нет, он будет использовать значение по умолчанию для ПРЕДУПРЕЖДЕНИЯ.
Комментарии:
1. Спасибо — так что в моем случае мой
log
вывод по-прежнему зависитWARNING
от уровня по умолчанию, несмотря на то, что он фактически установлен наDEBUG
?2. Да, вы настроили свой регистратор на DEBUG, но он не подключен к обработчику (его еще нет). Попробуйте
print('handlers=', logging.getLogger().handlers)
с и безbasicConfig
. Документы по обработчику ( docs.python.org/3/library/logging.html#logging . Обработчик ) показывает, что__init__(level=NOTSET)
метод принимает параметр уровня.3. Но если обработчиков нет, как может отображаться сообщение о критическом уровне? Потому что это было обработано регистратором корневого уровня? (и, несмотря на наличие собственного регистратора, каким-то образом подключился к корневому регистратору?)
4. Если их нет, используется уровень ПРЕДУПРЕЖДЕНИЯ по умолчанию: github.com/python/cpython/blob/master/Lib/logging /…
5. @WoJ причина, по которой что-то отображается, заключается в том, что когда обработчики не настроены, используется внутренний «обработчик последней инстанции», который имеет уровень
WARNING
. Документировано здесь: docs.python.org/3/library /…
Ответ №2:
С помощью a StreamHandler
это будет
отправляет выходные данные журнала в такие потоки, как sys.stdout, sys.stderr или любой файлоподобный объект «
согласно документации
import logging
import sys
# Initialize Logger and set Level to DEBUG
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# Initialize a Handler to print to stdout
handler = logging.StreamHandler(sys.stdout)
# Format Handler output
logFormatter = logging.Formatter(
"%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p"
)
handler.setFormatter(logFormatter)
# Set Handler Level to DEBUG
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.debug('Debug Info')
>>> 09/19/2020 09:01:00 PM Debug Info
Ответ №3:
Вам нужно добавить обработчик потока
import logging
log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)
# # Create a file handler to store the logs
file_handler = logging.FileHandler('test.log')
log.addHandler(file_handler)
# # Send output to terminal
stream_handler = logging.StreamHandler()
log.addHandler(stream_handler)
log.debug('debug log')