Простой способ найти “недостаточно аргументов …” в библиотеке входа Python

Вы знаете какой-либо простой способ найти регистрирующийся вызов, который бросает "недостаточно аргументов в пользу строки формата". На моей рабочей станции я изменил logging/__init__.py распечатать сообщение, таким образом, я могу легко найти строку в источнике.

Но у Вас есть какая-либо идея, что сделать на тестовой среде, где Вы не можете изменить библиотеку стандарта Python, ни выполнить pdb легко?

Примечание: traceback бессмыслен, и он пойман регистрирующейся библиотекой. Вот traceback:

  File "/usr/lib/python2.6/logging/handlers.py", line 71, in emit
    if self.shouldRollover(record):
  File "/usr/lib/python2.6/logging/handlers.py", line 144, in shouldRollover
    msg = "%s\n" % 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 enough arguments for format string

И вот код в стандартной библиотеке, которые фиксируют ошибку

    try:
        if self.shouldRollover(record):
            self.doRollover()
        logging.FileHandler.emit(self, record)
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        self.handleError(record)

Решение, как предложил Alex: я перенес getMessage для печати сообщения и args. Вот код:

def print_log_record_on_error(func):
    def wrap(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except:
            import sys
            print >>sys.stderr, "Unable to create log message msg=%r, args=%r " % (
                                getattr(self, 'msg', '?'), getattr(self, 'args', '?'))
            raise
    return wrap
import logging
logging.LogRecord.getMessage = print_log_record_on_error(logging.LogRecord.getMessage)
7
задан Piotr Czapla 19 March 2010 в 14:41
поделиться

2 ответа

Вообще, лучший способ поймать исключение (включая то, которое вы упомянули) - поместить подозрительный код в try предложение try/except; в except предложении вы можете использовать traceback модуль или другие способы определить ошибочное утверждение.

Иначе не пойманные исключения попадают в sys.excepthook, что является еще одним способом получить обратный след, если это необходимо.

Однако, я не думаю, что модуль logging имеет архитектурно оформленный способ сказать ему "позволить исключениям распространяться" - в этом случае вашим лучшим вариантом, каким бы грязным он ни был, вероятно, будет обезьянье исправление. Другими словами, вы обычно можете "изменить стандартную библиотеку Python" во время выполнения - путем установки идентификаторов в свои собственные функции / классы / и т.д., обернув их в стандартные. Например, если вы знаете, что проблема связана с вызовом logging.warning, "пробный вариант" monkeypatch может быть таким:

import logging, traceback

orgwarn = logging.warning
def mywarn(msg, *a):
  try: res = msg % a
  except TypeError:
    traceback.print_exc()
  return orgwarn(msg, *a)
logging.warning = mywarn

Есть более чистые способы, но они могут быть несколько громоздкими (например, создать свой собственный класс logger и установить его в качестве корневого logger). Monkey-patching - не лучший способ работы в производственной среде (он неустойчив к обновлениям системы, его трудно понять и поддерживать и т.д.), но он может быть приемлем для отладки и тестирования.

2
ответ дан 7 December 2019 в 18:42
поделиться

Найти вызов журнала, который выдает «недостаточно аргументов для строки формата».

Я ищу источник всех вызовов журналирования. Их не так много: .info (, .warn (, .debug (, .error (, ) .critical (, .exception (, .log (.

) Один из этих методов имеет формат без достаточного количества аргументов. Обычно его легко обнаружить, поскольку сообщение будут иметь операторы форматирования "%".

Если ваше приложение единообразно вызывает все регистраторы logger , это будет еще проще, так как вы можете упростить grep для logger. . .

0
ответ дан 7 December 2019 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: