日志基础认知:从零开始理解日志
说实话,我做了十几年运维,见过太多因为日志没用好而翻车的案例。有一次凌晨三点,线上服务突然挂了,大家手忙脚乱翻日志,结果发现日志级别设成了 DEBUG,一天就刷了几十 G 数据,关键的错误信息早被淹没了。嗯,从那以后,我每次搭建新系统,第一件事就是先把日志规范定好。
这一章,咱们就聊聊日志最基础的东西。别觉得基础不重要,你想想看,地基打不牢,后面排查问题的时候,你连从哪下手都不知道。
什么是日志?
日志,说白了就是系统运行时的「黑匣子」。它记录着系统在什么时间、哪个模块、干了什么事、结果怎么样。
我个人习惯把日志分成三类:
- 系统日志:操作系统层面的,比如 Linux 的 /var/log/messages
- 应用日志:业务代码自己打的,比如用户登录、订单创建
- 访问日志:Web 服务器的,比如 Nginx 的 access.log
我在项目中遇到过最离谱的情况——有个同事把日志全写到了系统日志里,结果排查问题时,应用日志干干净净,系统日志里却混着业务信息和内核报错。那叫一个乱。
日志的作用:不只是记录
很多人觉得日志就是出问题了才看。其实不然。日志的作用,我总结为四点:
- 故障排查:这是最直接的。系统崩了,日志就是第一现场。
- 性能分析:通过日志里的响应时间、QPS,能看出系统瓶颈在哪。
- 安全审计:谁在什么时间做了什么操作,日志里一清二楚。
- 业务监控:比如电商大促时,通过日志实时看订单量、支付成功率。
核心观点:日志不是写给机器看的,是写给人看的。你打的每一行日志,都可能成为未来救命的线索。
日志级别:DEBUG / INFO / WARN / ERROR / FATAL
日志级别这东西,看似简单,但用错的人真不少。我见过有人把所有日志都打成 ERROR,结果真正出问题时,根本分不清哪个是致命错误,哪个只是小警告。
咱们一个一个说:
| 级别 | 含义 | 什么时候用 | 我的经验 |
|---|---|---|---|
| DEBUG | 调试信息 | 开发环境、定位具体代码逻辑 | 生产环境千万别开,否则磁盘会爆炸 |
| INFO | 普通信息 | 记录关键业务流程,比如用户登录成功 | 我习惯用它记录「谁、什么时间、做了什么」 |
| WARN | 警告 | 系统还能跑,但可能有隐患 | 比如磁盘使用率超过 80%,就该报警了 |
| ERROR | 错误 | 功能不可用,但系统没挂 | 比如数据库连接失败,需要人工介入 |
| FATAL | 致命错误 | 系统即将崩溃,必须立即处理 | 我一般只在进程启动失败时用这个级别 |
避坑指南:我曾经接手过一个项目,所有日志都打成了 INFO,包括异常堆栈。结果排查问题时,根本不知道哪些是正常流程,哪些是报错。后来我强制要求:异常信息必须用 ERROR 级别,并且要带上完整的堆栈。
日志的格式标准
日志格式,我见过最乱的——有人只打了一行「error occurred」,连时间戳都没有。你想想看,出问题了你连什么时候发生的都不知道,怎么查?
我个人推荐的标准格式是:
[时间戳] [日志级别] [线程名] [类名:行号] - 日志内容
举个例子:
[2025-01-15 14:30:22.123] [ERROR] [http-nio-8080-exec-3] [OrderService.java:45] - 订单创建失败,订单号:20250115001,原因:库存不足
这里面每个字段都有用:
- 时间戳:精确到毫秒,方便定位问题发生的时间点
- 日志级别:快速筛选,只看 ERROR 或 WARN
- 线程名:多线程环境下,知道是哪个线程出的问题
- 类名:行号:直接定位到代码位置,省得翻源码
- 日志内容:关键的业务信息,比如订单号、用户 ID
小技巧:我习惯在日志里加上「traceId」,也就是一次请求的唯一标识。这样一次请求经过多个服务时,可以通过 traceId 把日志串起来。这在微服务架构下特别有用。
本章知识体系
下面这张图,帮你把这一章的核心逻辑串起来:
嗯,这一章的内容就到这。日志这东西,看着简单,但用好了能救命,用不好就是灾难。下一章咱们聊聊怎么在 Java 里打日志,包括 Logback 和 Log4j2 的配置,以及一些实战中的坑。
一句话总结:日志不是随便打的,它需要规范、需要思考、需要用心。你对待日志的态度,决定了你排查问题的效率。
可可精品资料库