跳转到内容

日志规范

日志级别、结构化字段、敏感信息屏蔽


[Requirement] 必须按以下级别使用日志,不得滥用。

级别使用场景示例
DEBUG开发调试细节,生产环境默认关闭入参出参、循环内部变量
INFO关键业务流程节点“用户登录成功”、“订单创建”
WARN可恢复的异常或非预期但不影响主流程“重试第 2 次”、“缓存未命中”
ERROR影响功能的错误,需要关注“调用支付接口失败”、“数据库写入异常”
CRITICAL/FATAL系统级故障,需要立即响应“服务不可用”、“数据损坏”

[Standard] 生产环境默认日志级别为 INFO;DEBUG 级日志必须可通过配置动态开启,无需重启。

[Caution] 不要在循环中使用 INFO 级别记录每条数据,大量高频日志应降为 DEBUG 或使用采样。

示例:

logger.debug("开始处理请求: request_id=%s, params=%s", request_id, params)
 
logger.info("用户登录成功: user_id=%s, ip=%s", user_id, ip)
 
logger.warning("缓存未命中,回源数据库: key=%s", cache_key)
 
logger.error("支付失败: order_id=%s, error=%s", order_id, error, exc_info=True)
 
logger.critical("数据库连接池耗尽,服务不可用")

[Requirement] 必须输出结构化日志(JSON 格式),便于采集、检索和分析。禁止使用字符串拼接的非结构化日志。

[Standard] 每条日志包含固定字段:timestamp、level、logger、message、trace_id、span_id。

日志格式示例:

{
  "timestamp": "2024-01-01T12:00:00.123Z",
  "level": "INFO",
  "logger": "user.service",
  "message": "用户登录成功",
  "trace_id": "abc123",
  "span_id": "def456",
  "user_id": 1001,
  "ip": "192.168.1.1"
}

[Suggestion] 使用结构化日志库:Python 用 structlog 或 python-json-logger,Java 用 Logback + logstash-logback-encoder,Node.js 用 pino。


[Requirement] 所有日志必须包含以下字段,由日志框架统一注入,业务代码无需手动添加。

字段说明示例
timestampISO 8601 格式,带毫秒2024-01-01T12:00:00.123Z
level日志级别INFO
loggerLogger 名称order.service
message日志消息(人类可读)订单创建成功
trace_id全链路追踪 IDabc123def456

[Standard] 业务字段使用 snake_case,保持全项目一致。

[Caution] 业务字段值必须是基本类型(字符串、数字、布尔),禁止传入复杂对象(需序列化为字符串)。

推荐字段:

字段说明
user_id用户 ID
order_id订单 ID
request_id请求 ID
cost_ms耗时(毫秒)
status_codeHTTP 状态码
error_code业务错误码

示例:

# 正确:结构化字段
logger.info(
    "订单创建成功",
    order_id=order.id,
    user_id=order.user_id,
    amount=order.amount,
    cost_ms=cost_ms,
)

[Requirement] 日志中禁止输出以下敏感信息,必须脱敏后才能记录。

敏感类型示例脱敏方式
密码password、secret完全屏蔽,输出 ***
身份证号18 位身份证保留前 4 后 2:1101***********12
手机号11 位手机号保留前 3 后 4:138****5678
银行卡号16-19 位卡号保留后 4 位:************1234
Token/Keytoken、api_key完全屏蔽
邮箱邮箱地址保留首字符和域名:z***@example.com
完整地址收货地址保留省市区,屏蔽详细门牌号

[Standard] 提供统一的脱敏工具函数,在日志输出前调用。

示例:

from mask import mask_phone, mask_id_card, mask_password
 
logger.info(
    "用户信息更新",
    user_id=user.id,
    phone=mask_phone(user.phone),
    id_card=mask_id_card(user.id_card),
)

[Caution] 打印异常堆栈时,异常消息中可能包含敏感信息(如 SQL 语句中的参数),需评估是否需要过滤。


[Standard] 高频路径(如循环内、热路径)上的 DEBUG 日志,必须使用惰性求值或级别判断,避免不必要的字符串拼接。

# 正确:使用 %s 占位符,日志库内部判断级别后才格式化
logger.debug("处理数据: item=%s", item)
 
# 错误:f-string 会在日志调用前就求值
logger.debug(f"处理数据: item={item}")

[Caution] 不要在日志参数中执行昂贵的计算(如序列化大对象),会拖慢主流程。

[Default] 单条日志不超过 4KB;大对象日志需截断。

[Suggestion] 对批量数据处理,使用聚合日志而非逐条日志:

# 正确:聚合统计
processed, failed = 0, 0
for item in items:
    try:
        process(item)
        processed += 1
    except Exception:
        failed += 1
logger.info("批量处理完成: total=%d, processed=%d, failed=%d",
            len(items), processed, failed)

[Suggestion] 高并发服务使用异步日志(AsyncAppender / QueueHandler),避免日志 I/O 阻塞业务线程。

[Caution] 异步日志可能丢失缓冲区中未落盘的日志,需在服务关闭时正确 flush。