日志基础:日志的作用、日志级别与格式规范

聊到分布式系统,我第一个想到的其实是日志。你想想看,一个系统拆成几十上百个服务,出了问题你连它在哪崩的都不知道,那多可怕。日志,说白了就是系统的「黑匣子」。今天我们就来把日志的基础打扎实。

日志到底有什么用?

我个人习惯把日志的作用归纳为三个层面:

  • 问题排查:这是最直接的用途。线上出了故障,第一件事就是翻日志。我记得有一次半夜被叫起来,说支付接口超时,我打开日志一看,原来是数据库连接池满了,前后不到五分钟定位问题。
  • 系统监控与告警:日志是监控数据的来源之一。比如 ERROR 级别的日志突然暴增,说明系统可能出大事了。我建议每个团队都配一套日志告警规则,别等用户投诉了才去查。
  • 业务分析与审计:日志记录了用户的行为轨迹。比如用户下单、退款、修改密码,这些操作日志在审计时就是铁证。我在项目中遇到过,有一次被客户质疑数据对不上,全靠日志还原了操作链路。

一句话总结:没有日志的系统,就像没有仪表盘的飞机。你敢飞,我不敢坐。

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

日志级别这东西,看似简单,但用错了会出大问题。我见过不少团队,线上环境开着 DEBUG 日志,结果磁盘被撑爆了。嗯,这里要注意,不同级别有不同用途。

级别 含义 使用场景 线上是否开启
DEBUG 调试信息 开发阶段,打印变量值、调用链路细节 通常关闭
INFO 普通信息 记录关键业务流程,如请求开始、结束 开启
WARN 警告 潜在问题,如磁盘使用率超过80% 开启
ERROR 错误 系统异常,如数据库连接失败、空指针 必须开启

DEBUG:说白了就是给开发人员看的。我写代码时习惯在关键分支上打 DEBUG 日志,比如「用户ID=123,进入支付流程」。但线上环境千万别开,否则日志量会爆炸。

INFO:记录业务的关键节点。比如「订单创建成功,订单号=20240301xxxx」。我建议 INFO 日志要让人能看懂业务流程,而不是一堆无意义的字符串。

WARN:系统还能跑,但有点不对劲。比如「重试第3次,仍然失败」。我曾经遇到过,一个接口偶尔超时,WARN 日志帮我提前发现了问题,没等到用户投诉。

ERROR:必须立即处理的问题。比如「数据库连接失败,无法获取数据」。ERROR 日志一定要带上堆栈信息,否则你根本不知道哪里崩了。

避坑指南:我曾经犯过一个错,把业务异常也打成了 ERROR 级别。比如用户输入了错误的密码,这其实是正常流程,打 WARN 就够了。ERROR 应该留给系统级故障,而不是业务逻辑异常。

日志格式规范

日志格式不统一,是分布式系统里最让人头疼的事。你想想看,A 服务用 JSON,B 服务用纯文本,C 服务又用自定义格式,排查问题时简直想骂人。我建议团队统一使用以下格式:

时间戳 | 日志级别 | 服务名 | 线程名 | 请求追踪ID | 类名:行号 | 日志内容

举个例子:

2024-03-01 14:30:22.123 | INFO | order-service | http-nio-8080-exec-1 | trace-abc123 | com.example.OrderService:56 | 订单创建成功,订单号=20240301123456

为什么这么设计?

  • 时间戳:精确到毫秒,方便定位问题发生的时间点。
  • 日志级别:一眼就能看出问题的严重程度。
  • 服务名:分布式系统里,知道是哪个服务出的问题很重要。
  • 线程名:排查并发问题时,线程名能帮你理清调用关系。
  • 请求追踪ID:这是链路追踪的核心,能把一次请求经过的所有服务串起来。
  • 类名:行号:快速定位代码位置,省得你翻半天源码。

我的小技巧:我习惯在日志里加上「业务标识」,比如订单号、用户ID。这样在 Elasticsearch 里搜索时,直接搜订单号就能找到所有相关日志,效率翻倍。

日志内容该写什么?

日志内容不是越多越好,也不是越少越好。我总结了一个原则:能复现问题,就够了

比如一个支付接口,日志应该包含:

  • 请求参数(脱敏后):用户ID、订单号、金额
  • 关键处理步骤:调用支付网关、收到回调、更新订单状态
  • 异常信息:如果失败,记录错误码和错误描述
  • 响应结果:成功或失败,以及耗时

我见过有人把整个请求体都打印出来,里面包含用户密码、银行卡号……这其实很危险。日志里绝对不能出现敏感信息,比如密码、身份证号、银行卡号。我建议在打印前做脱敏处理。

重要提醒:日志是给人看的,不是给机器看的。别写一堆无意义的数字或编码。比如「状态码=1001」,谁知道 1001 是什么意思?不如写成「状态码=1001(支付超时)」,一目了然。

总结一下

日志这东西,平时你可能觉得它不起眼,但真出了问题,它就是你的救命稻草。我个人习惯是:

  • DEBUG 日志只在开发环境开
  • INFO 日志记录关键业务节点
  • WARN 日志关注潜在风险
  • ERROR 日志必须立即处理
  • 日志格式统一,带上追踪ID
  • 敏感信息必须脱敏

下一章我们会聊到日志采集的架构设计,到时候再深入讲讲怎么把日志从各个服务里收集起来。今天就先到这里,记住一句话:日志写得好,下班回家早