日志分析入门:日志级别、格式解析与常用框架

日志这东西,说白了就是程序的「黑匣子」。

我刚入行那会儿,觉得日志就是随便打印点东西,方便自己调试。直到有一次线上出了个诡异的内存泄漏,查了三天没头绪。最后是一位老同事翻了半天日志,从几万行 WARN 里揪出了一条关键线索。嗯,从那以后,我再也不敢小看日志了。

今天我们就来聊聊日志分析的基础。你想想看,如果连日志都看不懂,怎么定位缺陷?

一、日志级别:你的程序在「喊」什么?

日志级别,就是给信息贴个标签。告诉你看日志的人:这条信息有多严重。

我个人习惯把日志级别分成四个档次,从轻到重:

级别 含义 什么时候用?
DEBUG 调试信息 开发阶段,用来跟踪变量、流程。线上环境一般关掉。
INFO 普通信息 记录关键业务节点,比如「用户登录成功」「订单已创建」。
WARN 警告 程序还能跑,但有点不对劲。比如「磁盘空间不足80%」「重试第3次」。
ERROR 错误 程序出问题了,需要人工介入。比如「数据库连接失败」「空指针异常」。

核心原则:线上环境只开 INFO 及以上。DEBUG 日志量太大,会拖垮性能。

我在项目中遇到过一件事:有个同事把关键的业务校验逻辑写在 DEBUG 日志里。结果线上环境没开 DEBUG,那个校验根本没执行。你说坑不坑?

避坑指南:我曾经见过有人把「用户密码错误」这种敏感信息打在 INFO 级别。结果日志被运维同学不小心发到了群里。嗯,隐私问题,一定要注意。

二、日志格式解析:别让信息「裸奔」

日志光有内容不够,还得有「身份证」。一条合格的日志,应该包含以下信息:

  • 时间戳:精确到毫秒。方便定位问题发生的时间点。
  • 线程名:多线程环境下,知道是哪个线程出的问题。
  • 日志级别:一目了然。
  • 类名/方法名:快速定位代码位置。
  • 消息内容:具体发生了什么。

举个例子,一条典型的 Logback 日志长这样:

2025-03-21 14:32:18.456 [http-nio-8080-exec-3] INFO  com.example.OrderService - 订单创建成功,订单号:ORD20250321001

你想想看,如果没有时间戳,你怎么知道这个错误是今天发生的还是上周的?如果没有线程名,并发场景下你根本分不清谁是谁。

我的小技巧:我个人习惯在日志里加上「请求ID」或者「TraceID」。这样一次用户请求的所有日志都能串起来。排查问题时,一条命令就能把整个调用链拉出来。

三、常用日志框架:Log4j 与 Logback

Java 世界里,日志框架就那几家。我重点说说 Log4j 和 Logback。

3.1 Log4j:老牌劲旅

Log4j 是 Apache 的项目,出道早,用的人多。配置方式比较传统,用 .properties 文件。

一个简单的 log4j.properties 示例:

# 设置根日志级别为 INFO,输出到控制台和文件
log4j.rootLogger=INFO, console, file

# 控制台输出
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %m%n

# 文件输出
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logs/app.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %m%n

这里要注意 RollingFileAppender。它会在文件达到 10MB 时自动滚动,保留最近 5 个备份。防止日志文件撑爆磁盘。

避坑指南:我曾经见过有人把 MaxBackupIndex 设成 0。结果日志文件越滚越大,最后把磁盘写满了。嗯,这个参数一定要设个合理的值。

3.2 Logback:Log4j 的升级版

Logback 是 Log4j 的作者写的另一个框架。性能更好,功能更强。现在 Spring Boot 默认就用它。

Logback 用 logback.xml 配置。举个例子:

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

Logback 有个很实用的功能:根据日志级别输出到不同文件。比如 ERROR 日志单独存一个文件,方便排查。

<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/error.log</file>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
    <!-- 其他配置略 -->
</appender>

我的建议:我个人习惯把 ERROR 日志单独拎出来。线上出问题时,直接 tail -f error.log,不用在 INFO 的海洋里捞针。

四、知识体系一览

说了这么多,我画张图帮你理一理。日志分析的核心就这三块:

日志分析入门 日志级别 DEBUG / INFO WARN / ERROR 日志格式解析 时间戳 / 线程名 类名 / 消息内容 常用日志框架 Log4j Logback 核心目标 快速定位问题 → 减少排查时间 规范日志输出 → 提升系统可观测性

说白了,日志分析就是三个步骤:看级别 → 读格式 → 用框架。级别告诉你严重程度,格式告诉你上下文,框架帮你把日志管好。

我个人觉得,日志这东西,前期多花点心思配置好,后期能省下大把时间。你想想看,线上出问题时,别人还在翻山越岭找日志,你一条命令就定位到了。那种感觉,嗯,挺爽的。

一句话总结:日志不是写给机器看的,是写给未来的自己看的。别偷懒,好好配。

可可精品资料库