日志级别:DEBUG、INFO、WARN、ERROR、FATAL

日志级别这东西,说白了就是给每条日志贴个标签——告诉你这条消息有多严重。我刚入行那会,总觉得日志随便打打就行了,结果线上出问题时翻了几万行INFO,愣是找不到关键线索。嗯,从那以后我才明白,级别不分清楚,日志就等于噪音。

我习惯把日志级别看作一个漏斗:越往上越紧急,数量越少。你想想看,开发环境里DEBUG满天飞,没人会觉得烦;但到了生产环境,你需要的往往是WARN以上的信号。

小提示:多数日志框架允许运行时动态调整级别。生产环境默认设成WARN或ERROR,排查问题时临时降到DEBUG——用完记得改回去。我有一次忘了切回去,结果磁盘三天就满了……那种尴尬,不想再经历。

五大级别详解

标准日志体系一般分成五档:DEBUG、INFO、WARN、ERROR、FATAL。它们之间没有值,但基本共识是:每一级代表一个“严重程度阶梯”。

级别含义典型场景我建议的用法
DEBUG细粒度调试信息进入函数、变量值、循环次数只在开发或临时调试时开启
INFO常规运行信息服务启动、配置加载、任务完成生产环境默认保留,数量可控
WARN潜在问题,不影响运行磁盘使用率超阈值、重试、降级必须重视,往往是隐患预兆
ERROR错误,但系统能继续外部接口失败、数据校验不通过立刻处理,至少要有告警
FATAL致命故障,系统不可用OOM、数据库断连无法恢复触发紧急告警 + 自动恢复流程

我个人习惯把FATAL当作ERROR的“加强版”——一旦出现,意味着服务无法继续有任何有效输出。你在项目中可能会遇到把所有严重问题都打成ERROR的情况,但这样会稀释FATAL的紧急度。我建议:只有“必死”的异常才用FATAL。

选择日志级别的黄金法则

很多人问我:“这个异常到底该打INFO还是WARN?”我的答案很简单:看它会不会让你半夜起来查。不会?INFO。可能?WARN。一定会?ERROR。

  1. DEBUG:不要在生产环境默认开启。它太啰嗦,但不可或缺——有一次我排查一个诡异的线程安全问题,全靠DEBUG日志里的锁获取顺序才定位到。
  2. INFO:记录“业务节点”。比如“订单创建成功”、“支付回调收到”。我反对用它记录循环内的每一步,否则日志量能把你吓哭。
  3. WARN:记录“异常但不影响当前请求”。比如重试策略触发、缓存穿透。我曾经忽略一个WARN,结果两周后磁盘满了——其实WARN就是在提前喊救命。
  4. ERROR:记录“请求失败但系统还能对外服务”。比如下游返回500。这时候必须打印堆栈和上下文参数,否则很难复现。
  5. FATAL:记录“整个进程马上就要挂了”。无可用内存、配置严重错误。我曾经给一个FATAL日志后面加了System.exit(1),结果被运维骂了一顿——他说你应该让进程自行崩溃,而不是主动自杀。想想也是。

避坑指南:我曾经踩过的坑

  • 我曾经在ERROR日志里不打印异常对象,只打了个字符串“出错了”。结果线上排查时根本不知道谁出的错、哪行代码,花了大半天才找到根因。从那以后我要求团队:ERROR级别必须打全异常栈,logger.error("消息", e),别嫌长。
  • 我曾经在循环体里打INFO日志,每秒输出几万条。日志系统直接被打崩,磁盘也满了。现在我用一个简单规则:循环内只打DEBUG,如果需要监控,用指标(如Prometheus)替代。
  • 更离谱的一次,有同事把FATAL当INFO用,导致告警系统疯狂发短信。最后发现他写了个log.fatal("订单处理完成")——嗯,这种乱用级别的后果就是,真正的FATAL被淹没在噪音里,没人重视。
警告:不要在日志中拼接用户敏感信息(密码、身份证号、完整手机号)。即使打了ERROR级别也不行。我曾经见过同事把SQL语句原样打印,里面包含明文密码——这是严重的安全事故。建议在日志框架中统一做脱敏过滤器。

日志级别与生产环境的配置策略

我通常推荐这样的配置模板(以logback为例):

<root level="WARN">
    <appender-ref ref="FILE"/>
</root>

<logger name="com.example.service" level="INFO"/>
<logger name="com.example.debug" level="TRACE"/>

注意:根级别设成WARN,只保留重要信息;但针对核心业务包可以单独降级到INFO。排查问题时,临时把某个包切到DEBUG即可,不用重启——多数框架支持动态修改。我记得有一次线上定位性能瓶颈,就是靠curl修改了日志配置,DEBUG打开后秒找到热点SQL。

一张图看懂日志级别

下面这张图我经常用来培训新人:从下往上,级别越来越严重,在生产环境通常只开WARN及以上。注意箭头方向——日志框架过滤时,会丢弃低于设定级别的所有消息。

日志级别金字塔 & 生产推荐阈值 DEBUG(开发环境默认) INFO(生产可选开启) WARN(生产推荐下限) ERROR FATAL ▼ 过滤线(生产常用阈值)
小结:日志级别不是越多越好,而是越精准越好。我个人的经验是:开发时DEBUG随便打,提交代码前检查一下级别是否合理;生产环境默认开WARN,核心业务包INFO;出现ERROR或FATAL必须立刻响应。记住——日志是你系统留给自己的“遗言”,级别就是这段话的紧急程度。