前端异常监控

  • 一.异常监控系统
  • 二.异常情况
  • 三.异常表现分类
  • 四.Web前端监控分类
  • 五. 监控分类解析
  • 六 错误分类和捕获
  • 七 小程序异常监控
  • 八 前端异常上报方式

一.异常监控系统

前端和后端处于同一个监控系统中,前端有自己的监控方案,后端也有自己的监控方案,但两者并不分离,因为一个用户在操作应用的过程中如果出现异常,有可能是前端引起,也有可能是后端引起,需要有一个机制,将前后端串联起来,使监控本身统一于监控系统。因此,即使只讨论前端异常监控,其实也不能严格区分前后端界限,而要根据实际系统的设计,在最终的报表中体现出监控对开发和业务的帮助。
  一般而言,一个监控系统,大致可以分为四个阶段:日志采集。日志存储、统计与分析、报告和警告。

二.异常情况

前端异常是指用户使用 Web
应用时无法快速得到符合预期结果的情况,不同的异常带来的后果程度不同,轻则引起用户使用不悦,重则导致产品无法使用,使用户丧失对产品的认可。
后端异常是指使服务无法正常运行的错误或外部问题,目前系统常见异常有数据库入库错误、数据库链接异常、数据格式错误等。后端程序运行的各类报错会将错误信息返回给前端。

三.异常表现分类

根据异常代码的后果程度,对前端异常的表现分为如下几类

  • a. 出错 界面呈现的内容与用户预期的内容不符,例如点击进入非目标界面,数据不准确,出现的错误提示不可理解,界面错位,提交后跳转到错误界面等。
  • b. 呆滞 界面出现操作后没有反应的现象,例如点击按钮无法提交,提示成功后无法继续操作。
  • c. 损坏 界面出现无法实现操作目的的现象,例如点击无法进入目标界面,点击无法查看详情内容等。
  • d. 假死 界面出现卡顿,无法对任何功能进行使用的现象。例如用户无法登录导致无法使用应用内功能,由于某个遮罩层阻挡且不可关闭导致无法进行任何后续操作。
  • e. 崩溃 应用出现经常性自动退出或无法操作的现象。例如间歇性crash,网页无法正常加载或加载后无法进行任何操作。

四.Web前端监控分类

(1)性能监控
性能监控主要是监听前端项目在用户端展示的性能,这将直接关乎到用户的体验效果。监控这些数据,将能够是我们更好的去优化用户体验。常见的性能监控指标包括以下数据:

  1. 不同用户和不同设备下的首屏加载时间,包括白屏时间;
  2. HTTP 接口的响应时间;
  3. 静态资源、包括图片的下载时间。

google 开发者提出了一种 RAIL 模型来衡量应用性能,即:Response、Animation、Idle、Load,分别代表着
web 应用生命周期的四个不同方面。并指出最好的性能指标是:100ms 内响应用户输入;动画或者滚动需在 10ms内产生下一帧;最大化空闲时间;页面加载时长不超过 5 秒。 我们转化为三个方面来看:响应速度、页面稳定性、外部服务调用
响应速度:
页面初始访问速度 + 交互响应速度
页面稳定性:页面出错率
外部服务调用:网络请求访问速度
1.页面访问速度:白屏、首屏时间、可交互时间
1)first paint (FP) and first contentful paint (FCP) 首次渲染、首次有内容的渲染 这两个指标浏览器已经标准化了,从 performance 的 The Paint Timing
API 可以获取到,一般来说两个时间相同,但也有情况下两者不同。
(2)First meaningful paint and hero
element timing 首次有意义的渲染、页面关键元素 我们假设当一个网页的 DOM
结构发生剧烈的变化的时候,就是这个网页主要内容出现的时候,那么在这样的一个时间点上,就是首次有意义的渲染。这个指标浏览器还没有规范,毕竟很难统一一个标准来定义网站的主体内容。
(3)Time to interactive 可交互时间
(4)长任务
浏览器是单线程的,如果长任务过多,那必然会影响着用户响应时长。好的应用需要最大化空闲时间,以保证能最快响应用户的输入。

