Настройка расширенной регистрации Python - PullRequest
4 голосов
/ 09 февраля 2012

Я бы хотел использовать логирование для своих модулей, но я не уверен, как разработать следующие требования:

  • нормальные уровни ведения журнала (информация, ошибка, предупреждение, отладка), а также некоторые дополнительные более подробные уровни отладки
  • протоколирование сообщений может иметь разные типы; некоторые предназначены для разработчика, некоторые предназначены для пользователя; эти типы идут на разные выходы
  • ошибки должны идти к stderr
  • Мне также нужно отслеживать, какая строка модуля / функции / кода написала сообщение отладки, чтобы я мог активировать или деактивировать отдельные сообщения отладки в конфигурации
  • Мне нужно отслеживать, возникли ли ошибки вообще, чтобы в итоге выполнить sys.exit() в конце программы
  • все сообщения должны идти на stdout, пока не будут настроены регистраторы

Я прочитал документацию по ведению журнала, но я не уверен, как наиболее рационально использовать модуль ведения журнала с вышеуказанными требованиями (как использовать концепцию Logger, Handler, Filter, ...). Можете ли вы указать на идею, чтобы настроить это? (например, модуль записи с двумя регистраторами «пользователь», «разработчик»; наследуется от Logger; делать getLogger(__name__); сохранять флаг ошибки следующим образом ... и т. д.)

1 Ответ

9 голосов
/ 09 февраля 2012

1) Добавление более подробных уровней отладки.

Вы думали об этом?

Посмотрите, что говорит документ :

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

Взгляните также на Когда использовать ведение журнала , есть две очень хорошие таблицы, объясняющие, когда что использовать.

В любом случае, если вы считаете, что вам понадобятся эти дополнительные уровни ведения журнала, взгляните на: logging.addLevelName().

2) Некоторые сообщения регистрации для разработчика, а некоторые дляпользователь

Используйте разные семейства регистраторов с разными обработчиками.В базе каждого семейства установите Logger.propagate на False.

3) Ошибки должны быть равны stderr

Это уже происходит по умолчанию с StreamHandler:

регистрация классов .StreamHandler (stream = None)

Возвращает новый экземпляр класса StreamHandler.Если указан поток, экземпляр будет использовать его для регистрации выходных данных;в противном случае будет использоваться sys.stderr .

4) Отслеживать источник сообщения журнала

Получить регистраторы с разными именами,а в вашем Formatter используйте строки форматирования с %(name)s.

5) Все сообщения должны идти на stdout, пока регистраторы не будут настроены

Настройка вашегоСистема регистрации должна быть одной из первых вещей, которую я должен сделать, поэтому я не понимаю, что это значит.Если вам нужно отправлять сообщения на стандартный вывод, используйте print, как это должно быть и уже объяснено в Когда использовать ведение журнала .

Последний совет: внимательно прочитайте Ведение журнала Кулинарная книга , поскольку она довольно хорошо покрывает то, что вам нужно.


Из комментария : Как бы я разработал, чтобы вывод на другойисточники, а также фильтровать мой модуль?

Я бы не стал фильтровать в первую очередь, файлеры трудно обслуживать, и если они все находятся в одном месте, то в этом месте будет слишком много информации.Каждый модуль должен получить и установить собственный Logger (со своими собственными обработчиками или фильтрами), используя или не используя родительский параметр.

Очень быстрый пример:

# at the very beginning
root = logging.getLogger()
fallback_handler = logging.StreamHandler(stream=sys.stdout)
root.addHandler(fallback_handler)

# first.py
first_logger = logging.getLogger('first')
first_logger.parent = False
# ... set 'first' logger as you wish
class Foo:
    def __init__(self):
        self.logger = logging.getLogger('first.Foo')
    def baz(self):
        self.logger.info("I'm in baz")

# second.py
second_logger = logging.getLogger('first.second') # to use the same settings

# third.py
abstract_logger = logging.getLogger('abs')
abstract_logger.parent = False
# ... set 'abs' logger
third_logger = logging.getLogger('abs.third')
# ... set 'abs.third' particular settings

# fourth.py
fourth_logger = logging.getLogger('abs.fourth')
# [...]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...