关于前端异常定位神器sourcemap的部署笔记

本文涉及到的技术nodejs,koa,sourcemap,webpack等

前端有脚本报错,通过监听异常,我们能捕获到异常发生的url。

比如,我们通过收集到的错误日志中发现有一条报错信息:

null is not an object evaluating ‘Pe.default.base.getAppBaseInfo’,对应的url:xxx/js/vendor.ae7546e8.js:1:494634

上面这条url,我们能获取到url以及行数和列信息,格式:{url}:{row}:{colum}。

因为代码一般都是压缩过的,所以行数一般都是1;

如果我们之前有保留对应js的souceMap(也就是vendor.ae7546e8.js.map) 文件,

就可以通过sourcemap的接口获取到具体的前端js异常堆栈:

下图是通过soucemap的反查到的错误堆栈:

 

是不是非常直观,简直不要太好用。

此外有时候你会发现一些很有意思的异常,

比如下面这个异常,一般情况下是用户禁用了本地缓存或导致的。

可以说,sourcemap的出现,给前端带来了非常好的bug定位体验。

具体实现sourcemap,定位异常呢?

sourcemap文件怎么来?

使用webpack打包js的时候,在webpack配置文件中有一个选项就能轻松生产对应map文件:

devtool: ‘source-map’,这样就能生成对应的sourcemap

 

网上有很多资料可以查阅,我也将自己部署异常分析系统的经验总结一下。

首先是异常日志收集,这一部分前面有单独介绍过。一般是在服务器部署一个日志服务,一般采用nginx的access.log进行收集,也可以通过api来采集,业界通常采用前者。前端通过请求一个gif图片,实际上是在nginx进行了特殊的转发处理。发送一条图片请求,将异常信息写入到nginx日志。

然后通过服务端一系列操作,可以拿到日志列表信息。

 

收集到异常日志之后,我们拿到几个关键信息,错误关键词error.message, url或者location,row、column。

然后,下面部分就是基于,获取到这些信息之后,如何反查具体异常的堆栈的。

sourcemap如何定位异常?

首先我们要了解下sourcemap 这个npm包。github官网:https://github.com/mozilla/source-map

包地址:https://www.npmjs.com/package/source-map

官网一句话介绍:sourcemap:commonjs模块的源码映射生成器。

首先引入模块

// Node.js
var sourceMap = require("source-map");

// Browser builds
var sourceMap = window.sourceMap;

// Inside Firefox
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");

 

使用接口获取源位置:

const consumer = new sourceMap.SourceMapConsumer(fileContent);
let letlookup = {
    line:parseInt(line),
    column:parseInt(column)
};
 
let result = consumer.originalPositionFor(lookup);

这里里面的 fileContent 是一个json对象,也就是sourcemap文件内容转换成的json对象,对象的格式如下。

{
  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"
}

上面的consumer.originalPositionFor 方法返回的result,就是我们要的异常堆栈信息了,我们可以使用node+koa包装成一个api

最终可以服务端返回下面格式的信息

{
 "code": 0,
 "data": {
 "url": "https:xxx/js/index_vue.a13044ca.js",
 "line": "1",
 "column": "102719",
 "source": {
 "name": "webpack:///src/xxxx/index.js",
 "data": {
 "line": 111,
 "column": 23
 },
 "line": [
 {
 "num": 108,
 "ctn": " if(Object.prototype.toString.call(res) === '[object String]'){"
 },
 {
 "num": 109,
 "ctn": " try{"
 },
 {
 "num": 110,
 "ctn": " res = JSON.parse(res)"
 },
 {
 "num": 111,
 "ctn": " }catch(err){"
 },
 {
 "num": 112,
 "ctn": " // 这里报错几率比较多,上报异常数据日志"
 },
 {
 "num": 113,
 "ctn": " reportException({"
 }
 ]
 }
 }
}

最后前端处理下,搞成一个可视化工具,从此查异常,就非常方便了。

下面是整个流程架构图

发表评论

记录工作生活点滴。

返回
顶部