页面的访问量大概是多少,用户主要使用什么平台,业务高峰出现在什么时候?卢依宁用这三个问题打开分享:前端监控不仅是收集报错,也能帮助工程师理解业务、定位问题,并主动发现体验改进的空间。
这段分享来自深圳“前端的挑战与机遇”录播第 1 段,所属稿件发布于 2022 年 5 月 9 日。卢依宁介绍的是当时货拉拉团队的建设与案例,产品能力、价格和监控指标均保留历史语境。
先确定监控要回答什么
卢依宁把需求分成三类:理解用户怎样使用产品,追查一次具体问题,以及观察真实页面与资源加载性能。对应的数据也不同:访问与自定义事件帮助理解业务,用户访问过程、请求与错误帮助排查,性能记录帮助找优化空间。
这些证据让前端能参与更多业务判断。遇到有争议的需求、用户反馈或体验问题时,工程师不只负责按图实现,还可以通过数据提出解释与建议。不过,有数据不等于已经有结论,仍需要理解业务含义。原片 01:06—05:20
为什么最终选择自研
他比较了当时接触过的几类方案。Sentry 的错误上下文和 source map 关联对定位代码有帮助,但团队常常从“谁在什么时间访问哪个页面”开始追查,因而更希望按用户、页面和请求组织信息。
其他方案的页面、接口、性能面板更接近所需形态,但日志规模带来的费用、私有部署和数据存放方式,又影响选择。团队最后决定自研,并借鉴成熟方案的信息组织方式。
这段比较说明的是当时团队的需求与选择,不能推出某个产品普遍无用,也不能把历史报价或当时没找到的部署选项当作今天的产品结论。原片 05:22—09:57
架构分成采集、处理和查询
方案由 Web 与小程序 SDK 采集日志,服务端接收后清洗、转换,再存入相应系统。原始日志进入 Elasticsearch,由 Kibana 查询细节;另一条链路产生时序指标,通过 Grafana 观察曲线。
两类界面服务于不同任务:大盘帮助发现什么时候、哪个范围发生变化,明细查询帮助深入到某一次访问或请求。页面访问、接口、错误、资源、性能及自定义事件,也应各自有明确用途,而不是尽可能多收集一切。原片 09:58—13:07
先设计接入方式,再组织 SDK
卢依宁希望接入尽量简单,例如引入脚本并指定项目。SDK 同时提供配置,控制监控项、忽略部分请求,以及在业务允许的范围内关联用户标识。用户关联用于把业务反馈与技术记录接起来,不意味着所有字段都应该无限制记录或公开访问。
实现上,各监控模块负责采集,统一发送模块处理延迟、批量、重试和退出时的发送策略。这样可以避免每个采集项各自实现一套上报逻辑。原片 13:07—14:33、17:35—19:07
上报策略要考虑体积、连接和退出
片中比较图片请求、POST 和长连接。图片请求简单,但 URL 承载数据有限,不适合任意大的批量;POST 更便于在请求体传数据,但要处理跨域及页面退出等情况;长连接则增加连接管理和服务端资源成本。
团队选择批量 POST,通过队列聚合、定时发送并处理失败重试,页面退出相关场景再考虑 sendBeacon 等机制。这里的取舍取决于日志量和使用环境,不是说某种方式在所有应用都不可用;请求体和浏览器后台发送也都有实际限制,退出时发起发送不等于绝对保证送达。原片 14:33—17:35
Web 采集:保留原行为,再插入观察逻辑
**请求。**分享以 XMLHttpRequest 为例,在原有方法外记录需要的信息,再调用原实现。关键不只是取得数据,还要避免破坏业务原有调用和回调。这个示例说明一种采集入口,不代表已经覆盖所有浏览器网络通信方式。
**错误。**除 window.onerror,还关注未处理的 Promise rejection,以补充异步失败的线索;记录内容包括消息、堆栈与位置等可获取信息。采集到事件后,仍要结合页面和请求判断影响。
**页面访问。**单页应用不会每次路由变化都整页刷新,因此需分别观察 hash 与 History 路径。片中展示监听 hashchange、包装 pushState 和 replaceState,以及记录前后地址的思路。这是核心示例,完整接入仍要覆盖应用实际导航行为。
**资源。**通过 Performance API 查看资源条目,再按类型筛选需要的静态资源,避免把接口或 SDK 自己的发送混入资源统计。不同类型、时序与浏览器条件下可取得的信息并不完全相同。原片 19:07—27:43
体积优化与小程序适配
SDK 自身也会增加页面负担。卢依宁展示当时精简版实现的体积,并解释功能范围较窄是原因之一;同时通过可压缩的局部变量、复用引用和较简单的打包封装减少重复代码。压缩前后数字对应特定实现,不能只比较 KB 就判断不同监控系统优劣。
小程序部分则先抽象不同宿主的全局接口,再包装请求、页面生命周期和应用错误入口。这样公共逻辑不必到处写死某一平台变量,平台差异可以集中处理。总体原则仍是保留原业务行为,插入采集逻辑,再统一发送。原片 27:43—33:24
两条排查路线:从人出发,从曲线下钻
司机反馈往往只有截图、身份和一句“按钮点不了”或“页面打不开”。团队先把业务标识转换成可查询入口,再按用户、时间、页面寻找记录,继续检查请求及错误,并利用链路标识和后端协作。这使前端日志成为连接业务反馈与服务端信息的桥梁。
另一条路线从整体异常出发:先看访问或业务接口结果的曲线,再按时间、页面、状态分布筛选日志。业务返回码与 HTTP 状态不是同一个维度,需要按本产品语义解释;流量突变也只是线索,不能自动等同于故障。原片 33:25—37:35
案例一:白屏背后是参数与业务链路
收到点击入口后白屏的视频时,卢依宁先检查发布情况及影响范围。页面本身已经被打开,空白发生在内容显示,于是按反馈时间查相关请求和日志。
异常返回把范围缩小到具体请求,再对照入口和参数,发现其中一项参数有误,随后与后端共同处理。日志提供证据,但要知道参数代表什么、上下游如何调用,仍依赖对业务的理解。原片 37:35—39:11
案例二:某个渠道数据骤降,先与其他入口比较
运营发现一个渠道的数据突然下滑。团队对照网页和客户端的发布时序,再查看该渠道入口页面的访问量:相应时段确实下降,而其他渠道没有同样变化。
这种比较让疑点转向渠道投放,提供给运营继续确认。它不是仅凭“某天没有发布”就排除技术问题,而是把多条时间与流量证据拼在一起,缩小需要调查的范围。原片 39:11—41:23
案例三:城市定位异常,实际暴露了默认值问题
司机注册需要填写城市,原有流程会尝试自动填入位置。某段时间后,特定城市区域的无效注册明显增加,但相关前端功能没有相应修改。
团队分析异常数据,发现它们不是均匀落在各区,而是集中到特定区域;部分来源 IP 只能定位到省,不能准确到市。继续结合当时应用权限行为的变化,推测更多请求进入了 IP 定位与默认值路径,把不确定的信息填成了看似确定的城市。
最后推动产品调整:在可用且获得授权的环境获取更可靠的位置;无法可靠判断时,放弃自动填充,让用户选择。案例的要点不是某种定位永远准确,而是不要用一个确定外观的默认值掩盖不确定性。原片 41:24—46:00
案例四:请求突增,通过前后端证据协同处理
服务端发现接口请求突然增加后,前端先确认页面侧是否也有相应访问和请求变化,再按时间窗口与关联标识查找异常活动。
片中展示的记录包含短时大量请求、较少页面访问和其他异常特征,团队据此怀疑自动化异常请求,并联系安全人员一起限制异常访问。日志关联帮助提出可验证的判断,但浏览器标识并不等于对真实自然人身份的确定证明,仍需与服务端和安全团队的证据结合。原片 46:00—48:37
告警必须理解业务节奏
同一次故障,不同页面的曲线可能朝相反方向变化:正常业务入口下降,用户求助或反复尝试的页面上升;恢复后又可能出现积压需求带来的反弹。监控因此需要读懂角色与业务路径。
团队尝试过按短时访问倍增或减半告警,但也遇到有明确上下班和午休规律的内部系统:规律性涨跌会让简单阈值反复误报。卢依宁最后强调,规则需要按业务特征调整,不能指望一条统一阈值适用于所有项目。原片 48:38—50:40
这也呼应开场的问题:监控价值不止来自部署了 SDK,而在于团队会用数据理解业务,并把发现的问题推进到解决。大盘与明细、技术事件与用户行为,需要在真实排查中持续连接起来。原片 50:42—53:39
