Использование пользовательских классов форматирования с модулем Python logging.config - PullRequest
3 голосов
/ 09 февраля 2012

У меня есть следующий класс ведения журнала, который отлично работает, когда он назначен в качестве средства форматирования в коде. Он расширяет существующий форматер, добавляя строку к началу сообщения, которое необходимо зарегистрировать, чтобы показать важность сообщения. (Я не просто использую %(levelname)s в строке формата, потому что я не хочу показывать префиксы DEBUG или INFO.)

class PrependErrorLevelFormatter(logging.Formatter):
    def __init__(self, default):
        self._default_formatter = default
    def format(self, record):
        if record.levelno == logging.WARNING:
            record.msg = "[WARNING] " + record.msg
        elif record.levelno == logging.ERROR:
            record.msg = "[ERROR] " + record.msg
        elif record.levelno == logging.CRITICAL:
            record.msg = "[CRITICAL] " + record.msg
        return self._default_formatter.format(record)

Теперь я хочу иметь возможность назначить его через файл конфигурации, загруженный с помощью logging.config.fileConfig (). Я пробовал синтаксис, как это:

[formatter_PrependErrorLevelFormatter]
format=%(asctime)s  %(message)s
datefmt=%X
class=PrependErrorLevelFormatter

К сожалению, я получаю ошибки при разрешении этого класса:

  File "C:\Python27\lib\logging\config.py", line 70, in fileConfig
    formatters = _create_formatters(cp)
  File "C:\Python27\lib\logging\config.py", line 127, in _create_formatters
    c = _resolve(class_name)
  File "C:\Python27\lib\logging\config.py", line 88, in _resolve
    found = __import__(used)
ImportError: No module named PrependErrorLevelFormatter

Я попытался добавить префикс имени класса к имени модуля, в котором он находится, но получаю ту же ошибку. И даже если он может разрешить класс, он, вероятно, не будет работать из-за дополнительного аргумента форматера по умолчанию, который я должен предоставить.

Как мне добиться желаемого результата с помощью системы logging.config?

1 Ответ

8 голосов
/ 10 февраля 2012

Поскольку вы используете Python 2.7, вы можете использовать словарную конфигурацию, используя dictConfig(): это более гибко, чем fileConfig(), так как позволяет использовать произвольные вызываемые объекты в качестве фабрик для возврата, например, обработчиков, средства форматирования или фильтры.

Если у вас есть для использования fileConfig(), вам нужно будет создать вызываемый объект, который принимает строковые значения format и datefmt и возвращает экземплярвашего класса.Значение class нужно просто преобразовать в вызываемый, а не в реальный класс.Вот настройка, которая работает: В этой сущности у меня есть файл custfmt.py, который содержит определение средства форматирования, и сценарий fcfgtest.py, который использует его через fileConfig().Просто поместите файлы в «чистый» каталог и запустите fcfgtest.py - вы должны увидеть результат, подобный следующему:

20:17:59 debug message
20:17:59 info message
20:17:59 [WARNING] warning message
20:17:59 [ERROR] error message
20:17:59 [CRITICAL] critical message

, который, кажется, вам нужен.

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

class AltCustomFormatter(logging.Formatter):
    def format(self, record):
        if record.levelno in (logging.WARNING,
                              logging.ERROR,
                              logging.CRITICAL):
            record.msg = '[%s] %s' % (record.levelname, record.msg)
        return super(AltCustomFormatter , self).format(record)

Чтобы использовать это, вам не нужна отдельная заводская функция, поэтому вы можете просто использовать

class=custfmt.AltCustomFormatter

вместо

class=custfmt.factory

, и это должно сработать - это сработало для меня, когда я тестировал только сейчас, используя Python 2.7.1: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...