news 2026/4/19 5:35:24

日志碎片:仅显示导致错误的日志

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
日志碎片:仅显示导致错误的日志

原文:towardsdatascience.com/log-breadcrumbs-only-show-logs-leading-up-to-an-error-82b9f4c15520

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a40ff83722411f873098d942f36a4432.png

图片由 Daniel Tseng / Unsplash 提供

在这篇文章中,我们将探讨一种高效记录日志碎片的途径,只显示导致错误的日志。我们将仅使用 Python 的标准日志库来创建一个高效的日志设置,仅在发生异常时捕获调试日志。这种方法提供了对导致问题的步骤的详细视图,同时减少混乱最小化 I/O。让我们开始编码!


为什么记录日志碎片?

当发生错误时,你希望尽可能多地拥有信息,以便引导你找到代码中的问题。记录大量信息在这方面非常有用。

坏处是,所有这些日志都需要被处理。然后需要将它们写入文件或通过 HTTP 发送到端点,这可能会影响你的应用程序或服务器的性能。此外,它可能会使日志变得混乱,使得在发生错误时更难找到相关信息。

面包屑方法“忽略”例如所有debug日志,除非发生错误。这允许你记录大量关于错误的详细信息,同时保持性能和概览在水平。


设置面包屑路径

下面是一个简单的函数,divide,其中包含帮助跟踪其内部行为的调试日志。理想情况下,我们不想每次都看到日志,只想在发生错误时看到,这样我们就可以看到函数尝试除以哪两个数字。

defdivide(a,b):logger.debug(f"Dividing [{a}] by [{b}]")returna/bforvaluein[1,2,3,4,5,6,7,8,9,'not a number',0]:try:logger.debug(f"start dividing..")res=divide(a=10,b=value)exceptExceptionase:logger.error(f"❌An exception occurred:{e}")

前几个值(19)成功进行了除法运算,在这些情况下通常不需要调试日志。

然而,对于像not a number0这样的错误输入,捕获debug日志会提供有价值的上下文。我们的。我们如何回到过去检索日志?

用一行代码将你的 Python 函数转换为装饰器


解决方案概述

要创建面包屑,我们将配置我们的日志记录器以使用两个处理器:

  • StreamHandler:仅显示INFO级别及以上的消息

  • MemoryHandler:临时存储DEBUG消息,并在发生错误时将它们传递给StreamHandler

此设置不会显示DEBUG日志,因为 StreamHandler 被设置为INFO。我们可以临时将DEBUG消息存储在 MemoryHandler 中,当我们检测到错误时,将消息刷新到 StreamHandler。然后,它将显示存储的DEBUG消息。


配置日志记录器

下面是如何使用StreamHandler进行常规输出和MemoryHandler进行缓冲DEBUG日志来配置记录器的示例:

importloggingfromlogging.handlersimportMemoryHandler# Create logger and formatter for a structured log messagelogger=logging.getLogger("my_logger")formatter=logging.Formatter(fmt="%(levelname)-7s ⏱️%(asctime)s 📍 %(funcName)12s:%(lineno)-2s 💌 %(message)s",datefmt="%H:%M:%S")# Configure stream handlerstream_handler=logging.StreamHandler()stream_handler.setLevel(logging.INFO)# Only INFO and above will be displayedstream_handler.setFormatter(formatter)logger.addHandler(stream_handler)# Configure memory handlermemory_handler=MemoryHandler(capacity=100,target=stream_handler,flushLevel=logging.ERROR)memory_handler.setFormatter(formatter)logger.addHandler(memory_handler)

在上述设置中,MemoryHandler可以缓冲最多 100 条日志条目。如果发生错误,我们可以从MemoryHandler刷新日志到StreamHandler,从而得到完整的线索路径。

如何仅用 77MB 使用 Python Bloom 过滤器存储和查询 1 亿项数据


在代码中使用面包屑记录器

下面是配置好的新日志记录器的演示。注意finally块,我们在每次尝试后清除缓冲区,以保持针对每个操作的特定调试日志。

defdivide(a,b):logger.debug(f"Dividing [{a}] by [{b}]")returna/bforvaluein[1,2,3,4,5,6,7,8,9,'not a number',0]:try:logger.debug("Start dividing..")res=divide(a=10,b=value)exceptExceptionase:logger.error(f"❌ An exception occurred:{e}")finally:memory_handler.buffer.clear()# Clear memory after each pass

