政策快报平台上线第一年基本没有日志系统。代码里到处是System.out.println()出了问题就登录服务器翻日志文件。运气好找到了运气不好找半天找不到。有一次凌晨2点系统报警爬起来查了2小时没查到原因。最后是重启了服务器问题消失了。但不知道原因心里一直悬着。后来我们花了一年多时间建了一套完整的日志系统。现在出了任何问题5-10分钟内能定位到具体代码行。今天复盘这套系统的演进过程。3个阶段阶段一文件日志第一年最原始的状态。每个服务把日志写在本地文件里按天切割。优点简单不需要额外系统缺点查日志要登录服务器用grep翻文件。多台服务器的情况下要一台一台翻。跨服务的调用链完全查不了某次一个用户反馈页面打不开我们3个人分别登录3台服务器翻了2小时才找到一条异常日志。效率极低而且这个过程里用户一直在等体验很差。阶段二集中式日志第二-三年把所有服务的日志统一收集到一个中心建立检索能力。架构Filebeat采集日志 → Kafka传输 → Elasticsearch存储 → Kibana检索查询。优点不用登录服务器一个界面查所有日志支持全文检索比grep快很多缺点查询速度还是不够快日志量大了之后ES存储成本高接入集中式日志后的第一周我们定位问题的平均时间从小时级降到了分钟级。有一次一个接口超时我们在Kibana里搜了5分钟就找到了原因——某个SQL查询没有命中索引。但新问题出现了ES的存储成本越来越高每天新增几十GB日志保留7天需要几百GB存储。阶段三分级存储与采样现在把日志分成重要和普通两类不同策略处理。重要日志错误、告警全量采集保留30天普通日志访问、调试采样采集比如只采10%保留7天另外加了一个一键拉取功能发现问题时可以手动触发全量采集当前日志平时只采10%需要的时候可以临时调高采样率实时采集所有日志用于定位问题。效果存储成本下降了60%排查问题的速度基本没变。日志内容的设计除了系统日志里写什么也很重要。我们早期日志写得随意异常只打印了堆栈没有上下文关键操作没有日志出了事不知道执行到哪里上下文信息缺失只知道出错了但不知道是哪个用户、哪个政策、哪个参数导致的。后来规范了日志内容每个日志必须包含时间戳、服务名、请求ID用于关联同一请求的所有日志、用户ID如果有、关键参数。有了请求ID跨服务的调用链路就能串起来了。一个请求从网关到A服务到B服务到数据库所有日志用同一个请求ID查起来非常清楚。3条经验第一日志系统要尽早建。第一天就建成本最低。后期再补数据补不回来。第二日志内容比日志系统更重要。再好的ELK日志里没写关键信息也查不出来。第三采样是控制成本的有效手段。不是所有日志都值得全量保存。有选择地采能省很多钱。