Structlog 实战指南:Python 结构化日志的终极形态
Structlog 是专为结构化日志而生的 Python 库。本文讲解 Structlog 的 processor 处理链、JSON 渲染、bind 上下文绑定、级别过滤、结构化堆栈(dict_tracebacks)、与标准库 logging 的集成,以及接入观测云的最佳路径。
Structlog 是专注于结构化日志的 Python 库,核心思想是把每条日志当作一个"事件字典",经过一串可插拔的 processor(处理器)管道逐步加工,最终渲染为 JSON 或人类可读文本。 它不替代标准库 logging,而是站在它之上,把"结构化"做到极致。
核心要点速览
- 核心模型:事件字典 + processor 链,最后一步由 Renderer(ConsoleRenderer/JSONRenderer)决定输出形态;
bind()绑定的上下文字段会出现在该 logger 后续的每一条日志中——请求级追踪的正确姿势;- 开发用彩色 ConsoleRenderer,生产切 JSONRenderer,同一份代码只改配置;
dict_tracebacks能把异常堆栈也序列化为 JSON,平台侧可直接解析;- 与标准库 logging 完全兼容,可逐步迁移;Django 项目可直接用 django-structlog。
快速上手
pip install structlog
import structlog
logger = structlog.get_logger()
logger.info("订单创建成功", order_id="ORD-123", amount=99.5)
默认输出是开发友好的彩色文本,关键在参数即字段——order_id 等关键字参数会成为结构化字段,而不是拼进消息字符串。
processor 链:日志的流水线
structlog.configure(
processors=[
structlog.processors.TimeStamper(fmt="iso"), # 加 ISO-8601 时间戳
structlog.processors.add_log_level, # 加级别字段
structlog.processors.EventRenamer("msg"), # 把 event 改名为 msg
structlog.processors.JSONRenderer(), # 最终渲染为 JSON
]
)
每个 processor 按声明顺序加工事件字典,输出:
{"order_id": "ORD-123", "amount": 99.5, "msg": "订单创建成功", "timestamp": "2026-08-25T13:57:41.468587Z", "level": "info"}
常用 processor:TimeStamper(时间戳)、add_log_level(级别)、StackInfoRenderer(调用栈)、dict_tracebacks(JSON 化堆栈)、format_exc_info(异常信息)。
上下文绑定:bind
logger = structlog.get_logger().bind(request_id="req-abc-123", service="order")
logger.info("开始处理订单")
logger.info("订单处理完成", elapsed_ms=120)
两条日志都自动携带 request_id 与 service——把"贯穿一次请求的字段"绑定一次,而不是每条日志重复传。Web 框架中配合中间件在请求入口绑定,效果最佳。
级别过滤
Structlog 默认不按级别过滤(全部输出),需要显式配置:
import logging
structlog.configure(wrapper_class=structlog.make_filtering_bound_logger(logging.INFO))
结构化堆栈
dict_tracebacks 让异常堆栈变成 JSON 数组而不是一坨文本——平台侧可按帧检索:
structlog.configure(
processors=[
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.add_log_level,
structlog.processors.dict_tracebacks,
structlog.processors.JSONRenderer(),
]
)
与标准库 logging 协作
Structlog 可以把渲染后的结果交给标准库 logging 输出(复用其 Handler 生态),也可反向拦截标准库日志进 Structlog 管道。这意味着迁移不必一步到位:新代码用 Structlog,老代码与第三方库继续走标准库,最终汇到同一出口。Django 项目可直接采用 django-structlog 包,中间件自动为每个请求绑定 request_id、IP、UA 等字段。
接入观测云
观测云落地:Structlog 的 JSONRenderer 输出与观测云是天作之合——应用写 stdout(容器)或文件(虚拟机),DataKit 采集上报 ;JSON 自动解析为字段,Pipeline 做两件标准化:确认 timestamp 映射为 time、level 映射为标准 status 。结构化的红利在平台侧全部兑现:查看器按任意字段精确过滤与聚合 ,聚类分析归并异常事件,监控器(日志检测)按 level: error 或特定 event 名配置告警,推送钉钉/企业微信/飞书 。
总结
Structlog 的一句话心法:日志即数据。processor 链负责加工数据,bind 负责沉淀上下文,JSONRenderer 负责机器可读——剩下的检索、告警、看板,交给观测云。
常见问题(FAQ)
Q:Structlog 和 Loguru 怎么选?
要"绝对结构化、processor 可编程、与标准库深度集成"选 Structlog;要"零配置上手、内置轮转、开发体验顺滑"选 Loguru。大型团队、强规范场景 Structlog 上限更高。
Q:Structlog 能完全替代标准库 logging 吗?
不建议完全替代。第三方库都在用标准库,最佳组合是 Structlog 负责你的代码 + 标准库集成负责外部日志,最终统一渲染输出。
Q:开发时不想看 JSON 怎么办?
把最后一个 processor 从 JSONRenderer() 换成 ConsoleRenderer()(可加 colors=True)即可,同一份代码按环境变量切换。
Q:Django 项目怎么用 Structlog?
使用 django-structlog 包:安装后在 settings 注册中间件与配置,它会自动为每个请求生成 request_id 并绑定 IP、UA 等上下文,业务代码里直接 structlog.get_logger() 使用。
系列阅读:Python 日志模块详解 | JSON 日志入门