前端日志监控的背景
- 处理生产环境出现的问题,快速定位
- 页面异常,快速定位,找出错误信息
- 页面卡顿,优化性能
性能监控(监测页面的性能情况,将性能数据指标量化并收集)
浏览器的performance、network、lighthouse面板
W3C标准化
- 开发者可以通过
window.performance属性获取 web-vitals插件:衡量性能和用户体验的工具(juejin.cn/post/709715…
以用户为中心的性能指标
通过使用window.performnce.getEntriesByType('navigation')或performanceObserver获取
- 白屏(FP):页面首次绘制的时间点
- 灰屏(FCP):首次绘制任何文本、图像
- 首屏(FMP):首次完成有意义内容绘制的时间点
- 最大内容绘制(LCP):完成最大内容绘制的时间点
- 首次输入延迟(FID):首次输入延迟,测量用户第一次与页面交互直到浏览器响应的时间
- 累计布局偏移(CLS):累计布局偏移
- TBT:总的阻塞时间
- TTI:可交互时间:用于测量页面从开始加载到主要资源完成渲染的时间
// 第一种:获取FP时间
performance.getEntries().filter(item=>item.name === 'first-paint')[0]
// 第二种 方式
var observer = new PerformanceObserver(function(list,obj){
var entries = list.getEntries()
entries.forEach(item=>{
if(item.name === 'first-paint')....}
})
})
observer.observer({type:'paint'})
// 第三种方式
performance.getEntriesByName('first-paint')
行为监控
路由跳转行为
- Hash路由:hash变化会触发hashchange,也会触发popstate,popstate,先触发,只需要监听popstate即可
- History路由:需要对
replaceState和pushState,去创建新的全局Event事件。然后window.addEventListener监听我们加的Event即可
点击行为
http请求行为
- XMLHttpRequest 的劫持:调用 proxyXmlHttp 即可完成全局监听 XMLHttpRequest
- Fetch的劫持:调用 proxyFetch 即可完成全局监听 fetch
用户自定义事件
错误监控
- RangeError:范围错误
- ReferenceError:引用错误
- SyntaxError:语法错误
- TypeError:类型错误
- URIError:全局URI处理函数传递不合法的URI时的错误
- EvalError:关于eval的异常
1.JS运行异常(JS运行时产生的错误)
捕获JS运行异常的方法
- 使用
window.onerror捕获全局的JS运行异常,window.onerror是一个全局变量,默认值为null,当Js运行错误时触发,window会触发error事件,执行window.onerror()。 - 使用
window.addEventListener('error')捕获JS运行异常,比window.onerror先触发。
两者的区别
- window.addEventListener('error')还可以捕获到静态资源加载异常错误
- onerror可以接受多个参数,而window.addEventListener('error')只有一个保存多有错误信息的参数
- window.onerror是在冒泡阶段捕获错误,window.addEventListener('error')在捕获阶段捕获
2.静态资源异常(img图片、CDN资源失效,打不开)
解决静态资源异常的方法
使用window.addEventListener('error',callback,true)方式捕获。而window.onerror是在冒泡阶段捕获错误,资源类型错误没有冒泡
3.Promise异常
使用 Promise 的过程中,当 Promise 被 reject 且没有被 catch 处理的时候,就会抛出 Promise异常;
解决Promise异常的方法
当抛出Promise异常时,会触发unhandledrejection 事件,只需监听它就可以捕获Promise异常
4.HTTP异常
异步请求的底层原理都是调用的 XMLHttpRequest或者 Fetch,我们只需要对这两个方法都进行 劫持 ,就可以往接口请求的过程中加入我们所需要的一些参数捕获;
- fetch异常:通过fetch(url).then(callback).catch(callback)方式捕获异常
- xhr.open方法执行时出现异常,使用window.addEventListener('error')或window.onerror捕获
- xhr.send方法执行时出现异常,使用 xhr.onerror或xhr.addEventListener('error',callback)捕获
5.跨域异常,引入第三方脚本执行时错误
window.addEventListener('error') 再加上对跨域资源的判断
Vue/React异常
Vue2、Vue3 错误捕获
-
Vue2如果在组件渲染时出现运行错误,错误将会被传递至全局 [Vue.config.errorHandler] 配置函数; -
Vue3同Vue2,如果在组件渲染时出现运行错误,错误将会被传递至全局的 [app.config.errorHandler] 配置函数;
sentry
Sentry 就是一个用于记录前端代码错误的平台工具,借助该平台,可以将项目在生产环境上发生的错误记录下来,并且根据 Sourcemap 定位到具体出错代码行,方便 debug。
为什么选择Sentry
- 开源:源码开放,性能卓越,易于扩展
- 支持SASS版和私有化部署
- 支持主流的编程语言
- 支持第三方集成,如github、gitlab、jira等
Sentry性能监控原理
通过 window.performance.getEntries 和 performanceObserver 这两个 api,获取用户在使用应用过程中涉及的 load 相关、fcp、lcp、fid、cls 等指标数据,然后通过接口上报。监控平台拿到数据以后,通过可视化图标的方式展示性能指标数据,帮助我们分析。
搭建sentry
第一步:安装docker
第二步:部署sentry
1:【项目】面板创建项目
2:选择项目的平台类型,填写项目名称,项目所属团队,就可以创建项目
3.1:选择平台,生成对应的配置方案
3.2:在自己的项目中粘贴配置代码:找到入口文件,main.js,将上一步生成的配置代码粘贴在入口文件中
第三步:查看错误报错信息
前端监控项目中的难点、亮点?
在前端监控中,可能不仅仅只是监控一个web环境下的数据,也会包括Nodejs、微信小程序、Electron等其他平台的监控。 设计一个SDK支持多平台,通过插件化对代码进行组织。
- Core管理SDK内与平台无关的代码,比如一些公共方法(格式化、生成mid方法);
- 每个平台单独一个SDK,继承core的类;SDK自己管理SDK特有的核心方法逻辑,比如上报、参数初始化
- Plugins插件,每个SDK都是有内核+插件组成的,将所有的插件功能,比如性能监控、错误监控都抽离成插件