跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

Python 3.12 Logging 核心:LogRecord 机制解析与定制实战

LogRecord 是 Python logging 模块中承载日志事件的核心数据容器,封装了消息内容、级别、时间戳及源码位置等信息。解析了 LogRecord 的动态属性管理与工厂模式机制,重点演示了如何通过继承 LogRecord 类、自定义工厂函数及过滤器来实现日志字段的深度定制。示例代码展示了如何在运行时注入业务追踪 ID 并统一格式化输出,同时提供了关于 Filter 中尽早过滤低级别日志的性能优化建议,帮助开发者构建灵活且高效的日志架构。

HadoopMan发布于 2026/3/21更新于 2026/8/2242 浏览
Python 3.12 Logging 核心:LogRecord 机制解析与定制实战

Python 3.12 Logging 核心:LogRecord 机制解析与定制实战

LogRecord 是 Python logging 模块中代表一条日志事件的数据容器。简单来说,它就像一张'记录单',每当程序调用日志方法(如 logger.info())时,logging 会自动创建一个 LogRecord 对象,并把所有相关信息都装进去,包括日志消息内容、级别、时间戳、源代码位置、线程信息以及异常详情等。这个对象随后会被传递给处理器(Handler)和格式化器(Formatter),最终转换成我们看到的文本。

LogRecord 的核心机制

LogRecord 封装了日志事件的所有细节。每次记录事件时,系统都会生成一个实例。主要信息位于 msg 和 args 中,通过 % 运算符组合形成最终的消息字段,实际格式化在 getMessage() 方法中完成。

动态属性管理

LogRecord 通过 __init__ 动态存储字段,例如 msg、levelname 等。值得注意的是,像 message 这样的属性支持延迟格式化——只有在访问时才会调用 getMessage() 解析 msg 与 args。默认情况下,它包含了一系列标准字段,如 name、pathname、lineno、exc_info 等。

工厂模式创建

除了常规流程,我们还可以利用 logging.makeLogRecord(dict) 工厂方法手动创建实例,这在测试或特殊场景下很有用:

record_dict = {
    "name": "demo",
    "level": 20,
    "pathname": "/app/main.py",
    "msg": "User %s logged in",
    "args": ("Alice",)
}
record = logging.makeLogRecord(record_dict)

关键方法解析

getMessage() 负责合并 msg 与 args 生成最终日志消息。如果存在 args,则使用 % 运算符进行格式化;当 args 为空元组、空字典或 None 时,直接返回消息字符串。该方法通常在 Formatter 中被调用。

def getMessage(self):
    """Return the message for this LogRecord."""
    msg = str(self.msg)
    if self.args:
        msg = msg % self.args
    return msg

生命周期与实战定制

LogRecord 的生命周期通常分为三步:由 Logger.log() 调用 Logger.makeRecord() 生成,经过 Filter 和 Formatter 处理,最后通过 Handler 写入目标(文件、网络等)。

在实际开发中,我们经常需要扩展 LogRecord 来添加业务字段。下面是一个完整的示例,演示如何自定义 LogRecord 类并注入工厂函数。

完整代码示例

这段代码展示了如何继承 LogRecord 添加自定义字段(如唯一 ID),并通过过滤器为未指定字段的记录补全默认值。

import logging
import logging.config
import time

class CustomLogRecord(logging.LogRecord):
    """扩展 LogRecord 以添加自定义字段"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 添加唯一 ID,模拟业务追踪
        self.custom_id = hash(time.time())

def custom_record_factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs):
    """自定义 LogRecord 工厂函数"""
    record = CustomLogRecord(name, level, fn, lno, msg, args, exc_info, func, sinfo)
    return record

# 定义一个过滤器,为记录添加默认的 custom_field
class DefaultCustomFieldFilter(logging.Filter):
    def __init__(self, default_value="d"):
        super().__init__()
        self.default_value = default_value

    def filter(self, record):
        if not hasattr(record, 'custom_field'):
            record.custom_field = self.default_value
        return True

# 配置日志系统
logging_config = {
    "version": 1,
    "formatters": {
        "detailed": {
            "format": "[%(asctime)s][%(levelname)s][%(name)s]-[ID=%(custom_id)s]-%(message)s # custom:%(custom_field)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "detailed",
            "level": "DEBUG",
            "filters": ["default_custom_field"]
        }
    },
    "loggers": {
        "demo": {
            "handlers": ["console"],
            "level": "DEBUG"
        }
    },
    "filters": {
        "default_custom_field": {
            "()": DefaultCustomFieldFilter,
            "default_value": ""
        }
    }
}

def main():
    # 应用配置并设置自定义工厂
    logging.config.dictConfig(logging_config)
    logging.setLogRecordFactory(custom_record_factory)
    
    logger = logging.getLogger("demo")
    
    # 标准日志记录
    logger.info("Service started")
    
    # 添加自定义字段
    logger.debug("Debug with extra", extra={"custom_field": "debug_value"})
    
    # 异常处理示例
    try:
        1 / 0
    except Exception as e:
        logger.error("Math error occurred", exc_info=True)

if __name__ == "__main__":
    main()

运行上述代码后,控制台会输出带有自定义 ID 和字段的日志格式。你可以看到 ID 字段来自 CustomLogRecord 的初始化逻辑,而 custom_field 则由过滤器补充。

性能优化建议

在编写日志逻辑时,注意避免冗余计算。特别是在 Filter 中,应尽早过滤掉低级别的日志请求,减少后续处理器的开销。

总结

LogRecord 作为日志系统的核心载体,通过灵活的属性和工厂机制支持深度定制。结合 Python 3.12 的优化特性,可以构建高性能、可扩展的日志架构。实际开发中,善用 extra 参数和自定义工厂是实现业务级日志增强的关键。

目录

  1. Python 3.12 Logging 核心:LogRecord 机制解析与定制实战
  2. LogRecord 的核心机制
  3. 动态属性管理
  4. 工厂模式创建
  5. 关键方法解析
  6. 生命周期与实战定制
  7. 完整代码示例
  8. 定义一个过滤器,为记录添加默认的 custom_field
  9. 配置日志系统
  10. 性能优化建议
  11. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 为何成为 AI 开发的首选语言?
  • 构建 Vue 全局错误处理体系,实现业务与错误解耦
  • 前端状态管理:Recoil 的原子化方案
  • Windows 下使用 VSCode 结合 WSL 进行远程开发配置
  • Python 面试高频考点:模块、装饰器与异步编程详解
  • 数据结构栈与队列基础及竞赛高频算法实操
  • Llama-2-7B 昇腾 NPU 性能测评与部署优化指南
  • Stable Diffusion v1.5 Archive 与 SDXL-Lightning 生成速度与质量对比
  • 初识Java:语言特性与基础语法入门
  • Wi-Fi 7 轻量化应用:智能家居与物联网的落地时代
  • GitHub 第 10 亿个仓库名为 shit,官方祝贺创造伟大屎
  • 归并排序的核心思想与进阶应用
  • 无人机 RGB+ 红外双模态小目标行人检测系统构建与数据集详解
  • DeepSeek-R1-Distill-Llama-70B:开源推理效率分析
  • HarmonyOS RcList 组件综合示例与尺寸计算
  • Android Handler 与 Binder 底层原理深度解析
  • 基于 uni-app 与 DeepSeek 的跨端 AI 流式对话系统实战
  • 开源 AI 编程工具 OpenCode 全面解析
  • Spring AI 实战:基于 Ollama 构建离线私有化 AI 服务
  • 模拟算法专题:替换问号、提莫攻击等 5 题详解

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online