Поиск источника ошибок формата при использовании регистрации в Python - PullRequest
7 голосов
/ 26 февраля 2011

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

Traceback (most recent call last):
  File "/usr/lib/python2.6/logging/__init__.py", line 768, in emit
    msg = self.format(record)
  File "/usr/lib/python2.6/logging/__init__.py", line 648, in format
    return fmt.format(record)
  File "/usr/lib/python2.6/logging/__init__.py", line 436, in format
    record.message = record.getMessage()
  File "/usr/lib/python2.6/logging/__init__.py", line 306, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting

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

Ответы [ 5 ]

6 голосов
/ 27 сентября 2011

Вместо того, чтобы редактировать установленный код Python, вы также можете найти такие ошибки:

    def handleError(record):
        raise RuntimeError(record)
    handler.handleError = handleError

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

5 голосов
/ 26 февраля 2011

Модуль ведения журнала предназначен для предотвращения уничтожения остальной части кода ошибочными сообщениями журнала, поэтому метод emit перехватывает ошибки и передает их методу handleError. Для вас проще всего временно отредактировать /usr/lib/python2.6/logging/__init__.py и найти handleError. Это выглядит примерно так:

def handleError(self, record):
    """
    Handle errors which occur during an emit() call.

    This method should be called from handlers when an exception is
    encountered during an emit() call. If raiseExceptions is false,
    exceptions get silently ignored. This is what is mostly wanted
    for a logging system - most users will not care about errors in
    the logging system, they are more interested in application errors.
    You could, however, replace this with a custom handler if you wish.
    The record which was being processed is passed in to this method.
    """
    if raiseExceptions:
        ei = sys.exc_info()
        try:
            traceback.print_exception(ei[0], ei[1], ei[2],
                                      None, sys.stderr)
            sys.stderr.write('Logged from file %s, line %s\n' % (
                             record.filename, record.lineno))
        except IOError:
            pass    # see issue 5971
        finally:
            del ei

Теперь временно отредактируйте его. Вставка простого raise в начале должна гарантировать, что ошибка распространяется на ваш код, а не на проглатывание. Как только вы исправите проблему, просто восстановите код регистрации.

3 голосов
/ 07 апреля 2015

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

Моя проблема заключалась в том, что я заменил все вхождения печати на logging.info, поэтому допустимая строка типа print('a',a) стала logging.info('a',a) (но вместо нее должна быть logging.info('a %s'%a).

На это также указывалось в Как отследить ошибки журналирования? , но в исследовании это не выяснилось

1 голос
/ 16 октября 2012

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

class DebugFormatter(logging.Formatter):
    def format(self, record):
        try:
            return super(DebugFormatter, self).format(record)
        except:
            print "Unable to format record"
            print "record.filename ", record.filename
            print "record.lineno ", record.lineno
            print "record.msg ", record.msg
            print "record.args: ",record.args
            raise


FORMAT = '%(levelname)s %(filename)s:%(lineno)d  %(message)s'
formatter = DebugFormatter(FORMAT)
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
0 голосов
/ 22 января 2019

Была такая же проблема Такой Traceback возникает из-за неправильного имени формата. Поэтому при создании формата для файла журнала проверьте имя формата один раз в документации по Python: "https://docs.python.org/3/library/logging.html#formatter-objects"

...