前端错误监控

编写代码只是做好项目的一小部分,写代码难免会碰到错误。因此,在项目上线后,我们还应该主动对项目的错误进行收集,不能等用户发现错误再联系我们处理。提前做好错误收集和处理,可以有效监控页面状态,减少损失。 更重要的是,线上如果出现错误,没有用户告知,前端基本无法发现,毕竟不可能要求用户一遍一遍为我们'重现',而且即使用户反馈,分析现象排查原因也费事费力。

# 基本思路

  1. 全局拦截错误
  2. 封装错误信息
  3. 回传错误信息
  4. 解析错误信息对应位置
  5. 上报统计分析

# 一、全局拦截错误

# 方案一 : window.onerror 事件

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        var message = [
            'Message: ' + msg,
            'URL: ' + url,
            'Line: ' + lineNo,
            'Column: ' + columnNo,
            'Error object: ' + JSON.stringify(error)
        ].join(' - ');

        alert(message);
    }

    return false;
};	

解释说明:

message:错误信息(字符串)
source:发生错误的脚本URL(字符串)
lineno:发生错误的行号(数字)
colno:发生错误的列号(数字)
error:Error对象(对象)

# 方案二: Vue.config.errorHandler()函数处理


Vue.config.errorHandler = function (err, vm, info) {
		let { message, name, script, line, column, stack } = err
        let stackStr = stack ? stack.toString() : `${name}:${message}`
  // handle error
  // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
  // 只在 2.2.0+ 可用
}

注:可根据vm实例解析出错误的component name 回传

# 二、封装错误信息

简单封装基本信息

sourceUrl:错误页地址
message:错误信息
lineNo: 行号 
columNo:列号 
stackStr:堆栈信息
componentName:错误组件名称

# 三、回传错误信息

ajax请求回传,做好接口支持即可

# 四、解析错误信息

此步骤较为繁琐,前端代码经过混淆压缩,实际上已经‘不可读’,就算知道行号与列号实际上也难以定位错误.异常常常是1行3000列的类似情况.

sourceMap文件结构如下

  {
    version : 3,
    file: "out.js", 
    sourceRoot : "", 
    sources: ["foo.js", "bar.js"],
    names: ["src", "maps", "are", "fun"],
    mappings: "AAgBC,SAAQ,CAAEA"
  }

解决方案:通过sourceMap的mappings来获取实际位置 所以问题变成如何根据行号与列号通过解析sourceMap来定位问题代码

  - version:Source map的版本,目前为3。

  - file:转换后的文件名。

  - sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。

  - sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。

  - names:转换前的所有变量名和属性名。

  - mappings:记录位置信息的字符串

关键在mappings它描述了两个文件的各个位置是如何一一对应的,具体对应规则可查看文末文档; 好在目前已经有开源项目(mozilla的source-map (opens new window))做这件事了

var rawSourceMap = {
  version: 3,
  file: 'min.js',
  names: ['bar', 'baz', 'n'],
  sources: ['one.js', 'two.js'],
  sourceRoot: 'http://example.com/www/js/',
  mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};

var smc = new SourceMapConsumer(rawSourceMap);

console.log(smc.sources);
// [ 'http://example.com/www/js/one.js',
//   'http://example.com/www/js/two.js' ]

console.log(smc.originalPositionFor({
  line: 2,
  column: 28
}));
// { source: 'http://example.com/www/js/two.js',
//   line: 2,
//   column: 10,
//   name: 'n' }

console.log(smc.generatedPositionFor({
  source: 'http://example.com/www/js/two.js',
  line: 2,
  column: 10
}));

# 五、上报数据分析通知

  1. 可记录为日志文件查看
  2. 发送邮件

有精力可做更多数据可视化分析,用户行为分析,首屏加载时间统计分析等等

# 六、目前可行的第三方方案:

考虑到目前精力人手有限,可直接使用第三方服务,先进行错误的记录分析与上报

1.https://sentry.io/ (opens new window)

2.https://www.bugsnag.com/ (opens new window)

优点:全面/强大/支持多种语言/分析全面/支持sourceMap上传 缺点:国外产品(速度影响)/收费

3.https://fundebug.com/ (opens new window)

优点:小巧/国内产品(速度快)/记录用户行为/支持sourceMap上传 缺点:只支持js

注:Sentry 是一个开源的实时错误报告工具,支持 web 前后端、移动应用
以及游戏,支持 Python、OC、Java、Go、Node、Django、RoR 等主流
编程语言和框架 ,还提供了 GitHub、Slack、Trello 等常见开发工具的集成。

综上,目前最优方案:选取fundebug进行错误收集,方案可实现:

1.错误上报
2.用户行为记录
3.数据统计分析

参考:

  1. https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onerror (opens new window)
  2. https://cn.vuejs.org/v2/api/index.html#errorHandler (opens new window)
  3. http://www.ruanyifeng.com/blog/2013/01/javascript_source_map.html (opens new window)
  4. https://github.com/mozilla/source-map (opens new window)
最近更新
01
echarts扇形模拟镜头焦距与可视化角度示意图
03-10
02
vite插件钩子
03-02
03
vite的依赖预构建
02-13
更多文章>