В настоящее время я загружаю регистратор python следующим образом:
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("myprogram")
и использовать его, например, так:
[...]
except FileNotFoundError:
log.exception("could not open configuration file")
sys.exit(1)
Тем не менее, это всегда будет печатать трассировку вместе с сообщением об ошибке:
ERROR:myprogram:could not open configuration file
Traceback (most recent call last):
[...]
FileNotFoundError: [Errno 2] No such file or directory:
'not/existing/file.yml'
Я не хочу, чтобы трассировка в нормальном выходе ошибки. Вместо этого он должен печатать только мое сообщение об ошибке и информацию об исключении ("Нет такого файла...").
Каков рекомендуемый способ показа трассировки только тогда, когда loglevel установлен в logging.DEBUG
?
Я бы использовал комбинацию exc_info
и .getEffectiveLevel
:
try:
...
except FileNotFoundError as ex:
logger.error(ex, exc_info=log.getEffectiveLevel() == logging.DEBUG)
Таким образом, само исключение (FileNotFoundError
) всегда регистрируется, но stacktrace будет регистрироваться только в том случае, если уровень журнала отлаживается.
exc_info=True
исключение на уровне DEBUG
и установите exc_info=True
. logger.exception()
по существу является logger.error(..., exc_info=True)
, но вы можете регистрировать трассировки исключений на любом уровне:
log.debug("could not open configuration file", exc_info=True)
Это опция exc_info
которая важна; из документации:
Если
exc_info
не оценивается как false, это приводит к добавлению информации о исключении в сообщение регистрации. Если используется кортеж исключений (в формате, возвращаемомsys.exc_info()
) или экземпляр исключения, он используется; в противном случаеsys.exc_info()
чтобы получить информацию об исключении.
Возможно, вы захотите использовать печать (для stdout или stderr) для связи с конечным пользователем:
except FileNotFoundError as e:
log.debug("could not open configuration file", exc_info=True)
print("Could not open configuration file:", e.strerror, file=sys.stderr)
sys.exit(1)
Я включил сообщение об ошибке системы в выходной файл без представления FileNotFoundError(...)
.
Если вы используете парсер для командной строки, например argparse
или click
, тогда используйте API обратной связи с пользователями (который обычно также включает в себя выход).
Вы также можете сделать модуль протоколирования для создания сообщений на уровне пользователя, но если вы хотите, чтобы один вызов журнала вызывал отладочные трассировки в файле и удобный для пользователя вывод на консоли, вам нужно будет настроить отдельные обработчики для этих целей -cases с обработчиком консоли с помощью пользовательского Formatter()
класса для переопределения formatException()
метода, чтобы изменить, как показаны исключения. Гораздо проще и понятнее отделять протоколирование и связь с конечным пользователем.
Formatter
чтобы изменить способ включения информации об исключениях в вывод , Вместо этого я обычно просто использую то, что изложил в своем ответе.
def err(*args, **kwargs): log.error(*args, exc_info=log.getEffectiveLevel() == logging.DEBUG, **kwargs)
делает именно то, что я хочу, спасибо!