webfunny前端监控:手把手教你搭建前端监控系统(二)—JS错误监控篇

如果你是一位前端工程师,那你一定不止一次去解决一些顽固的线上问题,你也曾想方设法复现用户的bug,结果可能都不太理想......

如何定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后。

错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决。当然,这些问题并非不能克服,让我们来一起看看如何去监控并定位线上的问题吧。

如果:你还是一个手无寸铁的前端小白吗?你想拥有一套属于自己的监控系统吗?跟着我一步步操作做,你也能搭建出一个属于自己的前端监控系统。

首页概览图

一、JS Error 监控功能 (数据概览)

如果每天都去盯着前端的报错数据,真的很耗费精力,而且很难看出是今天发生的,还是一直存在的报错。其实前端项目每天都会有些报错,比如:script error 。我们既不能控制,也不会影响我们的业务,只能让它一直存在。所以我们的前端应用,每天都会有一定数量的报错数据。只要日活量不会波动太大,那么报错数据就会比较平稳,所以我选择跟7天前的报错数据进行比较,如果出现大幅上升,那么就需要我对这个项目进行关注了,而不是每天查看具体的报错数据。

前端项目报错统计图

对于前端应用来说,Js错误的发生直接影响前端应用的质量。对前端异常的监控是整个前端监控系统中的一个重要环节。前端异常包含很多种情况:1. js编译时异常(开发阶段就能排);2. js运行时异常;3. 加载静态资源异常(路径写错、资源服务器异常、CDN异常、跨域);4. 接口请求异常等。这一篇我们只介绍Js运行时异常。

监控流程:监控错误 -> 搜集错误 -> 存储错误 -> 分析错误 -> 错误报警-> 定位错误 -> 解决错误

首先,我们应该对Js报错情况有个大致的了解,这样才能够及时的了解前端项目的健康状况。所以我们需要分析出一些必要的数据,如下图所示:

前端项目报错的分析数据

那么我们该如何去监控这些数据呢?其实主要用到下边三种方法:

1)重写window.onerror 方法, 大家熟知,监控JS错误必然离不开它,有人对他进行了测试测试介绍感觉也是比较用心了。

2)重写console.error方法,为什么要重写这个方法,我不能够给出明确的答案,如果App首次向浏览器注入的Js代码报错了,window.onerror是无法监控到的,所以只能重写console.error的方式来进行捕获,也许会有更好的办法。待window.onerror成功后,此方法便不再需要用了。

3)重写

window.onunhandledrejection方法。当你用到Promise的时候,而你又忘记写reject的捕获方法的时候,系统总是会抛出一个叫 Unhandled Promise rejection. 没有堆栈,没有其他信息,特别是在写fetch请求的时候很容易发生。所以我们需要重写这个方法,以帮助我们监控此类错误

  下边是就是做JS错误监控代码,大家可以参考一下:

// 重写console.error, 可以捕获更全面的报错信息

var oldError = console.error;

console.error = function (tempErrorMsg) {

var errorMsg = (arguments[0] && arguments[0].message) || tempErrorMsg;

var lineNumber = 0;

var columnNumber = 0;

var errorObj = arguments[0] && arguments[0].stack;

if (!errorObj) {

siftAndMakeUpMessage("console_error", errorMsg, WEB_LOCATION, lineNumber, columnNumber, "CustomizeError: " + errorMsg);

} else {

siftAndMakeUpMessage("console_error", errorMsg, WEB_LOCATION, lineNumber, columnNumber, errorObj);

}

return oldError.apply(console, arguments);

};

// 重写 onerror 进行jsError的监听

window.onerror = function(errorMsg, url, lineNumber, columnNumber, errorObj) {

jsMonitorStarted = true;

var errorStack = errorObj ? errorObj.stack : null;

siftAndMakeUpMessage("on_error", errorMsg, url, lineNumber, columnNumber, errorStack);

};

// 重写 onunhandledrejection 对未处理的rejection错误进行捕获处理

window.onunhandledrejection = function(e) {

var errorMsg = "";

var errorStack = "";

if (typeof e.reason === "object") {

errorMsg = e.reason.message;

errorStack = e.reason.stack;

} else {

errorMsg = e.reason;

errorStack = "";

}

siftAndMakeUpMessage("on_error", errorMsg, WEB_LOCATION, 0, 0, "UncaughtInPromiseError: " + errorStack);

}

封装简易的Ajax

为了将这些数据上传到我们的服务器,我们总不能每次都用xmlHttpRequest来发送ajax请求吧,所以我们需要自己封装一个简单的Ajax。

this.ajax = function(method, url, param, successCallback, failCallback) {

var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

xmlHttp.open(method, url, true);

xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

xmlHttp.onreadystatechange = function () {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

var res = JSON.parse(xmlHttp.responseText);

typeof successCallback == 'function' && successCallback(res);

} else {

typeof failCallback == 'function' && failCallback();

}

};

xmlHttp.send("data=" + JSON.stringify(param));

}

二、JS Error 详细信息解析

统计JS Error的目的,一、是为了了解线上项目的健康状况,二、是为了分析错误,帮助我们查找问题之所在,并且解决它。所以,如何定位线上的问题,并解决问题,是我们现在要讨论的重点。下面我们需要对几个关键点进行分析,先看一下总体的分析图:

JS错误分析结果图

① 某种错误发生的次数——发生次数跟影响用户是成正比的, 如果发生次数跟影响用户数量都很高,那么这是一个比较严重的bug, 需要立即解决。反之, 如果次数很多,影响用户数量很少。说明这种错误只发生在少量设备中,优先级相对较低,可以择时对该类机型设备进行兼容处理。当然,ip地址访问次数也能说明这个问题。

② 页面发生了哪些错误——这个有利于我们缩小问题的范围,方便我们排查。

③ 错误堆栈——这点不用说,是定位错误最重要的因素。正常情况下,代码都是被压缩的,所以我在后台解析并截取出错代码附近的一部分代码,进行展示,排查错误。PS: 可以根据sourceMap解析压缩混淆代码的具体位置和代码片段,想法很不错,后期我会加上,目前已经完成测试版本。另外,代码虽然被压缩,但是依然很轻松定位到出错的位置,如下图所示。

sourceMap解析源码

④ 设备信息——当错误发生是,分析出用户当时使用设备的浏览器信息,系统版本,设备机型等等,能够帮我们快速的定位到需要兼容的设备,进而提升解决问题的效率。

⑤ 用户足迹——通过记录用户的具体步骤,可以清晰了解到用户出错前后时间内发生的事情,对解决问题也有很大的帮助。如下图:

用户行为记录

三、JS报错的实时监控与报警

既然我们已经具有了搜集js报错和分析报错的能力了,那么我们也可以做到Js报错实时监控,以及实时预警了,这样可以防范线上事故于未然,及时的制止线上事故的持续发生, 减少损失。

如上图所示,展示了从当前时间向前推算24小时,每小时报错数量。另外展示了7天前同一时间段的报错数量,如果你的项目健康稳定,那么在相同时间段的报错数量应该不会相差太大。如果出现相差太大的情况发生,说明线上出现了问题,此刻应该发出警告,避免线上事故的发生。demo上暂未加上警告功能,但是原理清楚了,后边自然水到渠成。

最后这个功能应该很容易理解,及时的发布警报,能够让你更快知道前端的问题。

至此,我们的JS错误统计功能就完成了,你学会了吗?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容