什么是ARMS前端监控?
ARMS前端监控专注于对Web场景、Weex场景和小程序场景的监控,从页面打开速度(测速)、页面稳定性(JS Error)和外部服务调用成功率(API)这三个方面监测Web和小程序页面的健康度。
为什么要有前端监控?
用户访问您的业务时,整个访问过程大致可以分为三个阶段:页面生产时(服务器端状态)、页面加载时和页面运行时。
为了保证线上业务稳定运行,我们会在服务器端对业务的运行状态进行各种监控。现有的服务器端监控系统相对已经很成熟,而页面加载和页面运行时的状态监控一直比较欠缺。例如:
- 无法第一时间获知用户访问您的站点时遇到的错误。
- 各个国家、各个地区的用户访问您的站点的真实速度未知。
- 每个应用内有大量的异步数据调用,而它们的性能、成功率都是未知的。
目前ARMS前端监控存在的问题
- 即便开启SPA自动解析配置,也无法按页面路由统计访问量,即路由切换时无法进行数据上报;
- 满意度趋势、访问速度等性能指标无法按路由进行聚合分析,只能聚合到对应模块名下
- ARMS前端监控的api自动上报无法对xxx/?operationId=xxx格式的网关接口进行完整上报,会将operationId=xxx参数省略,导致不同接口聚合到域名,而非完整的接口地址。
(对于上述第二个问题,目前没有解决方案,阿里云表示会在后续迭代中支持。)
ARMS接入
接入阿里云ARMS时,为了保证监控功能尽可能完整可用,且上报数据符合要求,在接入时需要进行一些适配,官方文档请参考ARMS前端监控。下面来看看在项目中具体是怎么接入使用的:
1. 初始化配置
Web场景有两种接入方式:一种是以CDN方式安装探针,一种是以npm方式安装探针;本文将采用CDN方式接入; ARMS控制台的具体操作可以参考官方文档。
为了进行api请求手动上报,避免上报请求按域名聚合,请一定要接入关闭API自动上报的配置,即设置disableHook为true;为了保证页面路由统计数据上报,请一定要接入开启SPA自动解析的配置项,即设置enableSPA为true。
异步加载:复制提供的代码并粘贴至页面HTML中 <body>元素内部的第一行,然后重启应用。
<script>
!(function(c,b,d,a){
var hostname = location && location.hostname;
// 根据hostname确定要上报的应用id,对生产环境和测试环境上报数据进行区分,pid是arms监控台中创建应用之后自动生成的
var pid = hostname.indexOf('xxx.com') !== -1 ? 'brtgwl5o94@0cec5d2526c78fe' : 'brtgwl5o94@394d30e3bed24c7';
c[a]||(c[a]={});c[a].config={pid:pid,appType:"web",imgUrl:"https://arms-retcode.aliyuncs.com/r.png?",sendResource:true,enableLinkTrace:true,behavior:true,disableHook:true,enableConsole:true,useFmp:true,enableSPA:true,
parseHash:function(){
var pageName = '';
if (location) {
var pathname = location.pathname;
var hash = location.hash;
pageName = hostname + pathname + hash.split('?')[0];
}
return pageName || '未知页面';
}};
with(b)with(body)with(insertBefore(createElement("script"),firstChild))setAttribute("crossorigin","",src=d)
})(window,document,"https://retcode.alicdn.com/retcode/bl.js","__bl");
</script>
parseHash属性设置也是为了保证包含路由的页面地址上报,而不仅按前端模块名聚合,设置后上报页面地址如下:
2. API请求手动上报
参考官方文档对api进行手动上报。可参考下图的方式,在业务工程统一封装的api请求方法(例如fetch.js等)中进行手动上报。
注意:采用手动上报时,npm包中发起的请求及未通过统一api方法发起的请求无法进行上报。
3. 设置用户ID
了根据用户ID进行相关检索和会话追踪,在业务工程中还需按文档提供的方式进行uid配置:
if (__bl && __bl.setConfig) {
getToken(true, Madp.getChannel()).then((token) => {
// eslint-disable-next-line no-undef
__bl.setConfig({
uid: token
});
});
}
配置时可通过[二方包@mu/dev-finger]提供的getToken方法,将标示用户设备的token作为uid上报,但该标示存在可能无法对应唯一用户的问题,后续uid的上报可能会进行调整。