Python接口日志必须标准化:统一打什么、怎么打、打到哪;用logging替代print;所有入口、分支、异常路径强制记录;每条日志含trace_id/request_id;结构化JSON格式,精简必留字段;分级采样落盘,避免全量DEBUG或ERROR。
Python接口日志不标准化,会导致问题定位慢、上下游排查扯皮、线上故障复盘无从下手。核心不是“要不要打日志”,而是“打什么、怎么打、打到哪”必须统一。
logging 替代 print 是底线直接写 print 无法控制输出级别、格式、目标(文件/网络/标准输出),也进不了日志采集系统(如 ELK、Sentry)。所有接口入口、关键分支、异常路径都必须走 logging。
logging.basicConfig() 或用 dictConfig,避免每个模块重复初始化logging.getLogger(__name__) 获取 logger,保证层级可追溯logging.debug(),但开发阶段建议在请求头带 X-Debug: true 时动态开启 DEBUG 级别日志没有唯一请求标识的日志等于没日志。HTTP 接口需从请求中提取或生成 trace_id(如来自 X-Trace-ID 头),并透传至下游;内部调用则用 uuid.uuid4().hex 生成 request_id。
import logging import uuid from flask import requestlogger = logging.getLogger(name)
@app.before_request def set_request_id(): trace_id = request.headers.get('X-Trace-ID', uuid.uuid4().hex) request.request_id = trace_id # 挂载到 request 对象
%(request_id)s 字段,通过自定义 Formatter 注入JSON 格式日志是标配,但字段不是越多越好。Elasticsearch 等后端对嵌套过深、字段数超限、值过长的文档会丢弃或截断。
level、timestamp、request_id、endpoint(如 POST /api/v1/user)、status_code、duration_ms、error_type(仅异常时)、error_msg(仅异常时)__dict__ 全量 dump、原始 request body(敏感且膨胀)、堆栈全路径(用 exc_info=True 让 logging 自动处理即可)extra 参数注入业务字段,例如:logger.info("user created", extra={"user_id": 123, "plan": "pro"})
全量 DEBUG 日志写磁盘,不出三天磁盘告警;全量 ERROR 不采样,Sentry 被打爆。得按场景分流:
RotatingFileHandler),保留 7 天queue 缓冲防阻塞
整堆栈,其余只记摘要)最常被忽略的是:日志 handler 的 level 和 logger 的 level 是两层过滤,漏配一层就导致该写的没写、不该写的刷屏。