UNPKG

@aligov/retcodelog

Version:

retcode log上报npm包,适用于 browser|nodejs|weex|E应用

304 lines (260 loc) 9.33 kB
module.exports = function (wpo, undef) { // startTime配置兼容 var startTime = wpo.startTime || wpo.config.startTime; var scriptStart = startTime; if (!startTime) { try { startTime = window.performance.timing.responseStart || +new Date(); scriptStart = +new Date(); } catch (e) { scriptStart = startTime = +new Date(); } } var send = function (params, sampling) { sampling = sampling || wpo.config.sample; params.tag = wpo.config.tag && wpo.safetyCall(wpo.config.tag, [], wpo.config.tag + '') || '' // // 双十一当天统计数据抽样率降低 // // if ((curDate.getUTCDate() == 10 && curDate.getUTCMonth() == 10 && curDate.getUTCHours() >= 16) || // (curDate.getUTCDate() == 11 && curDate.getUTCMonth() == 10)) { // sampling *= 10; // } // retcode api上报做特殊处理 if (wpo.sampling(sampling, params.type == 'retcode') == (wpo.config.modVal || 1)) { params.sampling = sampling; wpo.send(params); } }; /** * [custom description] * @param {[int/string]} category [0/'time',1/'count'] * @param {[string]} key [自定义值] * @param {[any]} value [自定义值,如果type为count,自动忽略该值] * @return {[void]} */ wpo.custom = function (category, key, value) { var customParam = { type: 'custom' }, arr = ['time', 'count']; category = arr[category] || category; if (category == 'time' || category == 'count') { customParam['category'] = category; } if (customParam.type) { customParam['key'] = key; customParam['value'] = category == 'time' ? value : undef; send(customParam); } }; /** * 过滤规则检测 filter by pattern * @param {String} msg * @param {*} filterPattern * @return {Boolean} 是否被略过 */ var filterErrMsg = function(msg,filterPattern){ // 空白消息省略 if (!msg) return true; if (!filterPattern) return false; try { var type = Object.prototype.toString.call(filterPattern).substring(8).replace(']', ''); if (type === 'Function') { return !!filterPattern(msg); } else if (type === 'RegExp') { return filterPattern.test(msg); } else if (type === 'String') { return msg.indexOf(filterPattern)>=0 } } catch (err) { if(typeof window === 'object' && window.console){ console.error('retcode log errMsgFitler error', err); } } // 未识别的过滤规则统一不过滤 return false; }; /** * [error description] * @param {[str]} category [可选参,错误类型,默认为sys] * @param {[str]} msg [自定义错误信息] * @return {[void]} */ wpo.error = function (category, msg, file, line, col, stack) { var errorParam = { type: 'jserror' }; if (arguments.length === 1) { msg = category; category = undefined; } // 有错误信息才上报 if (msg) { errorParam['category'] = category || 'sys'; if(typeof msg == 'object' && msg.message){ //event处理https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent var msgEvent = msg; try { msg = msgEvent.message; file = file || msgEvent.filename; line = line || msgEvent.lineno; col = col || msgEvent.colno; } catch(e){ } } else { if(typeof msg === 'object'){ try { msg = JSON.stringify(msg); } catch(e){ } } } try { if(msg){ msg = msg.substring(0, 1e3); } else { msg = ''; } } catch(e){ msg = ''; } stack = stack ? stack.substring(0, 1e3) : ''; //限制1000个字符 errorParam['msg'] = msg; // 若有设置errMsgFilter if(wpo.config && wpo.config.errMsgFilter){ // 检测符合规则直接忽略 if(filterErrMsg(msg,wpo.config.errMsgFilter)) return; } // separate msg file name if (file) { errorParam['file'] = file; } if (line) { errorParam['line'] = line; } if (col) { errorParam['col'] = col; } if (stack) { errorParam['stack'] = stack; } send(errorParam, 1); } }; /** * [performance description] * @param {[obj]} params [性能相关信息] * @return {[void]} */ wpo.performance = function (params) { var perParam = { type: 'per' }; send(wpo.extend(perParam, params)); }; /** * [retCode description] * @param {[str / obj]} api [所调用的api] * @param {[boolean]} issuccess [是否成功,不成功会100%发送,成功按照抽样发送] * @param {[type]} delay [调用时间] * @param {[type]} code [错误码] * @param {[type]} msg [错误详情] * @return {[void]} */ wpo.retCode = function (api, issuccess, delay, code, msg) { var retParam = { type: 'retcode', sampling: this.config.retCode[api] }; if(typeof api === 'object') { //新接口 try { api.msg = api.msg ? api.msg.substring(0, 1e3) : ''; } catch(e){ api.msg = '' } retParam.sampling = api.api ? this.config.retCode[api.api] : 1; retParam.api = api.api; retParam.issucess = api.issuccess; retParam.delay = (typeof api.delay == 'number' ? parseInt(api.delay, 10) : (new Date() - startTime)); retParam.msg = api.msg || (api.issuccess ? 'success' : 'fail'); retParam.detail = api.detail || ''; retParam.traceId = api.traceId || ''; retParam = wpo.extend(api, retParam); delete retParam['issuccess']; } else { //兼容老的接口 try { msg = msg ? msg.substring(0, 1e3) : ''; } catch(e){ msg = '' } retParam = wpo.extend({ api : api, issucess: issuccess, delay : typeof delay == 'number' ? parseInt(delay, 10) : (new Date() - startTime), msg : code || (issuccess ? 'success' : 'fail'), detail : msg || '' }, retParam); } if (typeof retParam.delay !== 'undefined' && typeof retParam.issucess !== 'undefined') { send(retParam, retParam.issucess ? retParam.sampling : 1); } }; var sendSpeed = function () { var perParam = { type: 'speed' }, val; for (var i = 0, len = wpo.speed.points.length; i < len; i++) { val = wpo.speed.points[i]; if (val) { perParam['s' + i] = val; wpo.speed.points[i] = null; } } send(perParam); }; /** * [speed description] * @param {[int/str]} pos [0/'s0',1/'s1',2/'s2'....10/'s10'] * @param {[int]} delay [耗时,如果没有定义,这按照当前时间减去页面起始时间] * @param {[boolean]} _immediately [内部使用,是否强制发送,不强制发送会尽量收集3s内的所有点的数据一次性发送] * @return {[void]} */ wpo.speed = function (pos, delay, _immediately) { var sArr; if (typeof pos == 'string') { pos = parseInt(pos.slice(1), 10); } if (typeof pos == 'number') { sArr = wpo.speed.points || new Array(11); sArr[pos] = typeof delay == 'number' ? (delay > 86400000 ? delay - startTime : delay ) : new Date() - startTime; if (sArr[pos] < 0) { sArr[pos] = new Date() - scriptStart; } wpo.speed.points = sArr; } clearTimeout(wpo.speed.timer); if (!_immediately) { wpo.speed.timer = setTimeout(sendSpeed, 3000); } else { sendSpeed(); } }; /** * [log 日志统计] * @param {[string]} msg [发送的内容] * @param {[int]} sampling [可以自定义发送的抽样] * @return {[void]} */ wpo.log = function (msg, sampling) { var param = { type: 'log', msg : msg }; send(param, sampling); }; };