【JS】浅入浅出前端监控系统落地

浅入浅出前端监控系统落地

背景

前端代码不像java等后端语言运行在自己的服务器,错误可以直接捕获生成日志,前端代码运行在用户端,发生错误时前端工程师无法知晓。

这是这套系统应用前,前端开发者获取用户端错误信息的途径:
【JS】浅入浅出前端监控系统落地

做为一名合格的前端工程师,出于对项目认真负责的态度(技术驱动),开发了一套自己的前端监控系统,一方面可以促进项目更完善,增加用户体验,另一方面,学习其中的错误捕获机制,可以让我们对JavaScript这门语言更多一些了解。

架构

【JS】浅入浅出前端监控系统落地

  • 前端SDK

使用TypeScript开发保证代码规范,采用gulp做为代码打包压缩工具,代码构建后上传至 npm 供前端业务使用。

SDK一些主要API实现:

  1. 对前端资源,img、css、script等错误捕获

window.addEventListener('error', function (e) {

let errorData = {

errorType: 'resource',

msg: e.target['localName'],

target: e.target['localName'],

type: e.type,

resourceUrl: e.target['href'] || e.target['currentSrc'] || e.target['src']

};

}, true);

  1. 对前端语法错误的捕获

window.onerror = function (msg, _url, line, col, error) {

setTimeout(function () {

col = col || (window.event && window.event['errorCharacter']) || 0;

let errorData = {

errorType: 'grammar',

msg: error && error.stack ? error.stack.toString() : msg,

resourceUrl: _url,

line: line,

col: col,

}

};

};

  1. 对promise错误的捕获

window.addEventListener('unhandledrejection', function (e) {

let resourceUrl,

col,

line,

error = e && e.reason,

message = error.message || '',

stack = error.stack || '',

errs = stack.match(/\(.+?\)/);

if (errs && errs.length) errs = errs[0];

errs = errs.replace(/\w.+[js|html]/g, $1 => { resourceUrl = $1; return ''; });

errs = errs.split(':');

if (errs && errs.length > 1) line = parseInt(errs[1] || 0);

col = parseInt(errs[2] || 0);

let errorData = {

errorType: 'grammar',

msg: message,

resourceUrl: resourceUrl,

line: col,

col: line,

type: e.type

}

})

  1. 对ajax错误的捕获

虽然 xhr.readyState === 4 写到了注释里,但这里尤为重要,可以判断接口成功但是非正常的结果

 _Ajax({

onreadystatechange: function (xhr) {

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

//这里可以判断接口成功但是非正常的结果

}else if(xhr.readyState === 4 && xhr.xhr.status !== 200){

}

},

onerror: function (xhr) {

ajaxResponse(xhr)

},

onload: function (xhr) {

if (xhr.readyState === 4) {

if (xhr.status < 200 || xhr.status > 300) {

xhr.method = xhr.args.method

}

}

},

open: function (arg, xhr) {

let result = { url: arg[1].split('?')[0], method: arg[0] || 'GET', type: 'xmlhttprequest' }

this.args = result

}

})

// ajax重写

function _Ajax(proxy) {

window['_ahrealxhr'] = window['_ahrealxhr'] || XMLHttpRequest;

//@ts-ignore

XMLHttpRequest = function () {

this.xhr = new window['_ahrealxhr'];

for (var attr in this.xhr) {

var type = "";

try {

type = typeof this.xhr[attr]

} catch (e) { }

if (type === "function") {

this[attr] = hookfun(attr);

} else {

Object.defineProperty(this, attr, {

get: getFactory(attr),

set: setFactory(attr)

})

}

}

}

function getFactory(attr) {

return function () {

var v = this.hasOwnProperty(attr + "_") ? this[attr + "_"] : this.xhr[attr];

var attrGetterHook = (proxy[attr] || {})["getter"]

return attrGetterHook && attrGetterHook(v, this) || v

}

}

function setFactory(attr) {

return function (v) {

var xhr = this.xhr;

var that = this;

var hook = proxy[attr];

if (typeof hook === "function") {

xhr[attr] = function () {

proxy[attr](that) || v.apply(xhr, arguments);

}

} else {

var attrSetterHook = (hook || {})["setter"];

v = attrSetterHook && attrSetterHook(v, that) || v

try {

xhr[attr] = v;

} catch (e) {

this[attr + "_"] = v;

}

}

}

}

function hookfun(fun) {

return function () {

var args = [].slice.call(arguments)

if (proxy[fun] && proxy[fun].call(this, args, this.xhr)) {

return;

}

return this.xhr[fun].apply(this.xhr, args);

}

}

return window['_ahrealxhr'];

}

  1. 数据上报:

//1. 使用图片src进行数据上报

let sendData = new Image();

secdData.src = `${地址?数据}`

//2. 使用Navigator.sendBeacon

  • NodeJS服务端

使用经典MVC结构,框架采用KOA2,pm2进行进程守护,数据存储库使用MySQL

  • 管理后台React

使用react做为管理后台
【JS】浅入浅出前端监控系统落地

总结

这种业务支撑服务,起源于个人兴趣与思考,没有大量公司资源可以协调,同时也没有了来自上层的压力。自己想做的项目,有了更多的自主性,总想着赶快第一版可以上线,感谢前端同学JGT(姓名拼音缩写)的鼓励与配合。

目前第一版已稳定上线,服务于公司众多业务,后续还有细节要优化,同时会把一些新的想法加进去。

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star github ,对作者也是一种鼓励。

以上是 【JS】浅入浅出前端监控系统落地 的全部内容, 来源链接: utcz.com/a/104607.html

回到顶部