← [ BACK_TO_NOTES ]

Python 日志

logging 模块分层:logger/handler/formatter;用级别与上下文支撑运维,而不是 print。

#concept #growing #dev #python #python

[!info] related notes

Python 日志

这个概念为什么出现

print 无法分级、无法统一格式、难以在库中关闭。logging 提供可配置的诊断通道。

[!abstract] 一句话理解 业务代码拿 logger 打点;handler 决定输出到哪,formatter 决定长什么样,级别控制噪声。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:下单路径记录 info 与错误

# order_logging_demo.py
# 业务意图:用标准 logging 记录下单成功/失败。
# 教学点:
# - getLogger;
# - basicConfig;
# - 异常日志。

import logging

logger = logging.getLogger("billing.order")


def place_order(user_id: str, ok: bool) -> None:
    logger.info("placing order user=%s", user_id)
    if not ok:
        try:
            raise RuntimeError("payment declined")
        except RuntimeError:
            logger.exception("order failed user=%s", user_id)
            raise
    logger.info("order ok user=%s", user_id)


def main() -> None:
    logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
    place_order("u1", True)
    try:
        place_order("u2", False)
    except RuntimeError:
        pass


if __name__ == "__main__":
    main()

建议运行:

python order_logging_demo.py

直接运行此独立脚本时,默认写到 stderr(含 traceback 片段):

INFO billing.order: placing order user=u1
INFO billing.order: order ok user=u1
INFO billing.order: placing order user=u2
ERROR billing.order: order failed user=u2
Traceback (most recent call last):
...
RuntimeError: payment declined

结合场景再看三个关注点

  1. 库用 getLogger(name),应用配置 handler。
  2. logger.exception 在 except 中记录当前异常信息;本例记录后重新抛出,日志本身不等于处理了错误。
  3. 结构化字段(JSON logs)在生产更易检索。

核心概念与准确模型

  • Logger → Handler → Formatter
  • 级别:DEBUG/INFO/WARNING/ERROR/CRITICAL
  • propagate 将记录交给祖先 logger 的 handler;祖先 logger 本身的级别/过滤器不会重新检查,但 handler 的级别/过滤器仍生效。
  • 过滤器 Filter

边界情况与反直觉行为

  1. basicConfig 在根 logger 已有 handler 时默认不生效;应用需要重置时可显式 force=True。logger 及实际传播链上完全没有 handler 时,默认 lastResort 会将 WARNING 及以上记录写到 stderr。
  2. 子 logger 和祖先都配置 handler 且继续传播时可能重复输出;多进程也不能靠普通 FileHandler 自动协调同一文件。
  3. 敏感数据 脱敏。

常见误区

[!warning] 常见误区:库里 basicConfig 错误理解:方便。
正确模型:库只打点,应用配置。

工程实践

  • 请求 ID 写入上下文
  • 级别可动态调
  • 与指标/追踪关联

本节总结

日志是运行时叙事。设计字段与级别,比堆 print 重要。

自测题

  1. 为何用 %s 惰性格式化?
  2. 库为何不 basicConfig?
参考答案
  1. logger.debug(“x=%s”, value) 可推迟字符串格式化,但参数表达式仍先求值;昂贵计算要用 isEnabledFor 等显式判断。
  2. 避免抢占应用的全局日志策略。

延伸阅读与资料来源

资料类型支撑内容
logging文档标准库
Logging HOWTOHOWTO实践
创建于 2026/7/15 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本