Python项目日志需结构化、可过滤、带上下文、不冗余,严格按DEBUG/INFO/WARNING/ERROR四级规范记录,注入request_id等标识实现链路追踪,杜绝敏感信息与性能污染,结合grep或ELK高效排查。

Python项目日志不是“能打出来就行”,而是要让问题在5分钟内定位到代码行、上下文和关键变量值。核心是:结构化、可过滤、带上下文、不冗余。
日志级别要真实反映问题严重性
DEBUG不是“随便打”,ERROR不是“只要报错就写”。误用会导致告警疲劳或关键信息被淹没:
- DEBUG:仅用于开发期追踪变量流转,如
logger.debug("user_id=%s, order_items=%r", user_id, items);上线后建议关闭或按模块动态开启 - INFO:记录明确的业务动作完成,如
"order_created: id=%s, amount=%.2f",不含敏感字段 - WARNING:出现异常但流程仍继续,如第三方API返回非200但有降级逻辑
- ERROR:代码抛出未捕获异常前,必须记录完整堆栈+关键参数,用
logger.exception("Failed to process payment")
每条日志必须包含可追溯的上下文标识
单靠时间戳和行号无法快速关联一次请求的全链路。推荐在日志中注入轻量上下文:
- Web服务:用
request_id(如Flask的g.request_id或Django中间件注入)贯穿整个请求生命周期 -
异步任务(Celery):使用
task_id或自定义correlation_id - 数据库操作:记录
db_conn_id或shard_key,便于区分分库分表实例 - 格式统一示例:
[req=abc123][task=pay_456][shard=u_7] INFO: charge processed for user=U999
避免日志污染与安全风险
日志是生产环境的“公开日记”,不能成为漏洞入口或性能瓶颈:
立即学习“Python免费学习笔记(深入)”;
- 禁止打印原始请求体、响应体、密码、token、密钥、身份证号等敏感信息;脱敏后再记录,如
phone="138****1234" - 避免在循环中打日志(尤其DEBUG),可用计数器控制频率,如
if i % 100 == 0: logger.debug("processed %d items", i) - 不用
str(obj)或repr(obj)直接输出复杂对象,易触发无限递归或超长日志;改用vars(obj)或定制__log__()方法 - JSON日志建议用
structlog或python-json-logger,避免手工拼接字符串
排查时优先看什么?——建立日志阅读习惯
高效排查不靠“全文搜索”,而靠结构化筛选:
- 先锁定时间范围 + request_id/task_id,用
grep -A5 -B2 "req=xyz789"快速提取上下文片段 - 查失败:用
grep "ERROR\|CRITICAL" | grep -v "ConnectionRefused"过滤真实业务错误 - 查慢操作:匹配
"took.*ms"或"duration.*s"字段,结合INFO/DEBUG中的耗时埋点 - 日志集中平台(如ELK、Loki)中,用
level=ERROR | json | duration > 2000直接下钻分析
规范不是增加负担,是把“猜”变成“查”,把“重启试试”变成“看三行日志就懂”。坚持两周,你会明显感觉联调时间缩短一半。










