Python日志记录中的静默错误

2024-09-29 21:34:56 发布

您现在位置:Python中文网/ 问答频道 /正文

在我们的系统中,我们使用Python日志模块。我们在格式化字符串以写入日志时遇到了一些异常情况。 例如:

log.info(f"message {di[key]}")

由于di没有键,它将引发异常并中断脚本流。 因为这是一条“唯一”的日志消息,所以我更喜欢先释放这个日志消息,然后中断流程

在C++中,我会使用宏来捕获Log.FIN调用中的所有内容。

我能想到的最佳解决方案是:

class SafeLog:
    def __init__(self, log):
        self.log = log

    def __enter__(self):
        return self.log

    def __exit__(self, type, value, traceback):
        # Log the exception and prevent from propagate
        self.log.exception("Error writing to log")
        return True

但它需要在任何地方使用with

with SafeLog(log) as safelog:
    safelog.info(f"message {di[key]}")

尽管我认为更多的测试用例将具有更好的覆盖率并减少此类错误,但我仍然想知道是否有一种方法可以在Python中实现同样的效果

谢谢


Tags: keyselfinfolog消息messagereturn系统
1条回答
网友
1楼 · 发布于 2024-09-29 21:34:56

由于错误与日志记录本身无关,但与日志记录之前所做的操作无关,因此需要在日志调用周围包装一些内容,而不与它的参数交互。遗憾的是,with语句或try/except语句是我所知道的唯一这样做的语句。我也考虑过decorator,但它们在这里不起作用,因为它们在调用包装器函数之前使用参数

一个真正不那么漂亮的解决方案是只将一个with语句包装在更大的代码块周围(如果它只在一个模块中,那么可能是全部)

或者以后再做手术怎么样?但这意味着您需要为不同的用例编写大量样板代码:

import logging


class CustomLogger(logging.Logger):
    def division(self, a, b):
        try:
            super().info("%d / %d = %d", a, b, a / b)
        except Exception as exc:
            super().error("Log the exception %s", exc_info=1)


logging.setLoggerClass(CustomLogger)
logging.basicConfig(level=logging.DEBUG)
log: CustomLogger = logging.getLogger(__name__)

log.division(5, 1)

最后但并非最不重要的一点是在尝试记录数据之前避免异常和检测数据中的不一致性(在记录之前执行操作)。walrus操作符可以在这里派上用场,以便立即进行赋值和if语句:

if (dictelement:= dict_.get('keyname', None)):
    log.info(f"something with {dictelement}")
else:
    log.error("Something went wrong...")

相关问题 更多 >

    热门问题