日志基础与重要性
日志这东西,说白了就是系统的「黑匣子」。我做了十几年运维,见过太多系统出问题后两眼一抹黑的场景。那时候大家围着服务器转,谁也不知道刚才发生了什么。嗯,日志就是用来回答这个问题的。
日志的作用
日志到底能干嘛?我个人习惯把它分成三个层次:
- 故障排查:系统崩了,第一反应就是翻日志。我记得有一次线上服务半夜挂了,靠的就是一条「OutOfMemoryError」日志定位到内存泄漏。
- 安全审计:谁在什么时候干了什么,日志里一清二楚。我曾经帮客户追查过数据泄露事件,就是靠登录日志和操作日志还原了整个攻击路径。
- 性能分析:接口响应慢、数据库查询超时,这些都能从日志里找到蛛丝马迹。你想想看,没有日志,你连系统在干什么都不知道。
核心观点:日志不是写给机器看的,是写给人看的。尤其是出问题时的你。
日志级别
日志级别这东西,很多团队一开始都不重视。我见过一个项目,所有日志全用 INFO 级别,结果生产环境一天刷几个 GB,真正有用的信息全被淹没了。
常见的日志级别,我一般这么用:
| 级别 | 含义 | 我的使用习惯 |
|---|---|---|
| TRACE | 跟踪 | 开发调试用,生产环境基本不开 |
| DEBUG | 调试 | 排查问题时临时开启,平时关掉 |
| INFO | 信息 | 记录关键业务流程,比如用户登录、订单创建 |
| WARN | 警告 | 不影响运行但值得关注的情况,比如配置缺失 |
| ERROR | 错误 | 需要人工介入的问题,比如数据库连接失败 |
| FATAL | 致命 | 系统无法继续运行,比如内存溢出 |
避坑指南:我曾经见过一个团队把 ERROR 当 INFO 用,结果报警系统天天响,最后大家直接无视了所有报警。日志级别不是摆设,选对了能救命。
日志格式规范
日志格式这件事,我踩过不少坑。早期做项目时,日志格式五花八门,有的用逗号分隔,有的用竖线,有的干脆就是一段话。等到要写脚本分析日志时,那叫一个痛苦。
我个人推荐的标准格式:
[时间戳] [日志级别] [线程名] [类名:行号] - 日志内容
举个例子:
[2024-01-15 14:30:22.123] [ERROR] [http-nio-8080-exec-3] [OrderService.java:45] - 订单创建失败,订单号:ORD20240115001,原因:库存不足
为什么要这么写?
- 时间戳:精确到毫秒,方便定位问题发生的时间点
- 日志级别:一眼就能看出问题的严重程度
- 线程名:多线程环境下,知道是哪个线程出的问题
- 类名和行号:直接定位到代码位置,省去翻代码的时间
- 日志内容:包含关键业务信息,比如订单号、用户ID
注意:日志里不要记录敏感信息,比如密码、身份证号、银行卡号。我曾经见过一个项目,日志里明文记录了用户的支付密码,这要是泄露出去,后果不堪设想。
日志生命周期管理
日志不是存得越久越好。你想想看,一个日活百万的系统,一天能产生几十 GB 的日志。如果不加管理,硬盘很快就满了。
我一般把日志生命周期分成三个阶段:
- 热数据(最近 7 天):保存在本地磁盘,方便实时排查问题
- 温数据(7-30 天):压缩后存储,或者发送到集中式日志平台
- 冷数据(30 天以上):归档到对象存储或者磁带库,保留以备审计
具体的保留策略,我建议这样:
| 日志类型 | 保留时间 | 存储方式 |
|---|---|---|
| 应用日志 | 30 天 | 本地 + 远程 |
| 访问日志 | 90 天 | 远程存储 |
| 审计日志 | 1 年 | 归档存储 |
| 调试日志 | 7 天 | 本地 |
我的经验:日志轮转一定要配置好。我曾经接手过一个项目,日志文件没有做轮转,结果一个文件写了 50 GB,用文本编辑器打开直接卡死。用 logrotate 或者框架自带的轮转功能,按大小或时间切分,这是基本功。
嗯,日志基础这部分就这些。说白了,日志就是系统的「眼睛」和「耳朵」。没有日志,你就像在黑暗中摸索。有了日志,你才能知道系统到底在干什么,出了问题时才能快速定位。下一章我们聊聊日志收集的实战技巧。