6

我目前正在像这样加载 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什么?

4

3 回答 3

5

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(...)

如果您使用类似argparseor的命令行参数解析器click,请务必使用他们的用户反馈 API(通常也包括退出)。

也可以使日志记录模块产生用户级消息,但如果您希望单个记录器调用在文件中产生调试友好的回溯并在控制台上产生用户友好的输出,则必须为这些用途配置单独的处理程序- 控制台处理程序使用自定义Formatter()覆盖formatException()方法以更改异常显示方式的情况。将日志记录和最终用户通信分开更加容易和清晰。

于 2018-09-23T12:16:00.293 回答
5

我会使用exc_info和的组合.getEffectiveLevel

try:
    ...
except FileNotFoundError as ex:
   logger.error(ex, exc_info=log.getEffectiveLevel() == logging.DEBUG)

这样,异常本身 ( FileNotFoundError) 总是被记录下来,但只有在日志级别为调试时才会记录堆栈跟踪。

于 2018-09-23T12:16:38.860 回答
0

也可以直接使用logging.debugplus traceback:

try:
    do_something()
except Exception as e:
    logger.error("Unhandled exception: %s", e)
    logger.debug("Traceback: %s", traceback.format_exc())

编辑:logger.debug("", exc_info=True)可以用来代替logger.debug("Traceback: %s", traceback.format_exc()).

于 2020-11-15T05:33:41.250 回答