Я наблюдаю, как модуль логирования ведет себя странно. Я что-то упустил?
Обычно я использую два обработчика: StreamHandler для регистрации только INFO и выше на консоли и FileHandler, который также будет обрабатывать всю информацию DEBUG.
Это работало нормально, пока я не решил использовать другой формат для исключений. Мне нужна была полная трассировка стека в файле, но только тип исключения и значение на консоли. Поскольку в обработчиках есть функция setFormatter, и, поскольку кажется, что написать подкласс ведения журналов просто. Я думаю, что это сработает.
Обработчик консоли и обработчик файлов имеют свои собственные средства форматирования. Операторы печати в коде подтверждают это. Однако при вызове logger.exception будет использоваться только formatException первого добавленного обработчика => исключение регистрируется в файле в том формате, который он должен иметь в консоли. Измените порядок строк logger.addHandler, а затем это formatException обработчика файла, который используется везде.
import logging
import sys
class ConsoleFormatter(logging.Formatter):
def formatException(self, exc_info):
# Ugly but obvious way to see who's talking.
return "CONSOLE EXCEPTION %s: %s" % exc_info[:2]
def setup(path):
logger = logging.getLogger()
#
file_handler = logging.FileHandler(path, mode='w')
if __debug__:
file_handler.setLevel(logging.DEBUG)
else:
file_handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s %(levelname)-8s "
"%(name)-16s %(message)s "
"[%(filename)s@%(lineno)d in %(funcName)s]")
file_handler.setFormatter(formatter)
#
console_handler = logging.StreamHandler(sys.stderr)
console_handler.setLevel(logging.INFO)
console_formatter = ConsoleFormatter("%(levelname)-8s - %(message)s")
console_handler.setFormatter(console_formatter)
# >>> FUN HAPPENS HERE <<<
# Only the formatter of the first handler is used ! Both on the console
# and in the file. Change the order of these two lines to see.
logger.addHandler(console_handler)
logger.addHandler(file_handler)
#
# Proof that the two handlers have different formatters:
print logger.handlers
print file_handler.formatter.formatException
print console_formatter.formatException
#
logger.setLevel(logging.DEBUG)
logger.info("Logger ready.")
setup('test.log')
logger = logging.getLogger()
logger.debug("Only visible in the file.")
try:
1/0
except ZeroDivisionError:
logger.exception("boom")
Что происходит?
РЕДАКТИРОВАТЬ: Кстати, я использую Python 2.6.
РЕДАКТИРОВАТЬ: Исправлена опечатка в коде с именем переменной "console_formatter".