帮你快速理解、总结文档立即下载

数据上报验证

最近更新时间:2026-09-30 17:29:02
我的收藏
本文介绍接入用户体验监控 Web SDK 后,如何验证各监控能力的数据上报是否成功。

前提条件

错误监控(onError)、页面性能(pagePerformance)、Web Vitals(webVitals)、卡顿(lagMonitor)、白屏(blankScreen)、内存监控(memoryMonitor)默认开启。
接口测速(api)、静态资源测速(assets)、点击行为(click)、Console 采集(console)、会话回放(sessionReplay)、挣扎事件监测(struggleMonitor)、WebSocket 错误监控(websocket)、JSBridge 监控(bridge)、上报重试(reportRetry)默认关闭,需显式开启。
验证期间建议开启 debug: true,方便观察上报请求与运行日志。
单页应用(React / Vue 等)建议显式开启 spa: true,SDK 才会监听路由变化并上报页面浏览事件;该事件同时是挣扎检测中 back_forward 子规则的触发来源。
卡顿与内存监控虽默认开启,但存在浏览器前提:卡顿依赖 PerformanceObserver 支持 long-animation-frame,内存监控依赖 window.performance.memory(仅 Chromium 内核)。不满足前提时,这两项会被跳过采集器注册:插件实例仍处于挂载状态,但内部不会创建 PerformanceObserver 或内存采样定时器,因此既不产生任何数据,debug: true 下也不会输出对应告警。排查时不要以「插件已挂载」为依据推断「一定能采到数据」。

步骤1:检查上报请求

初始化后,SDK 会发出下列请求(会话回放默认关闭,开启后才有回放上报)。HTTP 2xx 均视为成功:
端点
内容
POST {url}/api/v1/config
远程配置预取。当前版本在初始化前先拉取该配置,只有返回 enabled 为真时才挂载各监控插件
POST {url}/api/v1/collect/events
标准事件(错误 / 页面性能 / Web Vitals / 接口与资源测速 / 点击与行为 / 挣扎 / 自定义事件等)
POST {url}/api/v1/collect/replay
会话回放录屏数据,仅在开启 sessionReplay 后上报
{url} 为初始化时填写的上报域名,国内站为 https://dem.rumt-zh.com。
其中「远程配置预取」是一道需要特别留意的闸门:若控制台侧未启用该项目,或预取请求失败且本地没有可用的 7 天缓存(localStorage 键 TDEM_SAMPLE_CONFIG),SDK 会在控制台打印 [TDEM] SDK disabled by remote config, skip initialization,随后直接返回、不初始化任何插件,既不抛异常,也不额外告警。这是接入后「一条数据都没有」最常见的成因,排查时请先确认该配置请求的返回内容。
除上述「是否初始化」的闸门外,采集管道入口还有一道事件级采样闸门,两者都通过才会有数据上报。远程配置中的 tdem_sample_rate(0 - 100,控制台配置)决定本次会话是否被采样:
取值0或缺失:即使 enabled=true、插件已正常挂载,所有事件仍会在管道入口被静默丢弃,控制台不会出现任何该项目的日志。
取值100:全部放行。
其余取值:按比例随机判定,判定结果在同一会话内保持一致(Session 要么全部上报、要么全部不上报),会话续期时重新抽样。
判定完成前产生的事件会先进入内存队列暂存(上限1000条),判定完成后统一放行或丢弃,因此不存在「部分事件漏报」的情况。在排查「远程已启用但没有数据」时,请确认 /api/v1/config 返回体中的 enabled 与 tdem_sample_rate 两个字段,而不只是 enabled。

步骤2:验证各监控能力

错误监控

初始化后,可在页面中主动触发 JS 错误来验证:
// 触发未捕获的 JS 异常
setTimeout(() => { throw new Error('tdem verify error'); }, 0);

// 触发 Promise 未捕获异常
Promise.reject(new Error('tdem verify promise error'));

接口测速

开启 api: true 后,SDK 会自动监听 XMLHttpRequest / fetch 请求并上报耗时与错误:
const tdem = new TDEM({
id: '<project-key>',
url: 'https://dem.rumt-zh.com',
api: true,
});
api 传对象时还可精细控制采集内容:apiDetail 为 true 时一并采集请求体与响应体,reqHeaders / resHeaders 指定需要附带采集的请求头 / 响应头,reportRequest 控制普通请求是否上报,retCodeHandler 用于自定义业务返回码判定。

页面性能与 Web Vitals

