日志基础:日志的作用、日志级别与格式规范
聊到日志,很多刚入行的朋友会觉得——不就是打印点信息嘛,有啥好讲的?
说实话,我当年也是这么想的。直到有一次线上故障,生产环境出了个诡异的内存泄漏,我翻遍了所有日志,发现全是 System.out.println 打出来的零散信息,连个时间戳都没有。那一次,我整整排查了三天三夜。
从那以后,我对日志的态度彻底变了。日志不是写给机器看的,是写给未来的自己看的。
日志到底有什么用?
我个人习惯把日志的作用归纳为四个核心场景:
- 故障定位:系统出问题了,日志是第一手线索。没有日志,你就像在黑夜里找钥匙。
- 行为审计:谁在什么时候做了什么操作?日志就是你的监控摄像头。
- 性能分析:接口响应慢?看看日志里的耗时记录,瓶颈一目了然。
- 业务监控:订单量、错误率、用户行为……日志里藏着业务的全貌。
我的经验之谈:在SOA架构里,一个请求会经过多个服务。如果没有统一的日志规范,你根本没法把调用链串起来。我曾经接手过一个项目,每个服务用的日志格式都不一样,有的用JSON,有的用纯文本,有的连时间格式都不统一。嗯,那感觉就像在拼一幅缺了无数块的拼图。
日志级别:别什么都打INFO
日志级别这个东西,看起来简单,但用对的人真不多。我见过太多项目,生产环境开着DEBUG跑,结果磁盘三天就满了。也见过一些项目,所有错误都打WARN,真正的致命异常反而被淹没了。
标准日志级别一般有五个,但最常用的是这四个:
| 级别 | 含义 | 使用场景 | 生产环境是否开启 |
|---|---|---|---|
| DEBUG | 调试信息 | 开发阶段,跟踪变量、流程细节 | 否 |
| INFO | 普通信息 | 系统运行状态、关键业务节点 | 是 |
| WARN | 警告信息 | 潜在问题,但不影响当前功能 | 是 |
| ERROR | 错误信息 | 功能异常、需要人工介入 | 是 |
避坑指南:我曾经见过一个团队,把所有的业务异常都打成了ERROR。结果每天几千条ERROR日志,真正的系统级故障反而被淹没了。记住,ERROR只留给那些需要立即处理的问题。业务上的参数校验失败,打WARN就够了。
为什么会这样?你想想看,如果每个小问题都打ERROR,运维人员就会产生「狼来了」效应。等到真正的灾难发生时,反而没人重视了。
日志格式规范:统一就是力量
在SOA架构里,日志格式不统一,简直就是灾难。我建议每个日志条目至少包含以下字段:
- 时间戳:精确到毫秒,格式统一为
yyyy-MM-dd HH:mm:ss.SSS - 日志级别:DEBUG/INFO/WARN/ERROR
- 线程名:方便追踪并发问题
- 类名/方法名:快速定位代码位置
- 请求ID:串联整个调用链的关键
- 消息内容:清晰、简洁、包含关键参数
来看一个我常用的日志格式示例:
2024-01-15 14:23:45.678 [http-nio-8080-exec-3] INFO com.example.OrderService - [traceId=abc123] 创建订单成功, orderId=98765, amount=299.00
这个格式看起来简单,但每个字段都有它的意义。比如 traceId,在微服务调用链里,它就是串联所有日志的「线」。没有它,你根本不知道哪个请求对应哪些日志。
小技巧:我个人习惯在日志里加上关键参数的摘要,比如订单ID、用户ID。但注意,不要打印敏感信息,比如密码、身份证号。我曾经见过一个项目,日志里直接打印了用户的银行卡号……嗯,那后果你懂的。
日志内容怎么写才有效?
说白了,日志内容要遵循三个原则:
- 可读性:别用一堆缩写,别人看不懂。比如
usrId写成userId不好吗? - 可搜索性:关键信息要突出,方便用 grep 或 ELK 搜索。比如订单号、用户ID这些,单独拎出来。
- 可关联性:同一个请求的日志,要有共同的标识符(traceId)。
举个例子,不好的写法是这样的:
2024-01-15 14:23:45.678 INFO 处理订单成功
好的写法是这样的:
2024-01-15 14:23:45.678 [http-nio-8080-exec-3] INFO com.example.OrderService - [traceId=abc123] 订单处理完成, orderId=98765, status=PAID, 耗时=123ms
你看,后者多了多少信息?traceId 让你能串联整个调用链,耗时让你能判断性能瓶颈,status 让你知道当前状态。这才是有效的日志。
关于日志,我想说的最后一点
日志不是写完了就完事了。它需要持续维护、持续优化。我每半年会做一次日志审计,看看哪些日志是多余的,哪些地方信息不够。记住,日志是你的「系统黑匣子」,平时可能用不上,但一旦出事,它就是你的救命稻草。
嗯,这一节就到这里。下一节我们会聊聊日志采集和集中管理,到时候我会分享一些我在ELK和EFK实战中的踩坑经历。