0.0.4 • Published 1 year ago

aegis-web-mini-sdk v0.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

aegis-web-mini-sdk

Aegis(读音/ˈiːdʒɪs/) 是腾讯云监控团队提供的前端监控 SDK,涵盖了错误监控,资源测速(img, script, css),接口测速,页面性能(首屏时间)。无需侵入代码,只需引入 SDK 即可自动完成所有监控上报。

在使用 aegis 时无需在业务代码中打点或者做任何其他操作,可以做到与业务代码充分解耦。aegis 将会自动监控前端错误,在错误发生时上报错误的具体情况,帮助您快速定位问题。当您开启资源测速时,aegis 将会自动监听页面资源加载情况(耗费时长、成功率等),并在不影响前端性能的前提下收集前端的性能数据,帮助您快速定位性能短板,提升用户体验。

使用本 SDK 需要配合使用腾讯云前端性能监控 RUM 平台

本 SDK 是 Aegis mini SDK,用于开发者包装后二次使用,比如模块内部使用。该 SDK 不会主动收集任何信息,需要开发者引入后自动上报。

Usage

  1. 前往腾讯云前端性能监控 RUM 平台

  2. 申请项目,申请完成后得到上报 id,id 在 sdk 初始化的时候会使用。

Aegis SDK 在上报所有数据时都会带上上报 id,后端服务将根据上报 id辨别数据来自哪一个项目,因此,Aegis 建议为每一个项目都单独申请一个 id,如果一个项目下有多个页面,还可以为每一个页面都申请一个项目 id,方便单独查看每一个页面的 PV、错误率、请求错误率等数据。

使用SDK

安装 SDK

  1. npm 引入
$ npm install aegis-web-mini-sdk
  1. 内联引入

如果想要把 SDK 代码直接内联到 html 中的话,可以选择直接 copy 代码的方式,或者使用您熟悉打包工具的内联代码的工具

SDK 实例化

引入 SDK 后,需实例化:

const aegis = new Aegis({
  id: 'pGUVFTCZyewxxxxx',
  uin: 'xxx', // 用户唯一标识(可选)
});

::: warning 注意 ⚠️ 为了不遗漏数据,须尽早进行初始化; :::

日志上报

创建完 Aegis 实例之后,就可以开心的上报日志啦 🥰,日志上报同样简单

在 mini sdk 中,因为没有白名单机制, info 与 infoAll 的用法完全相同

aegis.info(
  `我是一条普通的信息`
);

aegis.infoAll(
  `我是一条普通的信息`
);

aegis.error(
  new Error('我是一条主动上报的JS执行错误,你可以捕获错误后主动上报')
);

aegis.report({
  msg: '这是一个ajax错误日志', 
  level: Aegis.LogType.AJAX_ERROR, 
});

aid

Aegis SDK 为每个用户设备分配的唯一标识,会存储在浏览器的 localStorage 里面,用来区分用户,计算 uv 等。aid 只有用户清理浏览器缓存才会更新。

算法如下:

async getAid(callback: Function) {
// 某些情况下操作 localStorage 会报错.
  try {
    let aid = await localStorage.getItem('AEGIS_ID');
    if (!aid) {
    aid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
      const r = (Math.random() * 16) | 0;
      const v = c === 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });
    localStorage.setItem('AEGIS_ID', aid);
    }
    callback?.(aid || '');
  } catch (e) {
    callback?.('');
  }
}

对于一些项目,使用自己构造的 aid 作为上报规则,后端对 aid 的校验规则如下:/^[@=.0-9a-zA-Z_-]{4,36}$/

实例方法

Aegis 实例暴露接口简单实用,目前 Aegis 实例有以下方法供您使用:
setConfiginfoinfoAllreporterrorreportEventreportTimetimetimeEnd

setConfig

该方法用来修改实例配置,比如下面场景:
在实例化 Aegis 时需要传入配置对象

const aegis = new Aegis({
  id: 'pGUVFTCZyewxxxxx',
  uin: '777'
})

很多情况下,并不能一开始就获取到用户的 uin,而等获取到用户的 uin 才开始实例化 Aegis 就晚了,这期间发生的错误 Aegis 将监听不到。uin 的设置可以在获取到用户的时候:

const aegis = new Aegis({
  id: 'pGUVFTCZyewxxxxx'
})

// 拿到uin之后...
aegis.setConfig({
  uin: '6666'
})

reportEvent

该方法可用来上报自定义事件,平台将会自动统计上报事件的各项指标,诸如:PV、平台分布等...

reportEvent 可以支持两种类型上报参数类型,一种是字符串类型

aegis.reportEvent('XXX请求成功');

一种是对象类型,ext1 ext2 ext3 默认使用 new Aegis 的时候传入的参数,自定义事件上报的时候,可以覆盖默认值。

aegis.reportEvent({
    name: 'XXX请求成功', // 必填
    ext1: '额外参数1',
    ext2: '额外参数2',
    ext3: '额外参数3',
})

注意,额外参数的三个 key 是固定的,目前只支持 ext1 ext2 ext3。

reportTime

该方法可用来上报自定义测速,例如:

// 假如‘onload’的时间是1s
aegis.reportTime('onload', 1000);

或者如果需要使用额外参数,可以传入对象类型参数,ext1,ext2,ext3 会覆盖默认值:

aegis.reportTime({
    name: 'onload', // 自定义测速名称
    duration: 1000, // 自定义测速耗时(0 - 60000)
    ext1: 'test1',
    ext2: 'test2',
    ext3: 'test3',
});

onload 可以修改为其他的命名。

time、timeEnd