2.页面稳定性:页面出错情况 资源加载错误 JS 执行报错
3.外部服务调用 CGI 耗时 CGI 成功率 CDN 资源耗时

五. 监控分类解析

在讲如何监控之前,先来看看浏览器提供的 performance api,这也是性能监控数据的主要来源。 performance
提供高精度的时间戳,精度可达纳秒级别,且不会随操作系统时间设置的影响。 目前市场上的支持情况:主流浏览器都支持,大可放心使用。 基于
performance 我们可以测量如下几个方面:

mark、measure、navigation、resource、paint、frame。
let p = window.performance.getEntries();
1.重定向次数:performance.navigation.redirectCount
2.JS 资源数量: p.filter(ele => ele.initiatorType === "script").length
3.CSS 资源数量:p.filter(ele => ele.initiatorType === "css").length
4.AJAX 请求数量:p.filter(ele => ele.initiatorType === "xmlhttprequest").length
5.IMG 资源数量:p.filter(ele => ele.initiatorType === "img").length
6.总资源数量: window.performance.getEntriesByType("resource").length
7.不重复的耗时时段区分:
重定向耗时: redirectEnd - redirectStart
DNS 解析耗时: domainLookupEnd - domainLookupStart
TCP 连接耗时: connectEnd - connectStart
SSL 安全连接耗时: connectEnd - secureConnectionStart
网络请求耗时 (TTFB): responseStart - requestStart
HTML 下载耗时:responseEnd - responseStart
DOM 解析耗时: domInteractive - responseEnd
资源加载耗时: loadEventStart - domContentLoadedEventEnd
8.其他组合分析:
白屏时间: domLoading - fetchStart
粗略首屏时间: loadEventEnd - fetchStart 或者 domInteractive - fetchStart
DOM Ready 时间: domContentLoadEventEnd - fetchStart
页面完全加载时间: loadEventStart - fetchStart
9.JS 总加载耗时:
1.const p = window.performance.getEntries();
2.let cssR = p.filter(ele => ele.initiatorType === "script");
3.Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));
10.CSS 总加载耗时:
1.const p = window.performance.getEntries();
2.let cssR = p.filter(ele => ele.initiatorType === "css");
3.Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));

六 错误分类和捕获

错误监控主要是指代码在个别特殊场景下,会出现异常报错,很有可能会引发线上的故障。而这部分异常,如果没有异常监控,则只能在用户发现的情况下进行选择性的上报,并不能让我们及时去发现和解决问题。这一部分的错误信息主要分为下面几类:- JS 语法错误、代码异常;- 静态资源加载错误;- AJAX 请求错误;- Promise 异步函数错误;- Vue错误;- 跨域 Script error;- 崩溃和卡顿。

1、JS 语法错误、代码异常

大部分的语法和代码问题,在开发和测试的时候已经排查掉了,但是不排除有一些特殊场景下出现的漏网之鱼,所以这个问题也不能忽视。

使用try-catch try catch
finally只能捕获运行时的错误,无法捕获语法错误,可以拿到出错的信息,堆栈,出错的文件、行号、列号。try catch
finally语句标记要尝试的语句块,并指定一个出现异常时抛出的响应。

try {let name = 'aaa';console.log(nam);
} catch(e) {console.log('捕获到异常:', e);
}控制台:
捕获到异常: ReferenceError: nam is not definedat <anonymous>:3:15
window.onerror
window.onerror可以捕捉语法错误,也可以捕捉运行时错误,可以拿到出错的信息,堆栈,出错的文件、行号、列号,只要在当前window执行的Js脚本出错都会捕捉到,通过window.onerror可以实现前端的错误监控。出于安全方面的考虑,当加载自不同域的脚本中发生语法错误时,语法错误的细节将不会报告。/*message:错误信息(字符串)。source:发生错误的脚本URL(字符串)lineno:发生错误的行号(数字)colno:发生错误的列号(数字)error:Error对象(对象)若该函数返回true,则阻止执行默认事件处理函数。
*/
window.onerror = function(message, source, lineno, colno, error) { // onerror_statements
}
不论是静态资源异常,或者接口异常,语法错误都无法捕获到。

