日志基础与规范:日志级别、格式标准化与轮转策略

日志这东西,说白了就是系统的黑匣子。你想想看,线上出了故障,第一反应是什么?肯定是翻日志。但如果日志乱七八糟,级别乱用、格式不统一、文件撑爆磁盘……那这黑匣子还不如没有。今天我就把日志基础这块掰开揉碎了讲清楚。

2.1 日志级别:DEBUG / INFO / WARN / ERROR

日志级别不是拍脑袋定的,它有一套通用的语义。我个人习惯把这四个级别当成「信号灯」来看:

级别 含义 典型场景 生产环境是否开启
DEBUG 调试信息,开发阶段用 变量值、函数入口/出口、SQL 参数 ❌ 关闭
INFO 正常业务流程记录 服务启动、请求到达、任务完成 ✅ 开启
WARN 潜在问题,不影响当前运行 配置降级、重试、超时阈值接近 ✅ 开启
ERROR 明确错误,需要人工介入 数据库连接失败、空指针、业务异常 ✅ 开启
我曾经踩过一个坑: 有同事把所有的异常都打成了 ERROR,包括一些业务上预期的「用户输入不合法」。结果告警平台天天炸,真正的 ERROR 反而被淹没了。记住,ERROR 只留给「系统无法自动恢复」的情况。

级别之间还有一条潜规则:向上兼容。你设置了日志级别为 WARN,那么 DEBUG 和 INFO 就不会输出。这能帮你控制日志量,避免磁盘被刷爆。

2.2 日志格式标准化

日志格式不统一,解析工具根本没法用。我见过最离谱的日志,时间戳格式一天一变,有的用 ISO 8601,有的用 Unix 时间戳,还有的干脆写「昨天下午三点」。嗯,这种日志基本等于废纸。

标准化格式长什么样?我推荐一个通用模板:

[时间戳] [日志级别] [线程名] [类名:行号] - 消息内容

举个例子:

[2025-03-21 14:32:18.123] [INFO] [http-nio-8080-exec-3] [com.example.OrderService:56] - 订单 20250321143218001 创建成功,金额 299.00 元

这里面每个字段都有用:

  • 时间戳:精确到毫秒,格式统一用 yyyy-MM-dd HH:mm:ss.SSS
  • 日志级别:固定宽度,方便 grep 过滤
  • 线程名:排查并发问题必备
  • 类名:行号:定位代码位置
  • 消息内容:包含关键业务标识(订单号、用户 ID)
我建议: 在消息内容里加上 traceId 或 requestId。这样一次请求的所有日志都能串起来,排查链路问题会轻松很多。

2.3 日志切分与轮转策略

日志文件如果不切分,一个月下来能撑到几十 GB。到时候别说分析,连打开都费劲。切分和轮转就是为了解决这个问题。

常见的切分方式有两种:

  • 按时间切分:每天一个文件,比如 app-2025-03-21.log
  • 按大小切分:每个文件 100MB,满了就切下一个

轮转策略就是「切分之后怎么处理旧文件」。我一般用 保留最近 N 个文件 的策略:

策略 说明 适用场景
保留数量 只保留最近 7 个文件,旧的自动删除 磁盘空间紧张
保留天数 保留最近 30 天的日志 合规审计要求
压缩归档 切分后 gzip 压缩,保留更久 历史追溯需求

以 Logback 为例,配置一个按天切分、保留 30 天的策略:

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <file>/var/log/app/app.log</file>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>/var/log/app/app-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
    <maxHistory>30</maxHistory>
  </rollingPolicy>
  <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger{36}:%line] - %msg%n</pattern>
  </encoder>
</appender>
注意: 切分时机要避开业务高峰期。我曾经在双十一凌晨 0 点切分日志,结果切分时文件锁导致业务线程阻塞了 3 秒。后来我把切分时间改到了凌晨 4 点,再也没出过问题。

2.4 知识体系总览

下面这张图把日志基础的核心逻辑串起来了。你可以把它当成一个检查清单:

日志基础与规范知识体系 日志基础与规范知识体系 日志级别 日志格式标准化 切分与轮转策略 DEBUG INFO WARN ERROR 时间戳 + 级别 + 线程 + 类名 消息内容含 traceId / 业务 ID 按时间切分 按大小切分 保留 N 个 压缩归档 核心原则:级别准确 + 格式统一 + 轮转合理 = 可用的日志系统 缺少任何一环,日志都会变成「数据垃圾」 💡 实践建议:从今天起统一日志格式,设置合理的轮转策略

总结一下:

  • 日志级别要严格区分,ERROR 只留给真正的错误
  • 格式标准化是日志分析的基础,时间戳、级别、线程、类名缺一不可
  • 切分和轮转能避免磁盘爆满,同时保留足够的历史数据

这些规范看起来简单,但真正落地需要团队共识和工具配合。我见过太多项目因为日志不规范,排查问题时两眼一抹黑。别让你的系统也变成那样。