该方法同样可用来上报自定义测速,适用于两个时间点之间时长的计算并上报,例如:

aegis.time('complexOperation');
/**
 * .
 * .
 * 做了很久的复杂操作之后。。。
 * .
 * .
 */
aegis.timeEnd('complexOperation'); /** 此时日志已经报上去了😄**/

complexOperation 同样可以修改为其他的命名。 自定义测速是用户上报任意值,服务端对其进行统计和计算,因为服务端不能做脏数据处理,因此建议用户在上报端进行统计值限制,防止脏数据对整体产生影响。 目前 Aegis 只支持 0-60000 的数值计算,如果大于该值,建议进行合理改造。

钩子函数

onBeforeRequest

该钩子函数会在所有请求发出前调用,参数中会传入请求的所有内容,必须返回待发送内容。

function changeURLArg(url,arg,arg_val){ 
    var pattern=arg+'=([^&]*)'; 
    var replaceText=arg+'='+arg_val; 
    if (url.match(pattern)){ 
        var tmp='/('+ arg+'=)([^&]*)/gi'; 
        tmp=url.replace(eval(tmp),replaceText); 
        return tmp;  
    }
    return url
}
const aegis = new Aegis({
    id: 'pGUVFTCZyewxxxxx',
    onBeforeRequest(log) {
        if (log.type === 'performance') {
            // 页面测速,此时可以修改log内容,如修改页面测速platform
            log.url = changeURLArg(log.url, 'platform', type)
        }
        return log
    }
});

//  SendType {
//     LOG = 'log',  // 日志
//     SPEED = 'speed', // 接口和静态资源测速
//     PERFORMANCE = 'performance', // 页面测速
//     OFFLINE = 'offline', // 离线日志上传
//     WHITE_LIST = 'whiteList', // 白名单
//     VITALS = 'vitals', // vitals
//     PV = 'pv', // 自定义pv
//     EVENT = 'event', // 自定义事件
//     CUSTOM = 'custom', // 自定义测速
//     SDK_ERROR = 'sdkError', // sdk报错
// }

onReport

该钩子将在日志上报成功之后执行,用法类似 beforeReport 钩子,唯一不同点在于,该钩子接收到的所有参数都是已经上报完成的日志,而 beforeReport 钩子接收的参数是即将上报的日志。

配置文档

配置描述
id必须,string,默认 无。开发者平台分配的项目ID
uin建议,string,默认取 cookie 中的 uin 字段。当前用户的唯一标识符,白名单上报时将根据该字段判定用户是否在白名单中,字段仅支持字母数字@=._-,正则表达式: /^[@=.0-9a-zA-Z_-]{1,60}$/
aid可选,boolean,默认 true。当前实例是否生成aid
random可选,number,默认 1。0~1 抽样率
version可选,string,默认 sdk 版本号。当前上报版本,当页面使用了pwa或者存在离线包时,可用来判断当前的上报是来自哪一个版本的代码,仅支持字母数字.,:_-,长度在 60 位以内 /^[0-9a-zA-Z.,:_-]{1,60}$/
delay可选,number,默认 1000 ms。上报节流时间,在该时间段内的上报将会合并到一个上报请求中。
repeat可选,number,默认 5。重复上报次数,对于同一个错误超过多少次不上报。
hostUrl可选,默认是 aegis.qq.com影响全部上报数据的 host 地址,下面几个 url 地址设置后会覆盖对应的上报地址 |
url可选,string,默认 '//aegis.qq.com/collect'。日志上报地址
pvUrl可选,string,默认 '//aegis.qq.com/collect/pv'。pv上报地址
speedUrl可选,string,默认 '//aegis.qq.com/speed'。测速日志上报地址
ext1可选,string,自定义上报的额外维度,上报的时候可以被覆盖
ext2可选,string,自定义上报的额外维度,上报的时候可以被覆盖
ext3可选,string,自定义上报的额外维度,上报的时候可以被覆盖

示例

1 api.retCodeHandler,假如后台返回数据为:

{
    body: {
        code: 200,
        retCode: 0,
        data: {
            // xxx
        }
    }
}

业务需要:code不为200,或者retCode不为0,此次请求就是错误的。此时只需进行以下配置:

new Aegis({
  reportApiSpeed: true, // 需要开两个,不然不会有返回码上报
  reportAssetSpeed: true,
  api: {
    retCodeHandler(data, url, xhr) {
      // data 是string类型,如果需要对象需要手动parse下
      // url 为请求url
      // xhr 响应,可以通过xhr.response拿到完整的后台响应
      try {
        data = JSON.parse(data)
      } catch(e) {}
      return {
        isErr: data.body.code !== 200 || data.body.retCode !== 0,
        code:  data.body.code
      }
    }
  }
})

api.resourceTypeHandler,假如接口

http://example.com/test-api

返回的 Content-Typetext/html,这将导致 Aegis 认为该接口返回的是静态资源,可以通过以下方法修正:

new Aegis({
  reportApiSpeed: true, // 需要开两个,不然不会有返回码上报
  reportAssetSpeed: true,
  api: {
    resourceTypeHandler(url) {
      if (url?.indexOf('http://example.com/test-api') != -1) {
        return 'fetch';
      }
    }
  }
})

2 reportApiSpeed.urlHandler,假如您页面中有restful风格的接口,如:
www.example.com/user/1000
www.example.com/user/1001

在上报测速时需要将这些接口聚合:

new Aegis({
  reportApiSpeed: {
    urlHandler(url, payload) {
      if ((/www\.example\.com\/user\/\d*/).test(url)) {
        return 'www.example.com/user/:id';
      }
      return url;
    }
  }
})