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

Python 3.12 日志核心:深入理解 LogRecord 机制

LogRecord 是 Python logging 模块中代表一条日志事件的数据容器,封装了消息内容、级别、时间戳、源码位置及异常信息等。解析了 LogRecord 的动态属性管理、工厂模式及关键方法,展示了如何通过自定义工厂函数和过滤器扩展日志功能,例如添加唯一 ID 和业务字段。同时梳理了从创建到输出的生命周期,并提供了完整的代码示例与性能优化建议,帮助开发者构建更灵活高效的日志系统。

zhang发布于 2026/3/23更新于 2026/9/1049 浏览
Python 3.12 日志核心:深入理解 LogRecord 机制

LogRecord 基本概念

LogRecord 是 Python logging 模块中代表一条日志事件的数据容器。简单来说,它就像一张'记录单',每当程序调用日志方法(如 logger.info())时,logging 会自动创建一个 LogRecord 对象,并把所有相关信息都装进去。

这些信息包括:日志消息内容、日志级别(DEBUG/INFO 等)、产生日志的时间戳、源代码位置(文件名、行号、函数名)、当前线程/进程 ID、异常信息(如果有),以及通过 extra 添加的自定义属性。这个'记录单'随后会被传递给日志处理器(Handler)和格式化器(Formatter),最终被转换成我们看到的输出文本。

LogRecord 的核心机制

LogRecord 是 logging 模块的核心类,用于封装日志事件的所有信息。每次记录事件时,系统都会生成 LogRecord 实例。传递的主要信息位于 msg 和 args 中,通过 str(msg) % args 组合形成记录的消息字段,实际的消息格式化在 getMessage() 中完成。

动态属性管理

  • 属性存储:通过 __init__ 动态存储字段(如 msg, levelname 等)
  • 延迟格式化:如 message 属性在访问时通过 getMessage(),解析 msg 与 args
  • 默认属性集:包含多个字段信息(如 name, pathname, lineno, exc_info, sinfo 等)

工厂模式

我们可以通过 logging.makeLogRecord(dict) 工厂方法创建实例,这在调试或模拟日志场景下很有用:

import logging

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.
    Return the message for this LogRecord after merging any user-supplied arguments with the message.
    """
    msg = str(self.msg)
    if self.args:
        msg = msg % self.args
    return msg

LogRecord 生命周期

  1. 创建:由 Logger.log() 调用 Logger.makeRecord() 生成
  2. 处理:经由 Filter、Formatter 等组件
  3. 输出:通过 Handler 写入目标(文件/网络等)

完整 Demo 实现

下面是一个扩展 LogRecord 以添加自定义字段的完整示例。我们通过自定义工厂函数和过滤器来实现业务级日志增强。

import logging
import logging.config
import time

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

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  # 返回 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 和字段的日志信息(此处应显示包含自定义字段的日志输出)。

性能优化建议

在实际开发中,为了保持高性能,建议在 Filter 中尽早过滤低级别日志,避免不必要的计算和对象创建。

总结

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

目录

  1. LogRecord 基本概念
  2. LogRecord 的核心机制
  3. 动态属性管理
  4. 工厂模式
  5. 关键方法
  6. LogRecord 生命周期
  7. 完整 Demo 实现
  8. 定义一个过滤器,为记录添加默认的 custom_field
  9. 配置日志系统
  10. 性能优化建议
  11. 总结

更多推荐文章

查看全部
  • OpenClaw 结合 Kimi K2.5 本地部署与办公自动化实战
  • 使用 OpenClaw 与 cpolar 实现本地 AI 远程访问及内网穿透
  • Manba 与微服务架构:构建企业级 API 管理平台
  • Mac 开启 Apple Intelligence 配置指南
  • GBDT 算法原理详解:梯度提升决策树从数学推导到代码实现
  • Linux 入门指南:从零开始掌握命令行基础
  • AI 生成图片提示词:新手入门指南与最佳实践
  • Rust 异步并发安全与内存管理实战指南
  • Windows 下使用 Docker Desktop 和 Ubuntu 部署 Qwen 大模型
  • AI 大模型:从零搭建 Agent 框架
  • 基于 Java+Vue+SpringBoot 的学生网上选课系统设计
  • C++ 继承:语法、访问权限与虚继承详解
  • 2024 年 5 款主流 AI 编码工具对比与选型指南
  • AI 辅助前端设计:掌握三大技能独立完成产品全流程
  • GitHub 7 大 Claude Skills 开源项目:Skill Creator、Superpowers 与 Code Review 实战指南
  • 扩散模型技术演进:从DDPM到Stable Diffusion再到DiT
  • Plottable 高级图表制作:从散点图到堆叠面积图的 10 种实现方法
  • VSCode 中关闭 GitHub Copilot 功能的两种方法
  • 基于 STM32 的智能家居环境监测系统设计
  • PaperRed:AI 论文写作与查重降重工具功能介绍

相关免费在线工具

  • 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