例外:仅记录一次追溯

时间:2019-10-18 12:42:32

标签: python exception logging

我正在摸索最好的做法,以便在日志文件中仅一次进行追溯。请注意,总的来说,我知道如何将追溯信息记录到日志中。

假设我有一个大型程序,其中包含要导入的各种模块和功能,这样它就可以具有一定的深度并且记录器已正确设置。

每当发生异常时,我都会执行以下操作:

try:
    do_something()
except MyError as err:
    log.error("The error MyError occurred", exc_info=err)
    raise

请注意,追溯是通过选项exc_info=err写入日志的。

现在的问题是,当所有事情变得更加复杂和嵌套时,我无法控制将这种回溯写入日志的频率,并且变得非常混乱。

我当前针对此问题的解决方案的情况示例如下:

from other_module import other_f

def main():

    try:
        # do something
        val = other_f()

    except (AlreadyLoggedError1, AlreadyLoggedError2, AlreadyLoggedError3):
        # The error was caught within other_f() or deeper and 
        # already logged with traceback info where it occurred
        # After logging it was raised like in the above example
        # I do not want to log it again, so it is just raised
        raise
    except BroaderException as err:
        # I cannot expect to have thought of all exceptions
        # So in case something unexpected happened 
        # I want to have the traceback logged here
        # since the error is not logged yet
        log.error("An unecpected error occured", exc_info=err)
        raise

此解决方案的问题是,我需要跟踪自己已经记录的所有异常,并且行except (AlreadyLoggedError1, AlreadyLoggedError2, ...)任意长,必须将其放置在main()和错误实际发生的位置。

所以我的问题是:是否有一些更好的(pythonic)方式来处理此问题?更具体地讲:我想提出一个信息,即该异常已经与异常一起记录,因此我不必像上面的示例一样通过额外的except块来解决这个问题。

1 个答案:

答案 0 :(得分:1)

通常用于较大型应用程序的解决方案是,低级代码如果仅要记录日志,则实际上不对其本身进行错误处理,而是将异常日志记录/处理置于代码中的最高级别,因为异常会根据需要增加气泡。例如,向诸如New Relic和Sentry之类的服务发送错误的库不需要您对可能引发错误的代码的每一小部分进行检测,它们被设置为仅捕获任何异常并将其发送到远程服务。进行汇总和跟踪。