2、静态资源加载错误

window.addEventListener

当一项资源(如图片或脚本)加载失败,加载资源的元素会触发一个 Event 接口的 error 事件,并执行该元素上的onerror()
处理函数。这些 error 事件不会向上冒泡到 window ,不过(至少在 Firefox
中)能被单一的window.addEventListener 捕获。

/*ErrorEvent类型的event包含有关事件和错误的所有信息。
*/
window.addEventListener('error', function(event) { // onerror_statements})
需要注意:不同浏览器下返回的 error 对象可能不同,需要注意兼容处理。
需要注意避免 addEventListener 重复监听。
在vue中使用errorHandler
app.config.errorHandler = (err, vm, info) => {// 处理错误// `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
}
或者生命周期钩子 errorCaptured

3、AJAX请求异常

在响应拦截器中处理。 请求错误可以分为有响应的异常和无响应的异常

有响应:业务处理逻辑出错、数据库出错等;这种错误会收到服务端的错误码和对应的错误信息

无响应:40x,50x,网络错误,请求超时等

instance.interceptors.response.use((res) => {},  (error) => {// 处理错误逻辑
})

4、promise异常使用Promise Catch

没有写 catch 的 Promise 中抛出的错误无法被 onerror 或 try-catch 捕获到,所以我们务必要在 Promise
中不要忘记写 catch 处理抛出的异常

解决方案: 为了防止有漏掉的 Promise 异常,建议在全局增加一个对 unhandledrejection
的监听,用来全局监听Uncaught Promise Error。使用方式:

window.addEventListener("unhandledrejection", function(e){console.log(e);
});

5、Vue 错误

由于 Vue 会捕获到所有 Vue 单文件组件或者 Vue.extend 继承的代码,所以在 Vue 里面出现的错误并不会直接抛给
window.onerror ,而是会被 Vue 自身的 Vue.config.errorHandler 捕获。
如果开发者没有配置Vue.config.errorHandler,那么捕获到的错误会以console.error的方式输出。

Vue.config.errorHandler = error => {monitor.errors.push({time: new Date().getTime(), content: error.stack})
}

6、跨域Script error 脚本错误

因为我们在线上的版本,经常做静态资源 CDN
化,这就会导致我们常访问的页面跟脚本文件来自不同的域名,这时候如果没有进行额外的配置,就会容易产生 Script error

Script error
是浏览器在同源策略限制下产生的,浏览器处于对安全性上的考虑,当页面引用非同域名外部脚本文件时中抛出异常的话,此时本页面是没有权利知道这个报错信息的,取而代之的是输出
Script error 这样的信息

7、崩溃和卡顿

卡顿也就是网页暂时响应比较慢, JS 可能无法及时执行。但崩溃就不一样了,网页都崩溃了,JS
都不运行了,还有什么办法可以监控网页的崩溃,并将网页崩溃上报呢?

1.利用 window 对象的 load 和 beforeunload 事件实现网页崩溃的监控。

2.也可以使用 Service Worker 来实现网页崩溃的监控

8、其他错误

网络请求失败 重写 window.XMLHttpRequest 和 window.fetch 捕获请求错误 iframe 错误
父窗口直接使用 window.onerror 是无法直接捕获,通过直接给 iframe 添加 onerror 事件即可。
window.frames[0].onerror

七 小程序异常监控

web端与小程序错误监控差异

在 Web 端监测的是页面完整的 url,而小程序端监测的是路由地址;
小程序页面属于app内部的页面,使用时已全部加载完毕,因此监控页面性能时不统计页面加载时长等信息,更多的是对页面内请求、资源请求和用户行为的监控;
由于微信官方和小程序代码的要求,集成方式对比 Web 端会相对严格一些。

小程序需要监控的数据

1.JavaScript异常监控:不论是 Web 端还是小程序端,对 JavaScript 异常的监控都是必要的;
2.页面内请求监控:对于小程序来说,需要统计发送网络请求的 swan.request() 异常时的请求状态、请求时长、请求地址等;
3.资源加载监控:当需要下载资源到本地的
4.swan.downloadFile() 出现异常时,统计加载时间、异常类型、资源地址等;
5.页面性能监控:访问监控、页面来源及流向监控等,方便更好的对小程序进行运营;
6.用户数据统计:用户的分布、操作系统及版本、app版本、IP 地址等,给错误的分析提供更多条件。

收集方式

  1. 简单收集

小程序App()生命周期里提供了onError函数,可以通过在onError里收集异常信息。

  1. 用户操作路径收集

一些较隐蔽的错误如果只有错误栈信息,排查起来会比较难,如果有用户操作的路径,在排查时就方便多了。

小程序性能监控

  • 白屏监控

用户在访问网页的时候,在浏览器开始显示之前都会有一个的白屏过程,在移动端,受限于设备性能和网络速度,白屏会更加明显。

  • 白屏时间

页面完全空白的时间,web可以在页面的head底部添加的JS代码用来做白屏时间的标记。

微信web资源离线存储

通过使用微信离线存储,Web开发者可借助微信提供的资源存储能力,直接从微信本地加载 Web
资源而不需要再从服务端拉取,从而减少网页加载时间,为微信用户提供更优质的网页浏览体验。每个公众号下所有 Web App 累计最多可缓存 5M
的资源。这个设计有点类似 HTML5 的 Application Cache。

八 前端异常上报方式

  • 影响因素

异常上报,可能产生影响的因素有:

上报的频率。当出现死循环,不断触发异常上报时,这个就跟 DDOS 攻击差不多了。
上报的数据量。不同的请求方式,能携带的数据量有限制。如果想要录制用户的操作,那么产生的数据量,不同情况下会不一样。
跨域。日志服务器有些是单独的。 不同 web 服务器对于请求的 body 大小限制不同。 上报请求的响应方式。响应同样会消耗资源。

  • 上报方式

通常来说,上报方式可以分两种:一种是通过 Img 方式上报,另一种是 AJAX 接口上报。

  1. Img上报

这种方式非常的简单快捷,也是最推荐的一种方式。该方式通过动态的创建一个 Img
标签的方式,向服务器请求资源,然后把上报信息通过查询参数的方式带到请求的后面。至于请求的图片资源,为了节省流量和响应速度,我们可以请求一个
1×1 的透明 GIF 图片。这样一来不会产生跨域的问题,而且不需要等待服务器返回的数据,只要进行上报即可,非常的简单。
但是,也有相应的弊端。由于 URL 的长度有限,所以携带的查询参数并不是无限的,因此需要筛选有用的信息进行上报,而不是无限的长度。

  1. AJAX 接口上报

由于这种方式本身也是一个请求,存在发生异常的情况。而且,通常来说上报接口的域名和业务列域名是不同的,因此还会存在跨域的问题需要处理。必须要等到接口响应后状态为
200 才能确定这次信息上报是成功的。
当然,AJAX 接口上报也有其自身的优点,那就可以携带的参数更大,而且还可以默认携带 Token 等信息。

总结
在上报参数长度可控的情况下还是更推荐通过 Img 方式进行监控信息上报。如果上报的数据量较大,不可控的情况下,使用 AJAX 接口上报更加保险。

前端异常监控调研总结相关推荐

  1. 从无到有<前端异常监控系统>落地

    从无到有<前端异常监控系统>落地 参考文章: (1)从无到有<前端异常监控系统>落地 (2)https://www.cnblogs.com/1wen/p/7942608.htm ...

  2. 构建可靠的前端异常监控服务-采集篇

    http://jdc.jd.com/archives/2175 在 Web 应用异常复杂的今天,一个页面不单单只包含文字.图片和超链接,还可能包含复杂表单.大量动画.海量交互.很多 Web 应用完全单 ...

  3. 直播回顾丨神策数据王朋:如何搭建一套高可用的前端异常监控系统?

    本文根据神策数据资深前端研发工程师王朋在神策「大数据技术系列直播课」第二季"前端专题"第四讲的直播整理. 本次分享主要分为三大部分:前端异常监控概述,异常监控的背景意义,以及做一个 ...

  4. [转] 前端异常监控解决方案研究

    前端监控包括行为监控.异常监控.性能监控等,本文主要讨论异常监控.对于前端而言,和后端处于同一个监控系统中,前端有自己的监控方案,后端也有自己等监控方案,但两者并不分离,因为一个用户在操作应用过程中如 ...

  5. 学习 sentry 源码整体架构,打造属于自己的前端异常监控SDK

    前言 这是学习源码整体架构第四篇.整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现.文章学习的是打包整合后的代码,不是实际仓库中的拆分 ...

  6. 前端异常监控平台对比

    前言 前端监控包括很多种,用户行为监控,异常监控,性能监控等.一个完善的前端项目是肯定需要这些监控平台的,以便于在关键时刻给出我们未来方向的决策.本文重点讨论前端异常监控中的各大平台的差异对比. 概述 ...

  7. 调用后台接口返回报错前端隐藏提示_前端异常监控解决方案研究(转)

    前端监控包括行为监控.异常监控.性能监控等,本文主要讨论异常监控.对于前端而言,和后端处于同一个监控系统中,前端有自己的监控方案,后端也有自己等监控方案,但两者并不分离,因为一个用户在操作应用过程中如 ...

  8. 腾讯CDC团队:前端异常监控解决方案

    前端监控包括行为监控.异常监控.性能监控等,本文主要讨论异常监控.对于前端而言,和后端处于同一个监控系统中,前端有自己的监控方案,后端也有自己等监控方案,但两者并不分离,因为一个用户在操作应用过程中如 ...

  9. uni-app + sentry 前端异常监控

    最近在研究sentry,发现他提供了vue的初始化步骤,根据他提供的步骤完全可以实现vue的异常监控,所以就不对vue多做解释,本文主要针对uni-app+sentry的前端异常监控. sentry可 ...

最新文章

  1. 第二十课.DeepGraphLibrary(一)
  2. Linux socket / 端口复用
  3. 鸿蒙os界面鲁大师,鲁大师鸿蒙版下载-鲁大师 鸿蒙版v10.4.5-PC6鸿蒙网
  4. 不止1亿像素相机 小米MIX 4有望首发第四代超声波屏下指纹
  5. 关于C#中timer类
  6. 一文带你看懂自然语言处理——word表示技术的变迁(从bool模型到BERT)
  7. 一个简洁、美观的登录页面
  8. 论文笔记:主干网络——SENet
  9. 视频帧凸包检测 结果存入数据库
  10. 搜索功能支持大小写模糊查询
  11. python打印A-Z
  12. configmap资源简介和应用
  13. 小程序源码:全新独立后台修复登录在线答题
  14. 【水滴云|热点】个人信息安全有法可依,海量数据用IPFS存储
  15. //编写一个学生类(Students),包括姓名(name)、性别(sex)、学号(num)、语文课(Chinese)、英语课(English)、 //数学课(Math)和平均值(avg)
  16. 散阅史记_老子韩非列传第三
  17. CentOS下连VisualSVN服务器时报Key usage violation错误的解决方案
  18. 排队打水(排序不等式)
  19. post,put,get请求接口
  20. 苹果计算机怎么开科学,苹果手机怎样设置科学计算器?

热门文章

  1. RHCA回忆录---DO447介绍
  2. Server2016部署域控
  3. 接线 科思模块怎么和plc_博途S1200数字量模块接线图,NPN和PNP不要接错了,快收藏吧...
  4. python软件下载免费还是收费-老男孩教育Python学院|Python收费是多少?
  5. 网页素材大宝库:40套高质量的网站纹理背景素材
  6. 驾考经历分享——长沙
  7. 什么是Web API?Web API:网络应用程序接口
  8. 分享对于自学3DMAX来说,自学难吗?
  9. 可编程DDC控制器的实现 (1)
  10. 解决某些ERP软件无法用VNN的IP地址进行连接的问题