Как обрабатывать ошибки формата Python в шаблоне сообщения журнала? - PullRequest
0 голосов
/ 25 июня 2019

Я иногда путаю формат в строках шаблона для модуля logging Python, например:

import logging
logging.warning('%d', 1, 2)  # BROKEN

В консоли я вижу предупреждение (трассировка стека опущена):

--- Logging error ---
Traceback (most recent call last):
  File ".../python3.7/logging/__init__.py", line 1034, in emit
    msg = self.format(record)
  File ".../python3.7/logging/__init__.py", line 880, in format
    return fmt.format(record)
  File ".../python3.7/logging/__init__.py", line 619, in format
    record.message = record.getMessage()
  File ".../python3.7/logging/__init__.py", line 380, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
    ...
Message: '%d'
Arguments: (1, 2)

Однако ни мое сообщение, ни это предупреждение не отправляются обработчику журнала, который фактически записал бы его в файл журнала, отправил бы его в logstash и т. Д.

Я знаю, что могу найти эти ошибки с pylint , используя logging-too-less-args (E1206) и logging-too-many-args (E1205), однако я все еще предпочел бы некоторое время выполнения отступление на случай, если один из них ускользнет.

Так что, если не следить за stderr из-за пределов Python, такие ошибки легко не заметить.

Есть ли способ по-прежнему регистрировать сообщение с маркером и основными деталями, например:

[LogBug] message = '% d', аргументы = (1, 2)

Таким образом, исходная информация все равно будет сохранена, и можно будет периодически сканировать файлы журналов для маркера [LogBug].

1 Ответ

0 голосов
/ 25 июня 2019

Не могли бы вы использовать try / except, может быть?Возможно использование re для извлечения сообщения и аргументов из сообщения об исключении

import re

try:
    logging.warning('%d', 1, 2)
except TypeError as e:
    message = re.search(r'Message: ([^\n]*)[\n$]', e.message).group(1)
    arguments = re.search(r'Arguments: ([^\n]*)[\n$]', e.message).group(1)
    logging.error("[LogBug] message=%s, arguments=%s",message, arguments)
    # if you want, you could re-raise this exception

Если вы все-таки воспользуетесь этим решением, вам, возможно, придется учесть и обработку ошибок в случае, если TypeError не совсемв формате, который вы ожидаете, и, таким образом, регулярное выражение не будет работать и вызовет AttributeError, когда вы попытаетесь вызвать .group().

Нет предела тому, насколько глубоко вы можете пойти с этим, потенциально, но если вы сделаете действительно действительно уверенным , что эта проверка работает должным образом, тогда она сможет перехватить остальных.


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

i, j = 1, 2
logging.warning(f"{i}")
...