为什么要引入?
用户访问我们的应用时,大致分为三个阶段:页面生产时(服务器端状态)、页面加载时和页面运行时。
现有的服务器端监控系统相对已经很成熟,而页面加载和页面运行时的状态监控一直比较欠缺。例如:
- 线上错误无法复现
- 无法第一时间获取错误
- 每个应用内有大量的异步数据调用,而它们的性能、成功率都是未知的。
解决方案:
前端监控重点监控页面的加载过程和运行时状态,同时将页面加载性能、运行时异常以及API调用状态和耗时等数据,上报到日志服务器。
\
各类平台调研对比
| 平台 | Error监控(window级别) | Error监控(框架级别) | 错误录屏 | 收费标准 | 缺点 | |
|---|---|---|---|---|---|---|
| ARMS | 阿里云监控服务 | 有 | 无 | 无 | 159/月(15w) | |
| Sentry | 上万付费企业的成熟产品 | 有 | 有 | 无 | 182/月(10W) | 访问不稳定 |
| FunDebug | SASS | 有 | 无 | 有 | 375/6个月(200w) | 初创SASS |
接入前端监控
方式一:CDN异步
将代码粘贴在<body>内容的第一行。
<script>
!(function (c, b, d, a) {
c[a] || (c[a] = {});
c[a].config = {
pid: "fdy0nvu5t1@582846f37273cf8",
appType: "web",
imgUrl: "https://arms-retcode.aliyuncs.com/r.png?",
sendResource: true,
behavior: true,
sample: 10,
ignore: {
ignoreErrors: /^Script error.?$/
}
};
with(b) with(body) with(insertBefore(createElement("script"), firstChild)) setAttribute("crossorigin", "", src = d)
})(window, document, "https://retcode.alicdn.com/retcode/bl.js", "__bl");
</script>
各项配置说明:
- pid:项目唯一ID,由ARMS在创建站点时自动生成。(需替换为各自项目的pid)
- sendResource:为true时页面onload时会上报页面加载的静态资源
- behavior:是否为了便于排查错误而记录报错的用户行为
- sample:日志采样配置,值为
1、10或100。性能和成功API日志按照1/sample的比例采样,不会影响JS错误和失败API等其他类型日志的上报。(如需要对API成功请求进行监控不用配置此项,否则设为10或100) - ignore:忽略指定URL/API/JS错误。符合规则的日志将被忽略且不会被上报
可选配置项:
- tag:传入的标记,每条日志都会携带该标记(可用于区分同一项目不同端)。
- release:应用版本号。建议配置,便于查看不同版本的上报信息。
- environment:环境字段,取值为:prod、gray、pre、daily和local
- setUsername:用于设置一个方法,该方法需要返回类型为String的用户名称。(长度限制)
- enableLinkTrace:需和应用监控服务配置使用,可不配置
- disableHook:禁用AJAX请求监听
注:其他接入方式(CDN同步接入、NPM包)参考项目配置文档
设置entCode、userCode
在登录接口返回后将entCode-userCode设置到uid字段上,便于后续追踪
window.__bl && window.__bl.setConfig({
uid: 'EC1605121DQTK2RK-UI1605121E1SICJK'
});
框架捕获错误主动上报:
Angular:
angular.module('exceptionOverride', []).factory('$exceptionHandler',
function() {
return function(exception, cause) {
exception.message += 'Angular Exception: "' + cause + '"';
throw exception;
};
}
);
angular.module('maycur', ['exceptionOverride']);
React:
使用前端监控
SDK使用说明:
api()
var begin = Date.now(),
url = '/data/getTodoList.json';
$.ajax({
url: url,
data: {id: 123456}
}).done(function (result) {
var time = Date.now() - begin;
// 上报接口调用成功。
window.__bl && __bl.api(url, true, time, result.code, result.msg);
// do something ....
}).fail(function (error) {
var time = Date.now() - begin;
// 上报接口调用失败。
window.__bl && __bl.api(url, false, time, 'ERROR', error.message);
// do something ...
});
error()
window.__bl && __bl.error(new Error('发生了一个自定义的错误'), {
filename: 'app.js',
lineno: 10,
colno: 15
});