2、日志系统基础:日志的作用、日志级别、日志格式规范

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

我刚入行那会儿,觉得写日志就是给代码加几个 print,没啥技术含量。直到有一次线上服务半夜挂了,我对着黑乎乎的终端,完全不知道发生了什么。从那以后,我养成了一个习惯——日志写不好,排查两行泪

2.1 日志的作用:不只是记录

日志到底有什么用?我总结了三层价值:

  • 故障定位:系统出问题了,日志是第一现场。你想想看,没有日志就像警察破案没有监控。
  • 行为审计:谁在什么时候做了什么操作,日志里一清二楚。安全合规全靠它。
  • 性能分析:接口慢在哪?数据库查询耗时多少?日志里的时间戳就是最好的性能指标。

我个人习惯:每个关键业务操作,至少打一条 INFO 日志。这样出了问题,我能顺着日志把整个请求链路串起来。

2.2 日志级别:选对级别,少背锅

日志级别不是随便选的。选错了,要么日志太多把磁盘撑爆,要么关键信息没打出来。我见过最惨的一次,同事把所有日志都打成了 DEBUG,结果线上磁盘三天就满了……

常见的日志级别,从低到高:

级别 含义 什么时候用
DEBUG 调试信息 开发环境、本地调试。线上环境建议关闭
INFO 普通信息 业务关键节点、服务启动/停止、配置加载
WARN 警告 不影响运行但值得关注的情况,比如重试、降级
ERROR 错误 功能不可用、异常抛出,需要人工介入
FATAL 致命错误 系统即将崩溃,比如内存溢出、数据库连接池耗尽

避坑指南:我曾经在一个项目里,把数据库连接失败打成了 WARN 级别。结果线上数据库挂了,告警没触发,整整半小时没人发现……从那以后,凡是影响核心功能的异常,一律 ERROR 起步

2.3 日志格式规范:统一就是效率

日志格式不统一,排查起来有多痛苦?我举个例子:

团队 A 的日志:2024-01-01 12:00:00 [INFO] 用户登录成功

团队 B 的日志:[12:00:00] INFO - login success

你想想看,用 grep 查日志的时候,光是时间格式就够你喝一壶的。

我推荐的标准格式:

[时间] [线程名] [日志级别] [类名:行号] - [请求ID] 日志内容

举个例子:

[2024-01-01 12:00:00.123] [http-nio-8080-exec-1] [INFO] [UserController:56] - [req-abc123] 用户登录成功,userId=10086

这里面每个字段都有用:

  • 时间:精确到毫秒,方便做耗时分析
  • 线程名:多线程环境下,知道是哪个线程出的问题
  • 类名:行号:快速定位代码位置
  • 请求ID:把一次请求的所有日志串起来,这是排查分布式问题的关键

注意:日志里不要打敏感信息!密码、身份证号、银行卡号,这些绝对不能出现在日志里。我曾经见过一个同事,把用户密码明文打到了日志里,结果被安全部门通报批评……

2.4 实战建议:日志配置示例

嗯,这里我直接给一个 logback 的配置示例,你拿去就能用:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/var/log/app/app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger{36}:%line] - [%X{requestId}] %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/var/log/app/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

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

这个配置做了三件事:

  1. 按天滚动日志,保留 30 天
  2. 日志格式统一,包含请求ID
  3. 线上只打 INFO 及以上级别,避免 DEBUG 日志刷屏

最后说一句:日志系统就像保险,平时觉得没用,真出事了才知道它的价值。别等到线上故障了,才后悔日志没打好。

下一章,我会带你实战搭建一个完整的日志采集系统。到时候你就知道,日志这东西,玩好了能救命。