日志系统设计原则:从分级到性能,一个都不能少
日志这东西,说起来简单——不就是往文件里写点字吗?但真到了分布式系统里,日志往往是第一个崩溃的环节。我在好几个项目里都吃过日志的亏,有一次线上故障排查,发现关键日志全被 DEBUG 信息淹没了,气得我差点把键盘砸了。
所以这一章,咱们把日志系统的设计原则掰开揉碎讲清楚。你想想看,一个日志系统如果设计得不好,它就不是帮手,而是累赘。
日志分级:别让所有消息挤在一个桶里
日志分级是基础中的基础。说白了,就是给每条日志贴个标签,告诉系统「这条消息有多重要」。
| 级别 | 含义 | 典型场景 | 我建议的用法 |
|---|---|---|---|
| DEBUG | 调试信息 | 变量值、函数入口/出口、循环次数 | 只在开发环境开启,生产环境默认关闭 |
| INFO | 常规信息 | 服务启动、请求到达、任务完成 | 记录业务关键节点,别太频繁 |
| WARN | 警告信息 | 配置异常、重试次数超限、降级触发 | 需要关注但不影响当前流程 |
| ERROR | 错误信息 | 数据库连接失败、请求超时、业务异常 | 必须记录堆栈和上下文 |
核心原则:生产环境只开 INFO 及以上级别。DEBUG 日志如果上了生产,磁盘 IO 和存储成本会让你哭的。
我记得有一次,团队里新来的同事把 DEBUG 日志开到了生产环境,结果一天下来日志文件涨了 200GB,直接把磁盘撑爆了。嗯,从那以后我们就在配置中心里加了个硬限制——生产环境不允许动态开启 DEBUG 级别。
日志格式规范:机器和人看着都舒服
日志格式这事,很多人不重视。觉得「能看就行」。但你想过没有,当你有 100 台机器、每天产生 10TB 日志的时候,格式不规范就意味着没法自动化处理。
我个人习惯用这种格式:
[时间戳] [线程名] [日志级别] [类名:行号] [追踪ID] - 消息内容
举个例子:
[2025-03-21 14:30:22.123] [http-nio-8080-exec-3] [INFO] [OrderService:45] [trace-abc123] - 订单创建成功,订单号:ORD20250321001
小技巧:时间戳一定要带毫秒和时区。我见过太多因为时区问题导致日志时间对不上的坑了。
为什么需要这些字段?
- 时间戳:定位问题的时间窗口
- 线程名:排查并发问题
- 日志级别:快速过滤
- 类名:行号:定位代码位置
- 追踪ID:串联一次请求的完整链路
我曾经在一个项目里,因为没有统一格式,日志解析脚本写了三天还没搞定。后来强制统一格式,解析脚本半小时就写完了。你想想看,这时间花得值不值?
日志滚动策略:别让日志吃掉你的磁盘
日志滚动,说白了就是「旧日志怎么处理」。不滚动的后果是什么?磁盘满了,服务挂了。
常见的滚动策略有这几种:
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 基于时间 | 按天/小时生成新文件 | 日志量稳定,便于按时间归档 |
| 基于大小 | 文件达到阈值后滚动 | 日志量波动大,控制单文件大小 |
| 混合策略 | 时间和大小双重触发 | 大多数生产环境推荐 |
我建议的配置:
# 按天滚动,保留30天
log.file.rolling-policy = time-based
log.file.max-history = 30
# 同时限制单文件大小
log.file.max-size = 500MB
注意:不要只依赖一种策略。我曾经遇到过日志量突然暴增,按天滚动还没到时间,磁盘就满了。从那以后,我都是时间和大小双重限制。
另外,压缩也是个好习惯。旧日志用 gzip 压缩,能省 80% 以上的空间。代价就是查旧日志的时候需要解压,但比起磁盘爆掉,这点代价完全可以接受。
日志性能考量:别让日志拖垮你的系统
日志写入是 IO 操作,而 IO 是系统性能的瓶颈之一。如果日志系统设计得不好,它能把一个高性能服务拖成蜗牛。
几个关键点:
- 异步写入:日志写入不要阻塞业务线程。用异步队列,业务线程只管丢消息,后台线程负责写磁盘。
- 批量刷盘:每写一条就刷一次盘,性能极差。攒一批再刷,吞吐量能提升 10 倍以上。
- 缓冲区大小:缓冲区太小会导致频繁刷盘,太大又浪费内存。我一般设 8KB-64KB,根据日志量动态调整。
- 日志级别过滤:在写入之前就过滤掉低级别日志,别让它们进入 IO 管道。
性能数据参考:在同等硬件条件下,同步写入每秒约 5000 条,异步写入每秒可达 10 万条以上。差距就是这么大。
我曾经优化过一个日志系统,把同步改异步、单条改批量,日志写入性能从 3000 条/秒提升到了 12 万条/秒。业务接口的 P99 延迟也从 200ms 降到了 50ms。你看,日志优化带来的收益,远不止日志本身。
知识体系总览
下面这张图,把日志系统设计原则的核心脉络串起来了。你可以把它当作本章的「思维导图」。
这四个方面,缺一不可。分级决定了你看到什么,格式决定了你能不能看懂,滚动决定了系统能跑多久,性能决定了系统跑得快不快。