前端代码异常监控总结

时间:2019-10-15
本文章向大家介绍前端代码异常监控总结,主要包括前端代码异常监控总结使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【这个在去年8月就起稿了,一直没有发布....】

一、前言

  说到前端监控大家应该都不会陌生,这是现代前端工程的标配之一。引入前端监控系统,可以使用例如fundebugSentry等第三方监控神器,当然你完全可以自己定制一套符合实际情况的监控模型。一个监控系统大致可以分为四个阶段:日志采集、日志存储、统计与分析、报告和警告。下面主要从几个方面谈谈我对前端代码异常监控的一些理解。

二、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、上报方式

监控拿到报错信息之后,接下来就需要将捕捉到的错误信息发送到信息收集平台上,常用的发送形式主要有两种:

  1. 通过 Ajax 发送数据
  2. 动态创建 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