前端代码异常监控总结
【这个在去年8月就起稿了,一直没有发布....】
一、前言
说到前端监控大家应该都不会陌生,这是现代前端工程的标配之一。引入前端监控系统,可以使用例如fundebug,Sentry等第三方监控神器,当然你完全可以自己定制一套符合实际情况的监控模型。一个监控系统大致可以分为四个阶段:日志采集、日志存储、统计与分析、报告和警告。下面主要从几个方面谈谈我对前端代码异常监控的一些理解。
二、JS异处理
脚本错误一般分为两种:语法错误,运行时错误。常见的处理方式有:
2.1 try..catch
捕获
用来捕获捉到运行时的同步错误,示例:
try { a // 未定义变量 ,如果这里是语法错误,是无法捕获的,不过语法错误一般都会被eslint拦下了 } catch(e) { console.log(e);
//上报错误 }
2.2 window.onerror
捕获全局错误:
/** * @param {String} msg 错误信息 * @param {String} url 出错文件 * @param {Number} row 出错行号 * @param {Number} col 出错列号 * @param {Object} error 错误详细信息 */ window.onerror = function (msg, url, row, col, error) { //code
//解析,收集,上报
return true;//错误便不会暴露到控制台中 }; error;
2.3 注意几点:
a、对于 onerror 这种全局捕获,最好写在所有 JS 脚本的前面,因为你无法保证你写的代码是否出错,如果写在后面,一旦发生错误的话是不会被 onerror 捕获到的。
b、onerror 是无法捕获到网络异常的错误,于网络请求异常不会事件冒泡,因此必须在捕获阶段将其捕捉到才行,我们可以:
<script> window.addEventListener('error', (msg, url, row, col, error) => { console.log('我知道 404 错误了'); console.log( msg, url, row, col, error ); return true; }, true); </script> <img src="./404.png" alt="">
c、在实际的使用过程中,onerror 主要是来捕获预料之外的错误,而 try-catch 则是用来在可预见情况下监控特定的错误,两者结合使用更加高效。
三、Promise 错误
Promise 实例抛出异常而你没有用 catch 去捕获的话,onerror 或 try-catch 也无能为力,无法捕捉到错误。
所以如果你的应用用到很多的 Promise 实例的话,特别是你在一些基于 promise 的异步库比如 axios 等一定要小心,因为你不知道什么时候这些异步请求会抛出异常而你并没有处理它,所以你最好添加一个 Promise 全局异常捕获事件 unhandledrejection。
window.addEventListener("unhandledrejection", function(e){ e.preventDefault() console.log('我知道 promise 的错误了'); console.log(e.reason); return true; }); Promise.reject('promise error'); new Promise((resolve, reject) => { reject('promise error'); }); new Promise((resolve) => { resolve(); }).then(() => { throw 'promise error' });
四、异常上报
4.1、上报方式
监控拿到报错信息之后,接下来就需要将捕捉到的错误信息发送到信息收集平台上,常用的发送形式主要有两种:
- 通过 Ajax 发送数据
- 动态创建 img 标签的形式
实例 - 动态创建 img 标签进行上报
function report(error) { var reportUrl = 'http://xxxx/report'; new Image().src = reportUrl + 'error=' + error; }
4.2、抽样上报错误
Reporter.send = function(data) { // 只采集 30% if(Math.random() < 0.3) { send(data) // 上报错误信息 } }
五、统计页面所有AJAX性能数据
如何统计页面所有AJAX性能数据,如何知道所有AJAX已加载完毕?鉴于绝大部分网页的ajax都是用的XMLHttpRequest对象,我们可以在页面加载之处重新定义XMLHttpRequest对象,对open,onload,onreadystatechange方法进行拦截。请求接口时长可以监听ajaxReadyStateChange事件:
/** * 拦截接口请求,上报接口信息 */ //统一拦截ajax请求 var start_time = 0, gap_time = 0; //计算请求延时 window.addEventListener('ajaxReadyStateChange', function (e) { var xhr = e.detail, status = xhr.status, readyState = xhr.readyState, responseText = xhr.responseText; /** * 计算请求延时 */ if(readyState == 1){ start_time = (new Date()).getTime(); } if(readyState == 4){ gap_time = (new Date()).getTime() - start_time; } /** * 上报请求信息 */ if(readyState == 4){ httpReport(gap_time, status, xhr.responseURL) } })
六、如何解决数据频繁写入数据量太大的问题,数据库应该怎么设计或处理
1、写定时任务,每晚几点钟对数据表进行备份,统计,或删除
....
参考:
https://github.com/happylindz/blog/issues/5
原文地址:https://www.cnblogs.com/leaf930814/p/9251776.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- opencv 阈值分割的具体使用
- 浅谈keras 的抽象后端(from keras import backend as K)
- 在Keras中利用np.random.shuffle()打乱数据集实例
- 浅谈matplotlib中FigureCanvasXAgg的用法
- Keras自定义实现带masking的meanpooling层方式
- 利用keras使用神经网络预测销量操作
- 获取python运行输出的数据并解析存为dataFrame实例
- 如何使用Cython对python代码进行加密
- PHP快速排序算法实现的原理及代码详解
- 从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
- keras实现VGG16 CIFAR10数据集方式
- PyTorch: Softmax多分类实战操作
- 为什么称python为胶水语言
- opencv 图像礼帽和图像黑帽的实现
- python文件及目录操作代码汇总