前端代码错误日志监控——Sentry

随着项目工程化的发展,对于提升产品性能的要求也越来越多。产品即便通过研发自测,测试各种测,到了用户使用过程中,依然还是会出现一些bug;这对这些bug,不是所有用户会进行反馈(难以发现这些问题)甚至抛弃对于产品的使用;而且这些问题的复现性也相对困难。因此,对于bug的及时发现和解决,成为产品优化的一个考虑重心。

一般情况下,捕获错误的方法——

1、window.onerror针对整个js文件进行全局错误监控

2、try…catch针对性的进行错误监控

3、throw new Error()

捕获的错误的展示——

1、通过这两者进行错误捕获时,浏览器的console就不会输出错误信息,除非我们将错误信息 通过console.error打印显示。

2、浏览器作为js的宿主,错误信息也只限于浏览器进行捕获和显示,刷新后错误提示可能不会复现

如果需要通过平台实时监测并查询错误日志——解决思路:

1、如果需要一个平台可以查看所有日志信息,就需要将捕获的错误log进行保存,比如localStorage。

2、保存后还需要发送到服务端,便于在另一个平台进行统一查看。

3、期间产生跨域的问题

通过信息查询和后台小伙伴的推荐,了解的两种可以进行前端错误日志监控的平台——

1、https://fundebug.com/          中文版,易操作,仅限于JavaScript

2、https://sentry.io/     英文版,兼容前后端多种语言类型

目前,用了一个通过vue-cli搭建的后台管理系统,对进行了 sentry的错误收集代码测试,实现过程——————————  

1、在该平台注册用户并新建项目后,安装

import Vue from 'vue'
//测试错误获取
import Raven from 'raven-js';
import RavenVue from 'raven-js/plugins/vue';
Vue.prototype.$Raven = Raven; //设置全局变量
Raven
  .config('https://')
  .addPlugin(RavenVue, Vue)
  .install();

2、全局监控代码

window.onerror = function(msg, url, line, col, error) {
  //console.log(msg + '--' + url + '--' + line + '--' + col + '--' + error);
  //没有URL不上报!上报也不知道错误
  if (msg != "Script error." && !url) {
    return true;
  }
  //采用异步的方式
  //我遇到过在window.onunload进行ajax的堵塞上报
  //由于客户端强制关闭webview导致这次堵塞上报有Network Error
  //我猜测这里window.onerror的执行流在关闭前是必然执行的
  //而离开文章之后的上报对于业务来说是可丢失的
  //所以我把这里的执行流放到异步事件去执行
  //脚本的异常数降低了10倍
  setTimeout(function() {
    var data = {};
    //不一定所有浏览器都支持col参数
    col = col || (window.event && window.event.errorCharacter) || 0;

    data.url = url;
    data.line = line;
    data.col = col;
    if (!!error && !!error.stack) {
      //如果浏览器有堆栈信息
      //直接使用
      data.msg = error.stack.toString();
    } else if (!!arguments.callee) {
      //尝试通过callee拿堆栈信息
      var ext = [];
      var f = arguments.callee.caller,
        c = 3;
      //这里只拿三层堆栈信息
      while (f && (--c > 0)) {
        ext.push(f.toString());
        if (f === f.caller) {
          break; //如果有环
        }
        f = f.caller;
      }
      ext = ext.join(",");
      data.msg = ext;
    }
    console.log(data);
    Raven.captureException(data, {
      level: 'info', // one of 'info', 'warning', or 'error'
      logger: 'window',
      tags: { git_commit: 'window' }
    });
    //把data上报到后台!
  }, 0);
  return true;
}

3、单独的方法监控

let funcLog = (func, val) => {
  try {
    if (val) {
      func(val);
    } else {
      func();
    }
  } catch (e) {
    Raven.captureBreadcrumb({
      message: '获取方法或者参数错误',
      category: 'function',
    });
    Raven.captureException(e, {
      level: 'error', // one of 'info', 'warning', or 'error'
      logger: 'function',
      tags: { git_commit: 'function' }
    });
  }
}

4、ajax数据交互的监控,该项目采用的是vue-resource,仅用post方法为例

let ajaxLog_post = (that, url, data, success_func, error_func, all_func) => {
  let _this = that;
  //console.log('get');
  _this.$http.post(url, data, {
      before: function() {
       
      }
    })
    .then(function(response) {
      //console.log('get2');
      _this.loading = false;
      if (all_func) {
        all_func(data);
        return false;
      }
      let data_return = response.body;
      //console.log(data_return);
      if (data_return.respcd == '0000') {
        try {
          if (success_func) {
            success_func(data_return);
          }
        } catch (e) {
          console.error(e);
          _this.$Raven.captureException(e, {
            level: 'error', // one of 'info', 'warning', or 'error'
            logger: 'ajaxPost_function',
            tags: { git_commit: 'ajaxPost_function' }
          });
        }
      } else {
        if (data_return.respmsg) {
          _this.toastmsg = data_return.respmsg;
        } else {
          _this.toastmsg = data_return.resperr;
        }
        _this.visible_toast = true;
        if (error_func) {
          error_func(data_return);
        }
      }
    }, function(response) {
      
    })
    .catch(function(response) {
      
    });
}

5、备注

1、参考

http://www.cnblogs.com/xianyulaodi/p/6201829.html

2、在ajax数据交互过程中,执行的事件发生错误,window.onerror捕获不到,故需要单独处理;

3、对于其他window.onerror捕获不到的代码,可以通过异步处理,以便捕获

let test_log = null;
test_log.indexOf('q');
setTimeout(function() {
 test_log.indexOf('q');
}, 1000);

猜你喜欢

转载自my.oschina.net/dawd/blog/1796956