pagePerformance 与 webVitals 默认开启,无需额外配置。页面加载完成后,SDK 会自动上报首屏耗时及 FCP / LCP / CLS 等指标。

卡顿、白屏与内存监控

lagMonitor、blankScreen、memoryMonitor 默认开启:
卡顿:主线程出现长任务(long-animation-frame)时自动上报。该监控有两个阈值:threshold(默认 2000ms,长任务上报门槛)与 noResponseThreshold(默认 5000ms,超过即记为无响应事件)。两者存在联动约束,当配置的 noResponseThreshold <= threshold 时,SDK 会将其静默抬升为 max(5000, threshold + 1) 并输出 relation_conflict 告警;例如把 threshold 调到 6000,noResponseThreshold 会被改成 6001,而不是您配置的值。
白屏:页面采样点空白占比超过阈值(默认70%)时自动上报白屏事件。
内存:定时上报 JS 堆内存占用,超过 oomThreshold 时上报 OOM 事件。

WebSocket 错误监控

开启 websocket: true 后,SDK 会拦截 WebSocket 连接错误并上报:
const tdem = new TDEM({
id: '<project-key>',
url: 'https://dem.rumt-zh.com',
websocket: true,
});
需要说明的是,WebSocket 采集并非独立插件,而是错误监控(onError)内部的一段逻辑:websocket 只是它的子开关,命中后上报的仍是一条 js_error 族事件(mechanism_type 为 websocket,连接地址记在标签 websocket_url 中)。该能力随错误监控一同挂载,关闭 onError 会一并关闭 WebSocket 采集;websocket 也可写成对象形式 { enabled: true }。

JSBridge 监控

开启 bridge 并指定目标与方法白名单后,SDK 会覆写对应 JSBridge 方法并上报耗时:
const tdem = new TDEM({
id: '<project-key>',
url: 'https://dem.rumt-zh.com',
bridge: {
target: window.JSBridge,
methods: ['callNative'],
},
});

会话回放

会话回放默认关闭,需要显式开启:
const tdem = new TDEM({
id: '<project-key>',
url: 'https://dem.rumt-zh.com',
sessionReplay: {
enabled: true,
sessionSampleRate: 0.1, // 体验流采样率(0-1)
errorTraceback: true, // 错误回溯开关
errorSampleRate: 1.0, // 错误命中率(0-1)
},
});
四个旋钮的语义如下:
配置
默认值
说明
enabled
false
是否启用。与远程下发的 enabled 取与,两者都为真才生效
sessionSampleRate
0.1
体验流采样率,按会话随机抽取。可被远程 replay_sample_rate 覆盖(远程量纲为0 - 100)
errorTraceback
true
错误回溯开关:未抽中体验流的会话若发生错误,也补报该段回放
errorSampleRate
1.0
错误命中率,仅在 errorTraceback 为真时生效
由此产生三种常见组合:
组合
配置
会上报回放的会话
纯错误回溯
sessionSampleRate: 0 + errorTraceback: true
仅含错误的会话
体验流并集错误回溯
sessionSampleRate > 0 + errorTraceback: true
抽中的体验流会话,并含错误的会话
只看体验流
errorTraceback: false
仅按 sessionSampleRate 抽取,错误不再补报
验证前需知:未命中体验流且开启了错误回溯时,SDK 在内存缓冲区中持续攒数据,若始终没有错误发生,不会因为页面关闭等生命周期事件而 flush。因此在无错误场景下「开了回放却看不到数据」属正常现象。要快速验证,可把 sessionSampleRate 设为 1,或临时改为纯错误回溯并主动触发一次错误。

挣扎检测

挣扎检测默认关闭,需显式开启 struggleMonitor: true。它消费 SDK 其他模块产出的事件并按内置规则判定,产出下列子事件(规则版本 1.0.0,阈值内部写死、接入方不可修改):
子事件
判定规则
rage_click
同一元素1秒内连续点击达5次
dead_click
点击后3秒内未产生任何有效动作(页面跳转 / 接口成功 / 表单操作 / DOM 变更 / 打开新页等)
error_click
点击后3秒内出现接口错误或 JS / Promise / 资源错误
long_focus_time
表单控件持续聚焦超过20秒
form_zigzag
表单焦点的最近4次切换呈 a → b → a → b 往复,且已修改字段不少于2个,累计2次后上报
uncompleted_form
页面退出时表单已改动字段占必填项(无必填项时取已触碰字段)的比例达到阈值(默认30%),且期间没有成功提交
form_validation_error
表单提交结果的状态为失败
slow_page
页面 LCP 超过4000ms 或 INP 超过500ms
back_forward
页面浏览事件中的导航类型为后退或前进
各子事件的事件来源不同,并非全部开箱可用:
rage_click、dead_click、long_focus_time 与三个表单类规则:挣扎检测模块内部自行监听 DOM 点击与表单输入事件,无需其他插件配合,开启后即可生效。
error_click:需要点击事件的关联记录,而点击事件由点击行为插件(click,默认关闭)产出,需同时开启 click: true。
slow_page:消费页面性能与 Web Vitals 事件,两者默认开启,通常无需额外配置。
back_forward:消费页面浏览事件中的导航类型字段,该字段由单页应用能力产出,因此需同时开启 spa: true。
自定义挣扎事件:通过 trackStruggle() 主动上报,详见 主动上报。
配置为对象时还可按规则分组关闭:click.enabled / form.enabled / performance.enabled / navigation.enabled 分别对应点击类、表单类、慢页面类与返回类规则。

