Вы знаете какой-либо простой способ найти регистрирующийся вызов, который бросает "недостаточно аргументов в пользу строки формата". На моей рабочей станции я изменил 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)
Вообще, лучший способ поймать исключение (включая то, которое вы упомянули) - поместить подозрительный код в 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 - не лучший способ работы в производственной среде (он неустойчив к обновлениям системы, его трудно понять и поддерживать и т.д.), но он может быть приемлем для отладки и тестирования.
Найти вызов журнала, который выдает «недостаточно аргументов для строки формата».
Я ищу источник всех вызовов журналирования. Их не так много: .info (
, .warn (
, .debug (
, .error (
, ) .critical (
, .exception (
, .log (
.
) Один из этих методов имеет формат без достаточного количества аргументов. Обычно его легко обнаружить, поскольку сообщение будут иметь операторы форматирования "%".
Если ваше приложение единообразно вызывает все регистраторы logger
, это будет еще проще, так как вы можете упростить grep для logger.
. .