第2章:日志采集基础

日志这东西,说白了就是系统的「黑匣子」。我做了这么多年推荐系统,每次线上出问题,第一反应就是去翻日志。没有日志,你就像在黑暗中开车,撞了都不知道撞的是什么。

2.1 日志的概念与作用

日志是什么?简单说,就是系统运行时产生的记录。每一行日志,都记录了一个事件——谁、在什么时间、做了什么、结果如何。

在推荐系统里,日志的作用可大了去了。我个人习惯把它分成三类:

  • 调试日志:帮开发人员定位Bug。比如用户点击了推荐位,但没跳转,日志里就能看到是哪个环节出了问题。
  • 业务日志:记录用户行为。比如曝光、点击、收藏、购买。这些数据是训练推荐模型的「原材料」。
  • 监控日志:反映系统健康状态。比如接口响应时间、错误率、QPS等。

核心观点:日志是推荐系统的「眼睛」。没有日志,你就不知道用户喜欢什么,系统哪里出了问题。

我记得有一次,线上推荐效果突然暴跌。排查了半天,最后发现是日志采集模块挂了,模型训练用的全是旧数据。嗯,从那以后,我每次上线都会先检查日志是否正常写入。

2.2 日志级别

日志级别这东西,很多新手不太在意。但我在项目中吃过亏,所以特别想强调一下。

常见的日志级别从低到高:

级别 含义 使用场景
TRACE 追踪 最细粒度的调试信息,生产环境一般不开启
DEBUG 调试 开发环境使用,排查具体逻辑问题
INFO 信息 记录关键业务流程,比如用户登录、下单
WARN 警告 系统可以继续运行,但需要注意的异常情况
ERROR 错误 影响功能的错误,需要立即处理
FATAL 致命 系统即将崩溃,需要紧急介入

避坑指南:我曾经见过一个团队,生产环境开了DEBUG级别,结果一天产生了几百GB日志,磁盘直接爆了。生产环境建议只开INFO及以上级别。

你想想看,如果所有日志都混在一起,你根本分不清哪些是重要的。合理使用日志级别,就是在给日志「贴标签」,方便后续快速定位问题。

2.3 日志格式规范

日志格式这件事,看似简单,其实坑很多。我见过最离谱的日志,连时间戳都没有,你说这怎么排查问题?

我个人推荐的标准格式:

[时间戳] [日志级别] [线程名] [类名:行号] - 日志内容

举个例子:

[2024-01-15 14:30:22.123] [INFO] [http-nio-8080-exec-1] [com.recommend.controller.RecommendController:56] - 用户ID:12345,请求推荐列表,返回10条结果,耗时45ms

这里面每个字段都有用:

  • 时间戳:精确到毫秒,方便定位问题发生的时间点
  • 日志级别:快速筛选重要信息
  • 线程名:多线程环境下,追踪请求的完整链路
  • 类名:行号:快速定位代码位置
  • 日志内容:关键的业务信息

小技巧:日志内容最好包含「上下文信息」。比如记录用户行为时,带上用户ID、行为类型、目标物品ID、时间戳。这样后续分析时,一条日志就能还原出完整的事件。

2.4 日志采集的挑战

说到日志采集的挑战,我可得好好聊聊。这玩意儿看着简单,实际做起来全是坑。

挑战一:海量数据

推荐系统的日志量有多大?我做过的一个项目,日均用户行为日志超过10亿条。你想想看,每秒要处理上万条日志,这可不是闹着玩的。

挑战二:实时性要求

推荐系统对实时性要求很高。用户点击了一个物品,我们希望能在秒级内采集到这条日志,用于实时特征更新。但日志采集本身就有延迟,怎么平衡实时性和可靠性?

挑战三:数据一致性

日志采集过程中,可能会丢数据。比如网络抖动、磁盘满了、程序崩溃。怎么保证日志不丢、不重、不乱?

挑战四:存储成本

日志数据量巨大,存储成本很高。我见过一个团队,一年光日志存储费用就花了上百万。怎么在「保留足够信息」和「控制成本」之间找到平衡?

我的经验:面对这些挑战,没有银弹。我的做法是「分层采集、分级存储」。热数据用高性能存储,冷数据压缩归档。关键业务日志做双写备份,普通日志允许一定程度的丢失。

嗯,这里要注意一点:日志采集不是「越多越好」。采集太多无用日志,只会增加成本和排查难度。我建议每个日志字段都要有明确的业务含义,能回答「为什么要采集这个字段」这个问题。

最后说一句,日志采集是推荐系统的「地基」。地基没打好,上面的模型再牛也白搭。我见过太多团队,花大把精力优化模型,却忽略了日志质量,最后模型效果上不去,还找不到原因。

所以,别小看日志采集。它可能不炫酷,但绝对值得你认真对待。