Open zhaobinglong opened 3 years ago
// 每10条数据数据进行打包, 批量上报方案实现
let logs = []
/**
* @params {array} 日志数组
*/
function upload (logs) {
console.log('send logs', logs)
let xhr = new XMLHttpRequest()
let data = new FormData()
data.append('logs', logs)
xhr.open('POST', this.url)
xhr.send(data)
}
export default function analytics (action = 'pageview', params) {
logs.push(Object.assign({
action,
timeStamp: Date.now()
}, params))
if (logs.length >= 10) {
upload(logs)
logs = []
}
}
延迟上报策略下,如果没有达到数据上报的条件,用户退出页面,在用户不再进入的情况下,本地数据无法上报 解决方案:监听页面生命周期中的beforeunload事件,在页面离开前把剩余不足N条的log全部上传
// sendBeacon允许脚本在页面卸载后异步上web服务器发送少量数据
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
// 监听hash的切换,一旦hash发生变化,就认为是一个新的PV
window.addEventListener('hashchange', () => {
this.analytics()
})
我们可以尝试增加“失败重传”的功能,比起网络不稳定,更多的情况是某个问题导致的稳定错误,重传不能解决这类问题。设想我们在客户端进行数据收集,我们可以很方便地记录到log文件中,于是同样的考虑,我们也可以把数据暂存到localstorage上面,有网环境下再继续上报,因此解决这个问题的方案我们可以归纳为:
一次性上传批量数据时,必然遇到数据量大,浪费流量,或者传输慢等情况,网络不好的状态下,可能导致上报失败。因此,在上报之前进行数据压缩也是一种方案。
对于合并上报这种情况,一次的数据量可能要十几k,对于日 pv 大的站点来说,产生的流量还是很可观的。所以有必要对数据进行压缩上报。lz-string是一个非常优秀的字符串压缩类库,兼容性好,代码量少,压缩比高,压缩时间短,压缩率达到惊人的60%。但它基于LZ78压缩,如果后端不支持解压,可选择gzip压缩,一般而言后端会默认预装gzip,因此,选择gzip压缩数据也可以,工具包pako中自带了gzip压缩,可以尝试使用。
https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
考虑到上报数据过程我们并不关心返回值,只需要知道上报成功与否,我们可以用Head请求来更高效地实现我们的上报过程。
// 简洁的方式
export default function analytics (action = 'pageview') {
(new Image()).src = `https://xxx/test_upload?action=${action}×tamp=${Date.now()}`
}
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/HEAD
参考
正确的pv统计 https://zhuanlan.zhihu.com/p/26341409 PC端统计脚本 https://juejin.im/post/6891080391642316808 https://juejin.im/post/5dba5a39e51d452a2378348a
系统目标
系统阶段分析
信息收集四个维度
a. 用户信息 出现异常时该用户的信息,例如该用户在当前时刻的状态、权限等,以及需要区分用户可多终端登录时,异常对应的是哪一个终端。
b. 行为信息 用户进行什么操作时产生了异常:所在的界面路径;执行了什么操作;操作时使用了哪些数据;当时的API吐了什么数据给客户端;如果是提交操作,提交了什么数据;上一个路径;上一个行为日志记录ID等。
c. 异常信息 产生异常的代码信息:用户操作的DOM元素节点;异常级别;异常类型;异常描述;代码stack信息等。
d. 环境信息 网络环境;设备型号和标识码;操作系统版本;客户端版本;API接口版本等。
两种捕获类型
前端捕获异常分为全局捕获和单点捕获。全局捕获代码集中,易于管理;单点捕获作为补充,对某些特殊情况进行捕获,但分散,不利于管理。
a、全局捕获 通过全局的接口,将捕获代码集中写在一个地方,可以利用的接口有:window.addEventListener(‘error’) / window.addEventListener(“unhandledrejection”) / document.addEventListener(‘click’) 等框架级别的全局监听,例如aixos中使用interceptor进行拦截,vue、react都有自己的错误采集接口
b、单点捕获 在业务代码中对单个代码块进行包裹,或在逻辑流程中打点,实现有针对性的异常捕获:try…catch专门写一个函数来收集异常信息,在异常发生时,调用该函数
埋点分类
市面产品
开源js错误监控解决方案
badjs Webfunny zanePerfor
开源SDK学习
小程序日志上报SDK https://github.com/wangweianger/web-report-sdk/blob/master/src/web-report-axios.js 智云大健康开源前端SDK:https://juejin.cn/post/6862559324632252430