直到not a number,我们不会看到任何日志,因为所有前面的值执行时都没有错误。然而,当我们处理not a number时,divide函数会抛出异常,因为我们不能将整数除以字符串。

我们最终进入except块并记录一个ERROR。我们已将MemoryHandler配置为在遇到ERROR时将所有缓冲日志刷新到StreamHandler,这正是本例中将要发生的事情。

最后,我们在finally块中清除缓冲区,以便在开始处理not a number时删除9DEBUG日志。


样本输出

当我们运行最终代码时,只有错误情况的日志会显示调试信息作为线索。以下是完整输出的样子:

# Logs corresponding to 'not a number'ERROR ⏱️17:07:03📍 main:44💌 ❌ An exception occurred:unsupported operandtype(s)for/:'int'and'str'DEBUG ⏱️17:07:03📍 main:41💌 Start dividing..DEBUG ⏱️17:07:03📍 divide:32💌 Dividing[10]by[nota number]# Logs corresponding to 0ERROR ⏱️17:07:03📍 main:44💌 ❌ An exception occurred:division by zero DEBUG ⏱️17:07:03📍 main:41💌 Start dividing..DEBUG ⏱️17:07:03📍 divide:32💌 Dividing[10]by[0]

在这些示例中,MemoryHandler仅在遇到错误时捕获和刷新调试日志,提供了一个清晰的线索路径,提供了关于错误的有价值信息。

用两行代码应用 Python 多进程


结论

通过这种设置,我们通过缓冲调试日志并仅在遇到错误时显示它们,实现了更精简的日志记录过程。这种面包屑式的方法对于性能和日志量管理至关重要的应用程序来说非常理想。MemoryHandler为我们提供了两全其美的解决方案:当我们需要时提供详细的跟踪,当我们不需要时最小化日志量。

希望这篇文章和我希望的一样清晰,如果不是这样,请告诉我我可以做些什么来进一步澄清。同时,查看我关于各种编程相关主题的**其他文章**。

开心编码!

— Mike

P.s: 喜欢我在做的事情吗?关注我!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 16:05:27

Spring的反射与动态代理

1. Spring 反射与动态代理Spring 框架广泛使用反射和动态代理机制来增强灵活性与可扩展性,特别是在实现 AOP(面向切面编程)和动态 Bean 配置时。反射允许在运行时获取类的元数据并动态操作对象,而动态代理则允许在运行时创建代理对…

作者头像 李华
网站建设 2026/4/18 5:12:21

学霸同款9个AI论文平台,助你轻松搞定本科生毕业论文!

学霸同款9个AI论文平台,助你轻松搞定本科生毕业论文! AI 工具助力论文写作,告别熬夜苦战 对于本科生而言,撰写毕业论文是一项既重要又棘手的任务。从选题到成稿,每一个环节都充满了挑战。而随着 AI 技术的不断发展&…

作者头像 李华
网站建设 2026/4/17 17:03:21

基于单片机的彩灯控制系统

收藏和点赞,您的关注是我创作的动力 文章目录 概要 一、研究的主要内容二、彩灯的方案设计3.1彩灯常见的工作模式3.2彩灯的设计方案以及工作原理3.2.1彩灯的设计方案3.2.2彩灯的工作原理3.4彩灯效果图 三、设计3.1 plc机型的选择3.2 程序框图 概要 随着社会经济和科…

作者头像 李华
网站建设 2026/4/17 20:30:24

基于python的智能健康检测系统设计与实现2025_v5gemqq6

前言基于Python的智能健康检测系统是一个集数据采集、分析、预警和可视化于一体的综合性健康管理平台。该系统利用Python强大的数据处理能力和丰富的机器学习库,结合可穿戴设备或医疗传感器,实现对用户健康状况的实时监测和智能分析,为用户提…

作者头像 李华
网站建设 2026/4/16 10:00:41

高效便捷JAVA汽车保养同城服务新选择

JAVA汽车保养同城服务通过跨平台协同、智能调度、数据安全保障及创新功能,为用户提供高效便捷的一键触达体验,成为同城汽车养护的新选择。 以下是具体分析: 一、技术架构:跨平台无缝衔接,支撑高并发场景 多端协同 Jav…

作者头像 李华