python日志记录仅在调试中打印回溯

Seb*_*ark 6 python logging

我目前正在像这样加载 python 记录器:

import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("myprogram")
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

[...]
except FileNotFoundError:
    log.exception("could not open configuration file")
    sys.exit(1)
Run Code Online (Sandbox Code Playgroud)

但是,这将始终与错误消息一起打印回溯:

ERROR:myprogram:could not open configuration file
Traceback (most recent call last):
[...]
FileNotFoundError: [Errno 2] No such file or directory: 
'not/existing/file.yml'
Run Code Online (Sandbox Code Playgroud)

我不想要正常错误输出中的回溯。相反,它应该只打印我的错误消息和异常信息(“没有这样的文件...”)。

仅当日志级别设置为 时,推荐的显示回溯的方式是logging.DEBUG什么?

Mar*_*ers 5

DEBUG改为在级别记录异常并设置exc_info=True. logger.exception()本质上是一个logger.error(..., exc_info=True)调用,但您可以在任何级别记录异常回溯:

log.debug("could not open configuration file", exc_info=True)
Run Code Online (Sandbox Code Playgroud)

重要的是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)
Run Code Online (Sandbox Code Playgroud)

我在没有表示的打印输出中包含了系统错误消息FileNotFoundError(...)

如果您使用命令行参数解析器,例如argparseclick,那么请使用他们的用户反馈 API(通常也包括退出)。

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


Dee*_*ace 5

我会使用的组合exc_info.getEffectiveLevel

try:
    ...
except FileNotFoundError as ex:
   logger.error(ex, exc_info=log.getEffectiveLevel() == logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

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