设备信息

设备信息采集由 device 插件负责,始终挂载、没有开关,SDK 会在每次上报的上下文中附带 session_id / platform / user_agent / screen_resolution / language 字段。
其中 user_agent / language / screen_resolution 由浏览器环境读取;调用 setUser 后,上下文中还会带上 user_id。另有一组随请求地址参数上报的运行时字段:platform / netType / netStatus / vp(视口尺寸)/ sr(屏幕分辨率),其中:
netStatus 依赖宿主注入 getNetworkStatus,浏览器环境下无内置兜底,默认不采集;
netType 则优先调用宿主注入的 getNetworkType,未注入时由 SDK 内置实现自行探测(先取 UA 中的 NetType/,再读 navigator.connection.effectiveType),通常仍会带值,探测不到才回落为 unknown。
说明:
设备标识由 SDK 自动生成并持久化在 localStorage 键 TDEM_ID 中(配置项 aid 可传自定义字符串覆盖),接入方无需额外维护。
验证方式:在控制台打开任一事件的详情,确认事件上下文中的上述字段已填充。

步骤3:主动上报(可选)

除自动采集外,SDK 提供下列主动上报接口。
const tdem = new TDEM({ id: '<project-key>', url: 'https://dem.rumt-zh.com' });

// 自定义事件
tdem.track('order_submit', {
tags: { channel: 'web' },
properties: { amount: 99 },
});

// 自定义测速:可直接传耗时,或 start / end 成对使用
tdem.measure('api_latency', 320, { tags: { api: '/user/info' } });
tdem.startMeasure('render');
// ... 执行操作 ...
tdem.endMeasure('render');

// 日志与异常:用于上报业务已捕获、未导致页面崩溃的异常
tdem.captureMessage('用户完成注册', { level: 'info', tags: { step: 'register' } });
try {
riskyOperation();
} catch (e) {
tdem.captureException(e, { tags: { module: 'payment' } });
}

// 自定义挣扎事件
tdem.trackStruggle('submit_blocked', { severity: 'high', tags: { form: 'checkout' } });
用户标识与全局标签:
tdem.setUser('user-456'); // 设置用户标识,用于用户维度聚合
tdem.clearUser(); // 清除用户标识
tdem.setTags({ role: 'admin', team: 'dev' }); // 设置 / 追加全局标签
tdem.removeTags(['team']); // 移除指定标签
tdem.clearTags(); // 清空所有标签
页面浏览事件:
tdem.reportPageView('/checkout', { pageTitle: '结算页' }); // 主动上报一次页面浏览
tdem.setPage('/checkout'); // 设置当前逻辑页面,后续事件以此为准
tdem.leavePage(); // 离开当前逻辑页面
Web Vitals 主动上报:reportWebVitals 仅在 webVitals 配置为对象且 manualReport: true 时生效,调用后以传入数据覆盖 SDK 采集值后上报:
const tdem = new TDEM({
id: '<project-key>',
url: 'https://dem.rumt-zh.com',
webVitals: { manualReport: true },
});

tdem.reportWebVitals({ LCP: 2500, FCP: 1800 }); // 部分字段自定义,其余沿用 SDK 采集值
验证方式:调用后在控制台对应的自定义事件、日志、挣扎事件或用户页确认数据已入库。完整签名与参数说明请参见 API 说明。

步骤4:检查数据上报

在浏览器开发者工具 Network 面板中,观察 SDK 发往采集服务的事件上报请求(默认 POST 到 {url}/api/v1/collect/events),或在控制台查看对应监控能力的数据。其中 {url} 为初始化时填写的上报域名,国内站为 https://dem.rumt-zh.com。