@arms/rum-uniapp 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -9
- package/dist/uniapp-sdk.js +1 -1
- package/es/collector/action/index.d.ts +14 -0
- package/es/collector/action/index.js +2 -61
- package/es/collector/exception/index.d.ts +37 -2
- package/es/collector/exception/index.js +49 -4
- package/es/collector/resource/api.d.ts +1 -1
- package/es/collector/resource/api.js +6 -4
- package/es/collector/view/pv.js +1 -1
- package/es/configManager.d.ts +13 -0
- package/es/configManager.js +5 -0
- package/es/reporter/index.js +2 -2
- package/es/reporter/monitor-reporter.d.ts +11 -0
- package/es/reporter/monitor-reporter.js +5 -0
- package/es/shell.d.ts +4 -2
- package/es/shell.js +8 -10
- package/es/utils/api.d.ts +1 -1
- package/es/utils/api.js +1 -1
- package/es/utils/mixin.d.ts +2 -2
- package/es/utils/mixin.js +9 -2
- package/es/utils/platform.d.ts +4 -2
- package/es/utils/platform.js +1 -1
- package/es/utils/session.d.ts +3 -1
- package/es/utils/session.js +2 -2
- package/es/utils/view.js +3 -4
- package/lib/collector/action/index.d.ts +14 -0
- package/lib/collector/action/index.js +2 -62
- package/lib/collector/exception/index.d.ts +37 -2
- package/lib/collector/exception/index.js +48 -4
- package/lib/collector/resource/api.d.ts +1 -1
- package/lib/collector/resource/api.js +6 -4
- package/lib/collector/view/pv.js +1 -1
- package/lib/configManager.d.ts +13 -0
- package/lib/configManager.js +5 -0
- package/lib/reporter/index.js +1 -1
- package/lib/reporter/monitor-reporter.d.ts +11 -0
- package/lib/reporter/monitor-reporter.js +5 -0
- package/lib/shell.d.ts +4 -2
- package/lib/shell.js +5 -7
- package/lib/utils/api.d.ts +1 -1
- package/lib/utils/api.js +1 -1
- package/lib/utils/mixin.d.ts +2 -2
- package/lib/utils/mixin.js +9 -2
- package/lib/utils/platform.d.ts +4 -2
- package/lib/utils/platform.js +1 -1
- package/lib/utils/session.d.ts +3 -1
- package/lib/utils/session.js +1 -1
- package/lib/utils/view.js +2 -3
- package/package.json +2 -2
|
@@ -3,13 +3,48 @@ export default class ExceptionCollector implements ICollector {
|
|
|
3
3
|
name: string;
|
|
4
4
|
ctx: IContext;
|
|
5
5
|
sendEvent: (payload: RumEvent) => void;
|
|
6
|
+
private recentErrors;
|
|
7
|
+
private timerWrappers;
|
|
6
8
|
setup(ctx: IContext, sendEvent: (payload: RumEvent) => void): void;
|
|
7
9
|
hackOrigin(): void;
|
|
10
|
+
/**
|
|
11
|
+
* 仅在支持 addEventListener 的宿主(H5 window)上注册全局事件,
|
|
12
|
+
* App / 小程序环境安全跳过而非抛错中断后续注册
|
|
13
|
+
*/
|
|
14
|
+
safeAddEventListener(type: string, handler: Function): void;
|
|
15
|
+
/**
|
|
16
|
+
* App 端(plus 存在)补充引擎级异常通道。
|
|
17
|
+
* uni-app App 端的 App.onError 仅由 Vue errorHandler 触发,异步回调(timers、
|
|
18
|
+
* 原生回调等 Vue 管理范围外)中的未捕获异常由引擎异常处理器进入原生
|
|
19
|
+
* reportJSException 后终结,不回流 uni.onError / global error 事件:
|
|
20
|
+
* 1. 劫持 reportJSException(runtime 注入的全局函数):引擎级未捕获异常的收口,
|
|
21
|
+
* 原生按全局名调用时可被截获(机会性通道,取决于 runtime 调用方式),原函数照常执行
|
|
22
|
+
* 2. 包装 setTimeout / setInterval / setImmediate:确定性捕获 timers 回调异常,
|
|
23
|
+
* 上报后原样 rethrow 保持引擎原有行为
|
|
24
|
+
* 3. plus.globalEvent 的 error / unhandledrejection:防御式注册,若端上派发则自动生效
|
|
25
|
+
*/
|
|
26
|
+
hackAppRuntime(): void;
|
|
27
|
+
/**
|
|
28
|
+
* reportJSException 收口处理:参数形态无公开契约(观察为函数名 + 异常文本,
|
|
29
|
+
* 部分实现含 instanceId / errCode),逐参数解析:Error 对象优先,字符串拼接后
|
|
30
|
+
* 经 getErrorByStack 解析;字符串解析失败遵循既定的丢弃策略
|
|
31
|
+
*/
|
|
32
|
+
reportJSExceptionHandler: (...args: any[]) => void;
|
|
33
|
+
/**
|
|
34
|
+
* 包装 timers 全局函数:回调异常确定性捕获(App 端异步异常主场景),
|
|
35
|
+
* 上报后原样 rethrow,保持引擎对异常的原有处理路径
|
|
36
|
+
*/
|
|
37
|
+
wrapTimers(): void;
|
|
38
|
+
/**
|
|
39
|
+
* App 端多通道去重:timers 包装与 reportJSException 收口会对同一异常各触发
|
|
40
|
+
* 一次,窗口内 name+message 相同视为重复;环形清理 + 数量上限防泄漏
|
|
41
|
+
*/
|
|
42
|
+
isDuplicated(name: string, message: string): boolean;
|
|
8
43
|
vueError: (_: any, error: Error) => void;
|
|
9
|
-
uniError: (error:
|
|
44
|
+
uniError: (error: string) => void;
|
|
10
45
|
onError: (error: Error) => void;
|
|
11
46
|
onUnhandledRejection: (e: PromiseRejectionEvent) => void;
|
|
12
|
-
errorHandle: (event: any, source?: string) => void;
|
|
47
|
+
errorHandle: (event: any, source?: string, dedupe?: boolean) => void;
|
|
13
48
|
/**
|
|
14
49
|
* 根据stack获取Error信息
|
|
15
50
|
* TODO: 增加基于Stack解析filename和lineNumber的能力
|
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
"use strict";exports.__esModule=!0,exports["default"]=void 0;var _rumCore=require("@arms/rum-core"),_mixin=require("../../utils/mixin"),_platform=require("../../utils/platform"),ExceptionCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="exception-collector",this.ctx=void 0,this.sendEvent=void 0,this.vueError=function(b,c){a.errorHandle(c,"Vue.onError")},this.uniError=function(b){a.errorHandle(b,"uni.onError")},this.onError=function(b){a.errorHandle(b,"onError")},this.onUnhandledRejection=function(b){if(b){var c=b.reason;if(c){var d=c.errMsg;// 对 Uniapp 内置错误进行解析
|
|
2
|
-
if(d&&(0,_rumCore.isString)(d)){c=new Error(d),c.name="",c.stack="";for(var e,f=["navigateTo","redirectTo","appLaunch","switchTab","getLocation","onLocationChange"],g=0,h=f;g<h.length;g++)if(e=h[g],d.startsWith(e)){c.name=e;break}c.name||(c.name=d.split(":")[0])}a.errorHandle(c,"onUnhandledRejection")}}},this.errorHandle=function(b,c){void 0===c&&(c="");var
|
|
3
|
-
|
|
1
|
+
"use strict";exports.__esModule=!0,exports["default"]=void 0;var _rumCore=require("@arms/rum-core"),_mixin=require("../../utils/mixin"),_platform=require("../../utils/platform"),DEDUPE_WINDOW=5e3,DEDUPE_MAX=50,ExceptionCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="exception-collector",this.ctx=void 0,this.sendEvent=void 0,this.recentErrors=[],this.timerWrappers=[],this.reportJSExceptionHandler=function(){for(var b,c,d=[],e=0;e<arguments.length;e++)c=0>e||arguments.length<=e?void 0:arguments[e],c instanceof Error?!b&&(b=c):c&&c.message?!b&&(b=c):(0,_rumCore.isString)(c)&&c&&d.push(c);return b?void a.errorHandle(b,"reportJSException",!0):void(!d.length||a.errorHandle(d.join("\n"),"reportJSException",!0))},this.vueError=function(b,c){a.errorHandle(c,"Vue.onError")},this.uniError=function(b){a.errorHandle(b,"uni.onError")},this.onError=function(b){a.errorHandle(b,"onError")},this.onUnhandledRejection=function(b){if(b){var c=b.reason;if(c){var d=c.errMsg;// 对 Uniapp 内置错误进行解析
|
|
2
|
+
if(d&&(0,_rumCore.isString)(d)){c=new Error(d),c.name="",c.stack="";for(var e,f=["navigateTo","redirectTo","appLaunch","switchTab","getLocation","onLocationChange"],g=0,h=f;g<h.length;g++)if(e=h[g],d.startsWith(e)){c.name=e;break}c.name||(c.name=d.split(":")[0])}a.errorHandle(c,"onUnhandledRejection")}}},this.errorHandle=function(b,c,d){void 0===c&&(c=""),void 0===d&&(d=!1);var e,f,g,h,i,j;if(b instanceof Object){if(e=b.name,f=b.message,g=b.filename||b.fileName,h=b.stack,i=b.lineno||b.lineNumber,j=b.colno||b.columnNumber,b.error instanceof Error){var k=b.error;e=k.name,f=k.message,h=k.stack}// 兜底:wx.onError 回调入参为 { message, stack } 对象(无 name 字段),
|
|
3
|
+
// 尝试从堆栈反解,仍失败则用 'Error' 兜底,避免异常被静默丢弃
|
|
4
|
+
if(!e&&(0,_rumCore.isString)(f)){var l=a.getErrorByStack(h||f);l&&l.name&&l.message&&(e=l.name,f=l.message),e=e||"Error",h=h||f}}else if("string"==typeof b){h=b;var m=a.getErrorByStack(b);m&&(e=m.name,f=m.message)}!e||!f||d&&a.isDuplicated(e,f)||a.sendEvent({event_type:_rumCore.RumEventType.EXCEPTION,source:c,type:"error",name:e,message:f,file:g,stack:h,line:i,column:j,times:1})}}var b=a.prototype;return b.setup=function(a,b){this.ctx=a,this.sendEvent=b,this.hackOrigin()},b.hackOrigin=function(){var a=this,b=this.ctx.getConfig(),c=b.collectors,d=void 0===c?{}:c;if(!1!==d.jsError){// 各注册点独立防护:原先共用一个 try 块,App 端(Weex JS 引擎)global 无
|
|
5
|
+
// addEventListener 抛 TypeError,导致 unhandledrejection 与 uni.onError
|
|
6
|
+
// 注册被整体跳过(Vue 同步异常经 mixin 通道不受影响,与其余通道全静默的现象一致)
|
|
7
|
+
try{(0,_mixin.addEventListener)("onError",this.vueError)}catch(a){_rumCore.logger.warn("exception-collector","add vue onError listener failed",a)}if(this.safeAddEventListener("error",this.onError),this.safeAddEventListener("unhandledrejection",this.onUnhandledRejection),(0,_rumCore.isFunction)(_platform.sdk.onError))try{_platform.sdk.onError(this.uniError)}catch(a){_rumCore.logger.warn("exception-collector","uni.onError register failed",a)}// 无 window 级 unhandledrejection 的端(小程序等)退回 uni API 通道;
|
|
8
|
+
// H5 端已有 window 事件,跳过避免双通道重复上报
|
|
9
|
+
if(!(0,_rumCore.isFunction)(_platform.global2.addEventListener)&&(0,_rumCore.isFunction)(_platform.sdk.onUnhandledRejection))try{_platform.sdk.onUnhandledRejection(this.onUnhandledRejection)}catch(a){_rumCore.logger.warn("exception-collector","uni.onUnhandledRejection register failed",a)}this.hackAppRuntime()}!1!==d.consoleError&&(0,_rumCore.interceptFunction)(console,"error",function(b){a.errorHandle(b,"console.error")})}/**
|
|
10
|
+
* 仅在支持 addEventListener 的宿主(H5 window)上注册全局事件,
|
|
11
|
+
* App / 小程序环境安全跳过而非抛错中断后续注册
|
|
12
|
+
*/,b.safeAddEventListener=function(a,b){try{(0,_rumCore.isFunction)(_platform.global2.addEventListener)&&_platform.global2.addEventListener(a,b)}catch(b){_rumCore.logger.warn("exception-collector","add "+a+" listener failed",b)}}/**
|
|
13
|
+
* App 端(plus 存在)补充引擎级异常通道。
|
|
14
|
+
* uni-app App 端的 App.onError 仅由 Vue errorHandler 触发,异步回调(timers、
|
|
15
|
+
* 原生回调等 Vue 管理范围外)中的未捕获异常由引擎异常处理器进入原生
|
|
16
|
+
* reportJSException 后终结,不回流 uni.onError / global error 事件:
|
|
17
|
+
* 1. 劫持 reportJSException(runtime 注入的全局函数):引擎级未捕获异常的收口,
|
|
18
|
+
* 原生按全局名调用时可被截获(机会性通道,取决于 runtime 调用方式),原函数照常执行
|
|
19
|
+
* 2. 包装 setTimeout / setInterval / setImmediate:确定性捕获 timers 回调异常,
|
|
20
|
+
* 上报后原样 rethrow 保持引擎原有行为
|
|
21
|
+
* 3. plus.globalEvent 的 error / unhandledrejection:防御式注册,若端上派发则自动生效
|
|
22
|
+
*/,b.hackAppRuntime=function(){var a,b=this;try{// 无 plus(H5 / 小程序)时整体跳过,App 专属通道不注入
|
|
23
|
+
if("undefined"==typeof plus||!plus)return;plus.globalEvent&&(a=plus.globalEvent)}catch(a){return}if((0,_rumCore.interceptFunction)(_platform.global2,"reportJSException",this.reportJSExceptionHandler),this.wrapTimers(),a&&(0,_rumCore.isFunction)(a.addEventListener))try{a.addEventListener("error",function(a){try{b.errorHandle(a,"plus.globalEvent",!0)}catch(a){_rumCore.logger.warn("exception-collector","plus.globalEvent error failed",a)}}),a.addEventListener("unhandledrejection",function(a){if(a&&a.reason)try{b.errorHandle(a.reason,"plus.globalEvent",!0)}catch(a){_rumCore.logger.warn("exception-collector","plus.globalEvent unhandledrejection failed",a)}})}catch(a){_rumCore.logger.warn("exception-collector","plus.globalEvent register failed",a)}}/**
|
|
24
|
+
* reportJSException 收口处理:参数形态无公开契约(观察为函数名 + 异常文本,
|
|
25
|
+
* 部分实现含 instanceId / errCode),逐参数解析:Error 对象优先,字符串拼接后
|
|
26
|
+
* 经 getErrorByStack 解析;字符串解析失败遵循既定的丢弃策略
|
|
27
|
+
*/,b.wrapTimers=/**
|
|
28
|
+
* 包装 timers 全局函数:回调异常确定性捕获(App 端异步异常主场景),
|
|
29
|
+
* 上报后原样 rethrow,保持引擎对异常的原有处理路径
|
|
30
|
+
*/function(){for(var a,b=this,c=this,d=["setTimeout","setInterval","setImmediate"],e=function a(){var e,g=d[f];try{e=_platform.global2[g]}catch(a){return 0;// continue
|
|
31
|
+
}if(!(0,_rumCore.isFunction)(e)||e.__armsTimerWrapped)return 0;// continue
|
|
32
|
+
var h=function a(){for(var b=arguments.length,d=Array(b),f=0;f<b;f++)d[f]=arguments[f];var h=d[0];if(!(0,_rumCore.isFunction)(h))return e.apply(this,d);var i=function a(){try{return h.apply(this,arguments)}catch(a){try{c.errorHandle(a,g,!0)}catch(a){_rumCore.logger.warn("exception-collector","report timer error failed",a)}throw a}};return i.__armsOriginalCallback=h,d[0]=i,e.apply(this,d)};try{Object.defineProperty(h,"name",{value:g,configurable:!0})}catch(a){// 部分引擎 name 不可写,不影响包装
|
|
33
|
+
}h.toString=function(){return e.toString()},h.__armsTimerWrapped=!0;try{_platform.global2[g]=h,b.timerWrappers.push({name:g,original:e})}catch(a){_rumCore.logger.warn("exception-collector","wrap "+g+" failed",a)}},f=0;f<d.length;f++)a=e(),0===a}/**
|
|
34
|
+
* App 端多通道去重:timers 包装与 reportJSException 收口会对同一异常各触发
|
|
35
|
+
* 一次,窗口内 name+message 相同视为重复;环形清理 + 数量上限防泄漏
|
|
36
|
+
*/,b.isDuplicated=function c(a,b){for(var d=Date.now(),e=this.recentErrors;e.length&&d-e[0].time>DEDUPE_WINDOW;)e.shift();for(var f=a+"|"+b,g=0;g<e.length;g++)if(e[g].key===f)return!0;return e.push({key:f,time:d}),e.length>DEDUPE_MAX&&e.shift(),!1},b.getErrorByStack=/**
|
|
4
37
|
* 根据stack获取Error信息
|
|
5
38
|
* TODO: 增加基于Stack解析filename和lineNumber的能力
|
|
6
39
|
* @param stack
|
|
7
40
|
* @returns
|
|
8
|
-
*/function(a){void 0===a&&(a="");var
|
|
41
|
+
*/function b(a){void 0===a&&(a="");var c=a.split("\n");if(!(2>c.length)){// 优先直接扫描 'Name: message' 错误头部行,不依赖其与首帧的位置关系
|
|
42
|
+
// (V8 位于首行、微信 iOS/JSC 位于第三行,一次实现覆盖双端);类名前缀可选,兼容纯 'Error: msg'
|
|
43
|
+
for(var d,e=function b(a){var c=a.trim();return c.startsWith("at ")||/@.+:\d+:\d+/.test(c)||/@(\[native code\])?$/.test(c)},f=/^\s*([\w$]*(?:Error|Exception))\s*:\s*(.+)$/,g=0;g<c.length;g++)if(d=f.exec(c[g]),d)return{name:d[1],message:d[2]};// 后备:按 '首帧上一行即头部行' 的位置关系解析(覆盖自定义错误名等非 Error/Exception 后缀场景)
|
|
44
|
+
for(var h=1;h<c.length;h++)if(e(c[h])){var j=c[h-1];// 上一行也是堆栈帧(如 Safari 扩展的纯帧堆栈),说明无头部行,交由上层兜底
|
|
45
|
+
if(e(j))return;var k=j.indexOf(": ");return-1===k?{name:"",message:j}:{name:j.substring(0,k),message:j.substring(k+2)}}}// 兼容多引擎堆栈帧格式(参考 Sentry chrome/gecko StackLineParser):
|
|
46
|
+
// 1. V8/Chrome:'at fn (url:line:col)' / 'at url:line:col'
|
|
47
|
+
// 2. JavaScriptCore/Gecko(App 端/iOS):'fn@url:line:col' / '@url:line:col'
|
|
48
|
+
// 3. 无行列号帧:'forEach@[native code]' / '_onNativeTimer@'
|
|
49
|
+
},b.destroy=function a(){(0,_rumCore.restoreFunction)(console,"error"),(0,_rumCore.restoreFunction)(_platform.global2,"reportJSException");for(var b=0;b<this.timerWrappers.length;b++){var c=this.timerWrappers[b],d=c.name,e=c.original;try{_platform.global2[d]&&_platform.global2[d].__armsTimerWrapped&&(_platform.global2[d]=e)}catch(a){// 还原失败静默忽略
|
|
50
|
+
}}this.timerWrappers=[],this.recentErrors=[]},a}();// App 端 HTML5+ 运行时注入的全局对象,其余端(H5 / 小程序)不存在
|
|
51
|
+
// App 端多通道去重窗口:同一异常可能先被 timers 包装捕获并 rethrow,
|
|
52
|
+
// 随后又被 reportJSException 收口捕获,5s 内 name+message 相同视为同一事件
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ICollector, IContext, ITracingHeaders, RumEvent } from '@arms/rum-core';
|
|
2
|
-
import { IApiAttr, Options } from
|
|
2
|
+
import { IApiAttr, Options } from '../../utils/api';
|
|
3
3
|
export default class ApiCollector implements ICollector {
|
|
4
4
|
name: string;
|
|
5
5
|
ctx: IContext;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")),_rumCore=require("@arms/rum-core"),_platform=require("../../utils/platform"),_url=require("../../utils/url"),_base=require("../../utils/base"),_view=require("../../utils/view"),_api=require("../../utils/api"),ApiCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="api-collector",this.ctx=void 0,this.sendEvent=void 0,this.sendApi=/*#__PURE__*/function(){var b=(0,_asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function e(b,c,d){var f,g,h,i,j,k,l,m,n,o,p;return _regenerator["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(f=a.ctx.getConfig(),g=f.evaluateApi,h=c.statusCode,i=c.status,j=c.errMsg,k=c.errorMessage,l=c.message,!(0,_rumCore.isFunction)(g)){e.next=4;break}return e.prev=1,0===b.success&&(m=new Error("request error")),e.next=2,g(d,c,m);case 2:n=e.sent,b=(0,_extends2["default"])({},b,(0,_api.reviseApiAttr)(n)),e.next=4;break;case 3:e.prev=3,p=e["catch"](1);case 4:if(o=(0,_extends2["default"])({event_type:_rumCore.RumEventType.RESOURCE,type:"api",status_code:i||h,message:k||j||l,duration:(0,_base.getCurrentTime)()-b.timestamp,times:1},b),!(o.duration>_rumCore.ONE_DAY)){e.next=5;break}return e.abrupt("return");case 5:a.sendEvent(o);case 6:case"end":return e.stop()}},e,null,[[1,3]])}));return function(){return b.apply(this,arguments)}}()}var b=a.prototype;return b.setup=// origin = {
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")),_rumCore=require("@arms/rum-core"),_platform=require("../../utils/platform"),_url=require("../../utils/url"),_base=require("../../utils/base"),_view=require("../../utils/view"),_api=require("../../utils/api"),ApiCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="api-collector",this.ctx=void 0,this.sendEvent=void 0,this.sendApi=/*#__PURE__*/function(){var b=(0,_asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function e(b,c,d){var f,g,h,i,j,k,l,m,n,o,p;return _regenerator["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(f=a.ctx.getConfig(),g=f.evaluateApi,h=c.statusCode,i=c.status,j=c.errMsg,k=c.errorMessage,l=c.message,!(0,_rumCore.isFunction)(g)){e.next=4;break}return e.prev=1,0===b.success&&(m=new Error("request error")),e.next=2,g(d,c,m);case 2:n=e.sent,b=(0,_extends2["default"])({},b,(0,_api.reviseApiAttr)(n)),e.next=4;break;case 3:e.prev=3,p=e["catch"](1),_rumCore.logger.error("api-collector","evaluateApi failed",p);case 4:if(o=(0,_extends2["default"])({event_type:_rumCore.RumEventType.RESOURCE,type:"api",status_code:i||h,message:k||j||l,duration:(0,_base.getCurrentTime)()-b.timestamp,times:1},b),!(o.duration>_rumCore.ONE_DAY)){e.next=5;break}return e.abrupt("return");case 5:a.sendEvent(o);case 6:case"end":return e.stop()}},e,null,[[1,3]])}));return function(){return b.apply(this,arguments)}}()}var b=a.prototype;return b.setup=// origin = {
|
|
2
2
|
// request: sdk.request
|
|
3
3
|
// }
|
|
4
4
|
function(a,b){var c=a.getConfig(),d=c.collectors,e=void 0===d?{}:d;!1===e.api||(// Object.keys(this.origin).forEach((key) => this.hackRequest(key));
|
|
5
|
-
this.ctx=a,this.sendEvent=b,this.interceptorRequest())},b.interceptorRequest=function(){if((0,_rumCore.isFunction)(_platform.sdk.addInterceptor)){var a=this;_platform.sdk.addInterceptor("request",{
|
|
5
|
+
this.ctx=a,this.sendEvent=b,this.interceptorRequest())},b.interceptorRequest=function(){if((0,_rumCore.isFunction)(_platform.sdk.addInterceptor)){var a=this;_platform.sdk.addInterceptor("request",{// 用 logger.wrap 包装拦截回调:采集异常自动上报,同时隔离故障,避免影响业务请求
|
|
6
|
+
invoke:_rumCore.logger.wrap(function(b){a.rebuildRequestOptions(b)},"api-collector","intercept request failed")})}},b.injectTracing=function(a,b){var c,d=this.ctx.getConfig(),e=d.tracing,f=d.pid,g=d.version,h=void 0===g?"1.0.0":g,i=(0,_rumCore.parseTracingOptions)(e),j=i.enable,k=i.sample,l=i.propagatorTypes,m=i.allowedUrls,n=i.tracestate,o=i.baggage;if(j){var p=(0,_rumCore.find)(m,function(b){return(0,_rumCore.matchList)([b.match],a.url)});if(p){var q=p.propagatorTypes;0===q.length&&(q=l);// skywalking
|
|
6
7
|
var r=!1;q.includes("sw8")&&(q=["sw8"],r=!0);var s=r?(0,_rumCore.generateGUID)():(0,_rumCore.generateTraceId)(),t=r?(0,_rumCore.generateGUID)():(0,_rumCore.generateSpanId)(),u=(0,_rumCore.performDraw)(k),v=this.ctx.session.getUserId(),w=this.ctx.session.getSessionId(),x=void 0===n||n?"rum=v2&uniapp&"+f+"&"+w+"&"+v:void 0,y=void 0!==o&&o?"rum=v2,appType=uniapp,pid="+f+",sid="+w+",uid="+v:void 0,z=(0,_rumCore.makeTracingHeaders)(s,t,u,q,{tracestate:x,baggage:y,appId:f,appVersion:h,viewName:null===(c=a.view)||void 0===c?void 0:c.name,host:_platform.appName});u&&(a.trace_id=s,a.trace_data=JSON.stringify({spanId:t,sample:k,sampled:u,header:z})),b(z)}}}// hackRequest(key) {
|
|
7
8
|
// const self = this;
|
|
8
9
|
// if (!isFunction(sdk[key])) return;
|
|
@@ -25,8 +26,9 @@ var r=!1;q.includes("sw8")&&(q=["sw8"],r=!0);var s=r?(0,_rumCore.generateGUID)()
|
|
|
25
26
|
if((0,_url.isEndpoint)(this.ctx,c)||(0,_rumCore.urlMatch)(c))return a;// const newOptions = {
|
|
26
27
|
// ...options,
|
|
27
28
|
// };
|
|
28
|
-
var i={view:(0,_view.getCurView)(this.ctx),timestamp:h,url:c,name:this.getResourceName(c),method:a.method||"GET"};return this.injectTracing(i,function(b){a.header=(0,_extends2["default"])({},g,b)}),a.success=function(){i.success=1;for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];d&&d.apply(this,b)},a.fail=function(){i.success=0;for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];e&&e.apply(this,b)},a.complete=function(){for(var c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];var g=(0,_extends2["default"])({},d[0]);try{
|
|
29
|
-
|
|
29
|
+
var i={view:(0,_view.getCurView)(this.ctx),timestamp:h,url:c,name:this.getResourceName(c),method:a.method||"GET"};return this.injectTracing(i,function(b){a.header=(0,_extends2["default"])({},g,b)}),a.success=function(){i.success=1;for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];d&&d.apply(this,b)},a.fail=function(){i.success=0;for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];e&&e.apply(this,b)},a.complete=function(){for(var c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];var g=(0,_extends2["default"])({},d[0]);try{// 对齐 Browser 端 getResourceSuccessByCode:有 HTTP 状态码时按 [200, 300) 判定,
|
|
30
|
+
// 无状态码时保留原网络回调结果(success=1/fail=0)作为兜底
|
|
31
|
+
var h=g.statusCode;if(h){var j=+h;i.success=200<=j&&300>j?1:0}i.size=(0,_base.getStringSize)(JSON.stringify(g)),b.sendApi(i,g,a)}catch(a){_rumCore.logger.error("api-collector","process response failed",a)}f&&f.apply(this,d)},a},b.getResourceName=function(a){var b,c=this.ctx.getConfig(),d=c.parseResourceName;return b=(0,_rumCore.isFunction)(d)?d(a):(0,_url.getPathByURL)(a),b}// /**
|
|
30
32
|
// * 解析小程序的性能数据
|
|
31
33
|
// * 参考:https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
|
|
32
34
|
// * https://opendocs.alipay.com/mini/api/owycmh?pathHash=c91640f8
|
package/lib/collector/view/pv.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_rumCore=require("@arms/rum-core"),_view=require("../../utils/view"),_platform=require("../../utils/platform"),KEYS=["navigateTo","redirectTo","switchTab"],PvCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="pv-collector",this.ctx=void 0,this.sendEvent=void 0,this.timer=void 0,this.sendPv=function(){var b=(0,_view.getCurView)(a.ctx);b&&clearInterval(a.timer),b&&"_noReport"in b&&(delete b._noReport,a.sendEvent((0,_extends2["default"])({event_type:_rumCore.RumEventType.VIEW,type:"pv",loading_type:"initial_load"},b)))}}var b=a.prototype;return b.setup=function(a,b){var c=this;this.ctx=a,this.sendEvent=b,setTimeout(this.sendPv,100),this.timer=setInterval(function(){c.sendPv()},100),(0,_rumCore.isFunction)(_platform.sdk.addInterceptor)&&KEYS.forEach(function(a){_platform.sdk.addInterceptor(a,{success:c.sendPv})})},b.destroy=function(){},a}();
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_rumCore=require("@arms/rum-core"),_view=require("../../utils/view"),_platform=require("../../utils/platform"),KEYS=["navigateTo","redirectTo","switchTab"],PvCollector=exports["default"]=/*#__PURE__*/function(){function a(){var a=this;this.name="pv-collector",this.ctx=void 0,this.sendEvent=void 0,this.timer=void 0,this.sendPv=_rumCore.logger.wrap(function(){var b=(0,_view.getCurView)(a.ctx);b&&clearInterval(a.timer),b&&"_noReport"in b&&(delete b._noReport,a.sendEvent((0,_extends2["default"])({event_type:_rumCore.RumEventType.VIEW,type:"pv",loading_type:"initial_load"},b)))},"pv-collector","sendPv failed")}var b=a.prototype;return b.setup=function(a,b){var c=this;this.ctx=a,this.sendEvent=b,setTimeout(this.sendPv,100),this.timer=setInterval(function(){c.sendPv()},100),(0,_rumCore.isFunction)(_platform.sdk.addInterceptor)&&KEYS.forEach(function(a){_platform.sdk.addInterceptor(a,{success:c.sendPv})})},b.destroy=function(){},a}();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigManager, IContext, IConfiguration, ICacheConfiguration } from '@arms/rum-core';
|
|
2
|
+
import { IUniConfig } from './types/client';
|
|
3
|
+
export default class UniConfigManager extends ConfigManager {
|
|
4
|
+
private version;
|
|
5
|
+
fetchRemoteCfg(config: IConfiguration): Promise<unknown>;
|
|
6
|
+
private getV1Config;
|
|
7
|
+
private getV2Config;
|
|
8
|
+
getCacheConfig(): (ICacheConfiguration & Record<"pid", unknown>) | (ICacheConfiguration & Record<"endpoint", unknown>);
|
|
9
|
+
setCacheConfig(remoteCfg: ICacheConfiguration): void;
|
|
10
|
+
getRemoteConfigUrl(): string;
|
|
11
|
+
parseConfig(json: any): Partial<IUniConfig>;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkEnable(ctx: IContext, key: string, def?: boolean): boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports.checkEnable=checkEnable,exports["default"]=void 0;var _inheritsLoose2=_interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")),_rumCore=require("@arms/rum-core"),_platform=require("./utils/platform"),_url=require("./utils/url"),LOCAL_STORE_CONFIG_KEY="arms_rum2_local_config";function parseV2Config(a){var b,c={};c.enable=null===(b=a.enable)||void 0===b||b;// 处理 Session 配置
|
|
2
|
+
var d=a.session;if(d){var e,f,g={};g.sampling=null!==(e=d.sampling)&&void 0!==e?e:100,g.storage=null!==(f=d.storage)&&void 0!==f?f:"auto",c.sessionConfig=g}// 处理上报配置
|
|
3
|
+
var h=a.report;if(h){var i={};i.flushTime=h.flush_interval,i.maxEventCount=h.max_batch_count,c.reportConfig=i}// 处理链路追踪
|
|
4
|
+
var j=a.tracing;if(j){var k,l={};l.enable=null===(k=j.enable)||void 0===k||k;var m=[];(j.rules||[]).forEach(function(a){var b={enable:a.enable,tracestate:a.tracestate,baggage:a.baggage,propagatorTypes:a.protocols,sampling:a.sampling};return"{location.origin}"===a.match?void(l=Object.assign({},l,b)):void(b.match=(0,_rumCore.parseRule2Match)(a),m.push(b))}),l.allowedUrls=m,c.tracing=l}// 处理采集器
|
|
5
|
+
var n=a.collectors;if(n&&Array.isArray(n)&&0<n.length){var o={};n.forEach(function(a){var b=a.name;if(b){var c=Object.assign({},a),d=a.filters;0<(null===d||void 0===d?void 0:d.length)&&(c.filters=c.filters.map(function(a){return(0,_rumCore.parseRule2Match)(a)})),o[b]=c}}),c.collectors=Object.assign({},c.collectors,o)}return c}var UniConfigManager=exports["default"]=/*#__PURE__*/function(a){function b(){for(var b,c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];return b=a.call.apply(a,[this].concat(d))||this,b.version="v2",b}(0,_inheritsLoose2["default"])(b,a);var c=b.prototype;return c.fetchRemoteCfg=function(){var a=this.getRemoteConfigUrl();return a?a.includes(".rum.aliyuncs.com")?(this.version="v1",this.getV1Config(a)):this.getV2Config(a):void 0},c.getV1Config=function(a){return new Promise(function(b,c){_platform.sdk.request({url:a,method:"GET",success:function(a){b(a)},fail:function(a){c(a)}})})},c.getV2Config=function(a){var b=(0,_rumCore.getUrlParams)(a),c={instanceId:"",agentType:"rum_web_sdk",attributes:b,instanceConfigs:[{configType:"rum_web_config",version:1}],capabilities:2};return new Promise(function(b,d){_platform.sdk.request({url:a,method:"POST",data:JSON.stringify(c),header:{"Content-Type":"application/json","x-log-apiversion":"0.6.0"},success:function(a){b(a)},fail:function(a){d(a)}})})},c.getCacheConfig=function(){var a=(0,_platform.getStorageSync)(LOCAL_STORE_CONFIG_KEY);if(a){var b=this.currentConfig;try{var c=JSON.parse(a);if("pid"in c&&c.pid===b.pid||"endpoint"in c&&c.endpoint)return c.content=this.parseConfig(c.content),c}catch(a){_rumCore.logger.warn("configManager","Failed to read cache config",a)}}},c.setCacheConfig=function(a){var b=this.currentConfig,c=Object.assign({},a,{pid:b.pid,endpoint:b.endpoint});(0,_platform.setStorageSync)(LOCAL_STORE_CONFIG_KEY,JSON.stringify(c))},c.getRemoteConfigUrl=function(){var a=this.currentConfig,b=a.pid,c=a.remoteConfig,d=a.endpoint,e=c||{},f=e.url,g=e.region;if(f)return f;if(b){var h=b.split("@");return!h||2>h.length?void 0:"https://"+h[0]+"-sdk.rum.aliyuncs.com/config/"+(g||"cn-hangzhou")+"/"+h[1]+"?t="+Date.now()}var i=(0,_url.getURL)(d),j=(0,_rumCore.getUrlParams)(d);return i.protocol+"://"+i.hostname+"/agentconfig?workspace="+j.workspace+"&service="+j.service_id},c.parseConfig=function(a){try{var b=a.data||a,c=b.instanceConfigs[0].config;return"v2"===this.version?parseV2Config(JSON.parse(c)):a}catch(b){return a}},b}(_rumCore.ConfigManager);function checkEnable(a,b,c){var d;void 0===c&&(c=!0);var e=a.getConfig();if(!1===e.enable)return!1;var f=null===(d=e.collectors)||void 0===d?void 0:d[b];return(0,_rumCore.isBoolean)(f)?f:(0,_rumCore.isObject)(f)&&"enable"in f?f.enable:c}
|
package/lib/reporter/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _inheritsLoose2=_interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")),_rumCore=require("@arms/rum-core"),_platform=require("../utils/platform"),UniReporter=/*#__PURE__*/function(a){function b(){for(var b,c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];return b=a.call.apply(a,[this].concat(d))||this,b.name="uni-reporter",b}(0,_inheritsLoose2["default"])(b,a);var c=b.prototype;return c.init=function(){var a=this;(0,_rumCore.isFunction)(_platform.sdk.onAppHide)&&_platform.sdk.onAppHide(function(){a.flushEventQueue()})},c.request=function(a,b){var c=a.getConfig();(0,_platform.fixAttrs)(b).then(function(a){_platform.sdk.request({url:c.endpoint,method:"POST",header:{"Content-Type":"text/plain"},dataType:"text",data:JSON.stringify(a)})})["catch"](function(a){
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=void 0;var _inheritsLoose2=_interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")),_rumCore=require("@arms/rum-core"),_platform=require("../utils/platform"),UniReporter=/*#__PURE__*/function(a){function b(){for(var b,c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];return b=a.call.apply(a,[this].concat(d))||this,b.name="uni-reporter",b}(0,_inheritsLoose2["default"])(b,a);var c=b.prototype;return c.init=function(){var a=this;(0,_rumCore.isFunction)(_platform.sdk.onAppHide)&&_platform.sdk.onAppHide(function(){a.flushEventQueue()})},c.request=function(a,b){var c=a.getConfig();(0,_platform.fixAttrs)(b).then(function(a){_platform.sdk.request({url:c.endpoint,method:"POST",header:{"Content-Type":"text/plain"},dataType:"text",data:JSON.stringify(a)})})["catch"](function(a){_rumCore.logger.warn("uni-reporter","request failed",a)})},b}(_rumCore.Reporter),_default=exports["default"]=UniReporter;/**
|
|
2
2
|
* uni-app reporter
|
|
3
3
|
*/
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IMonitorReporter, MonitorEventBundle } from '@arms/rum-core';
|
|
2
|
+
/**
|
|
3
|
+
* uni-app 自监控上报器
|
|
4
|
+
* 将 Telemetry 采集的自监控数据编码为 protobuf,通过 uni.request 上报
|
|
5
|
+
*/
|
|
6
|
+
export declare class UniMonitorReporter implements IMonitorReporter {
|
|
7
|
+
private endpoint;
|
|
8
|
+
constructor(endpoint: string);
|
|
9
|
+
send(data: MonitorEventBundle[]): void;
|
|
10
|
+
private buildMonitorEndpoint;
|
|
11
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";exports.__esModule=!0,exports.UniMonitorReporter=void 0;var _rumCore=require("@arms/rum-core"),_platform=require("../utils/platform"),_url=require("../utils/url"),UniMonitorReporter=exports.UniMonitorReporter=/*#__PURE__*/function(){function a(a){this.endpoint=void 0,this.endpoint=this.buildMonitorEndpoint(a)}var b=a.prototype;return b.send=function(a){if(a&&0!==a.length)try{var b=(0,_rumCore.convertBundlesToLogGroup)(a);_platform.sdk.request({url:this.endpoint,method:"POST",header:{"Content-Type":"application/x-protobuf","x-log-apiversion":"0.6.0","x-log-compresstype":"","x-log-date":new Date().toUTCString()},// uni.request 支持发送 ArrayBuffer 二进制数据
|
|
2
|
+
data:b.buffer})}catch(a){_rumCore.logger.warn("monitor-reporter","Monitor data send failed",a)}},b.buildMonitorEndpoint=function(a){try{var b=(0,_url.getURL)(a);return b.protocol+"://"+b.host+"/rum/monitor"}catch(b){return a}},a}();/**
|
|
3
|
+
* uni-app 自监控上报器
|
|
4
|
+
* 将 Telemetry 采集的自监控数据编码为 protobuf,通过 uni.request 上报
|
|
5
|
+
*/
|
package/lib/shell.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Shell } from '@arms/rum-core';
|
|
2
|
-
import { IUniConfig, Vue } from
|
|
2
|
+
import { IUniConfig, Vue } from './types/client';
|
|
3
3
|
/**
|
|
4
4
|
* 对外导出 shell 层, 所有 shell 层模型的 API 设计约定:
|
|
5
5
|
* 1. API 命名空间按照 variables / functions / events 来组织
|
|
@@ -8,10 +8,12 @@ import { IUniConfig, Vue } from "./types/client";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class ArmsRum extends Shell {
|
|
10
10
|
version: string;
|
|
11
|
+
private configManager;
|
|
11
12
|
/**
|
|
12
13
|
* 初始化
|
|
13
14
|
*/
|
|
14
|
-
init(config: IUniConfig):
|
|
15
|
+
init(config: IUniConfig): Promise<Shell>;
|
|
16
|
+
getConfig(): import("@arms/rum-core").IConfiguration;
|
|
15
17
|
/**
|
|
16
18
|
* set config
|
|
17
19
|
*/
|
package/lib/shell.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=exports.ArmsRum=void 0;var
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports["default"]=exports.ArmsRum=void 0;var _inheritsLoose2=_interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")),_rumCore=require("@arms/rum-core"),_pv=_interopRequireDefault(require("./collector/view/pv")),_exception=_interopRequireDefault(require("./collector/exception")),_api=_interopRequireDefault(require("./collector/resource/api")),_action=_interopRequireDefault(require("./collector/action")),_defaultProcessor=_interopRequireDefault(require("./processor/default-processor")),_sessionProcessor=_interopRequireDefault(require("./processor/session-processor")),_reporter=_interopRequireDefault(require("./reporter")),_monitorReporter=require("./reporter/monitor-reporter"),_platform=require("./utils/platform"),_session=require("./utils/session"),_mixin=require("./utils/mixin"),_view=require("./utils/view"),_configManager=_interopRequireDefault(require("./configManager")),ArmsRum=exports.ArmsRum=/*#__PURE__*/function(a){function b(){for(var b,c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];return b=a.call.apply(a,[this].concat(d))||this,b.version=_platform.VERSION,b.configManager=void 0,b}(0,_inheritsLoose2["default"])(b,a);var c=b.prototype;return c.init=/**
|
|
2
2
|
* 初始化
|
|
3
|
-
*/function(a){a.vue&&
|
|
4
|
-
new _exception["default"],new _api["default"]
|
|
5
|
-
]),this.client.useProcessors([new _defaultProcessor["default"],new _sessionProcessor["default"]]),this.client.useReporter(new _reporter["default"]),this.client.init(a,new _session.RumSession);// 监听网络类型变化
|
|
3
|
+
*/function(a){var b=this;return this.configManager=new _configManager["default"],Promise.resolve().then(function(){return b.configManager.init(a)})["catch"](function(a){_rumCore.logger.warn("shell","configManager init error",a)}).then(function(){var a=b.configManager.getConfig();if(!1===a.enable)return b;a.vue&&b.setVue(a.vue),b.client.useCollectors([new _pv["default"],// new PerfCollector(),
|
|
4
|
+
new _exception["default"],new _api["default"],new _action["default"]]),b.client.useProcessors([new _defaultProcessor["default"],new _sessionProcessor["default"]]),b.client.useReporter(new _reporter["default"]),b.client.init(a,new _session.RumSession,b.configManager,new _monitorReporter.UniMonitorReporter(a.endpoint));// 监听网络类型变化
|
|
6
5
|
// getNetType(this.updateNetType);
|
|
7
|
-
var b
|
|
6
|
+
var c=b.client.getContext();return c.getViews=_view.getCurViews,(0,_rumCore.isFunction)(_platform.sdk.onAppHide)&&_platform.sdk.onAppHide(function(){var a;null===(a=_rumCore.Telemetry.get())||void 0===a?void 0:a.flush()}),b})},c.getConfig=function(){var a;return null===(a=this.configManager)||void 0===a?void 0:a.getConfig()}/**
|
|
8
7
|
* set config
|
|
9
|
-
*/,c.setConfig=function(){var a=this.
|
|
10
|
-
// import ActionCollector from './collector/action';
|
|
8
|
+
*/,c.setConfig=function(){var a=this.configManager;if(a)if(2===arguments.length){var b,c=a.getConfig();a.setConfig(Object.assign({},c,(b={},b[0>=arguments.length?void 0:arguments[0]]=1>=arguments.length?void 0:arguments[1],b)))}else a.setConfig(0>=arguments.length?void 0:arguments[0])},c.setVue=function(a){this.setConfig("vue",a),(0,_mixin.mixin)(a)},b}(_rumCore.Shell),_default=exports["default"]=new ArmsRum;// import PerfCollector from './collector/view/perf';
|
|
11
9
|
// import { getNetType } from "./utils/network";
|
|
12
10
|
/**
|
|
13
11
|
* 对外导出 shell 层, 所有 shell 层模型的 API 设计约定:
|
package/lib/utils/api.d.ts
CHANGED
package/lib/utils/api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var _rumCore=require("@arms/rum-core");exports.__esModule=!0,exports.reviseApiAttr=reviseApiAttr;function reviseApiAttr(a){if(a&&(0,_rumCore.isObject)(a)){var b={};return(0,_rumCore.isString)(a.name)&&(b.name=a.name.substring(0,1e3)),(0,_rumCore.isString)(a.message)&&(b.message=a.message.substring(0,1e3)),
|
|
1
|
+
"use strict";var _rumCore=require("@arms/rum-core");exports.__esModule=!0,exports.reviseApiAttr=reviseApiAttr;function reviseApiAttr(a){if(a&&(0,_rumCore.isObject)(a)){var b={};return(0,_rumCore.isString)(a.name)&&(b.name=a.name.substring(0,1e3)),(0,_rumCore.isString)(a.message)&&(b.message=a.message.substring(0,1e3)),(0,_rumCore.isNumber)(a.success)&&-1<=a.success&&1>=a.success&&(b.success=a.success),(0,_rumCore.isNumber)(a.duration)&&0<=a.duration&&(b.duration=a.duration),(0,_rumCore.isString)(a.status_code)&&(b.status_code=a.status_code.substring(0,100)),(0,_rumCore.isNumber)(a.status_code)&&(b.status_code=a.status_code),(0,_rumCore.isString)(a.snapshots)&&(b.snapshots=a.snapshots.substring(0,5e3)),b}}
|
package/lib/utils/mixin.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Vue } from
|
|
1
|
+
import type { Vue } from '../types/client';
|
|
2
2
|
type Callback = (that: any, ev: any) => void;
|
|
3
3
|
/** Vue 2 传入构造函数;Vue 3 传入 createApp() 的 app 实例 */
|
|
4
|
-
export type VueRuntimeKind =
|
|
4
|
+
export type VueRuntimeKind = 'vue2' | 'vue3';
|
|
5
5
|
/** 根据运行时形态区分:Vue 2 为函数(构造函数),Vue 3 app 为对象 */
|
|
6
6
|
export declare function getVueRuntimeKind(vue: unknown): VueRuntimeKind | null;
|
|
7
7
|
export declare function mixin(vue: Vue): void;
|
package/lib/utils/mixin.js
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
"use strict";exports.__esModule=!0,exports.addEventListener=addEventListener,exports.getVueRuntimeKind=getVueRuntimeKind,exports.mixin=mixin,exports.removeEventListener=removeEventListener;var vueCache;/** Vue 2 传入构造函数;Vue 3 传入 createApp() 的 app 实例 *//** 根据运行时形态区分:Vue 2 为函数(构造函数),Vue 3 app 为对象 */function getVueRuntimeKind(a){if(null==a)return null;return"function"==typeof a.mixin?"function"==typeof a?"vue2":"object"==typeof a?"vue3":null:null}/** 会合并进 Vue.mixin 的生命周期键(与 listeners 中需单独处理的键分开) */var MIXIN_HOOK_KEYS=["onLaunch","onLoad","onShow","beforeCreate","mounted"],listeners={onError:[]};MIXIN_HOOK_KEYS.forEach(function(a){listeners[a]=[]});function invokeListeners(a,b,c){var d=listeners[a];if(null!==d&&void 0!==d&&d.length)for(var e=0;e<d.length;e++)try{d[e](b,c)}catch(b){
|
|
2
|
-
|
|
1
|
+
"use strict";exports.__esModule=!0,exports.addEventListener=addEventListener,exports.getVueRuntimeKind=getVueRuntimeKind,exports.mixin=mixin,exports.removeEventListener=removeEventListener;var vueCache,_rumCore=require("@arms/rum-core");/** Vue 2 传入构造函数;Vue 3 传入 createApp() 的 app 实例 *//** 根据运行时形态区分:Vue 2 为函数(构造函数),Vue 3 app 为对象 */function getVueRuntimeKind(a){if(null==a)return null;return"function"==typeof a.mixin?"function"==typeof a?"vue2":"object"==typeof a?"vue3":null:null}/** 会合并进 Vue.mixin 的生命周期键(与 listeners 中需单独处理的键分开) */var MIXIN_HOOK_KEYS=["onLaunch","onLoad","onShow","beforeCreate","mounted"],listeners={onError:[]};MIXIN_HOOK_KEYS.forEach(function(a){listeners[a]=[]});function invokeListeners(a,b,c){var d=listeners[a];if(null!==d&&void 0!==d&&d.length)for(var e=0;e<d.length;e++)try{d[e](b,c)}catch(b){_rumCore.logger.warn("vue-mixin","vue listener failed",b,{hook:a})}}/** tap/click 事件源:识别 uni-app 事件对象(有 type 且带 currentTarget/target) */var ACTION_EVENT_TYPES=["tap","click"];function isActionEvent(a){return!!a&&"object"==typeof a&&-1!==ACTION_EVENT_TYPES.indexOf(a.type)&&(null!=a.currentTarget||null!=a.target)}/**
|
|
2
|
+
* 拦截组件 methods,为 tap/click 建立事件源。
|
|
3
|
+
* $options.methods 为组件定义共享对象,包装一次即可(__armsActionWrapped 去重);
|
|
4
|
+
* 包装函数在被事件触发时派发 'action',再执行原方法,保持原行为与返回值。
|
|
5
|
+
*/function wrapInstanceMethods(a){// 无 'action' 监听(采集器未启用)时不包装,零开销
|
|
6
|
+
if(listeners.action&&listeners.action.length){var b=a&&a.$options&&a.$options.methods;if(b)for(var c=Object.keys(b),d=function a(){var d=c[e],f=b[d];if("function"!=typeof f||f.__armsActionWrapped)return 1;// continue
|
|
7
|
+
var g=function a(){var b=arguments[0];return isActionEvent(b)&&invokeListeners("action",this,b),f.apply(this,arguments)};g.__armsActionWrapped=!0,b[d]=g},e=0;e<c.length;e++)d()}}function createMixinOptions(a){function d(a,b,c){invokeListeners("onError",this,{error:a,instance:b,info:c})}// Vue 2.5+ / Vue 3:后代组件错误走 onErrorCaptured,再转给 onError 监听(不用 config.errorHandler)
|
|
8
|
+
for(var e={},f=function a(){var b=MIXIN_HOOK_KEYS[g];e[b]=function(a){invokeListeners(b,this,a)}},g=0;g<MIXIN_HOOK_KEYS.length;g++)f();// beforeCreate 早于 Vue initMethods,此时拦截 methods 可让绑定到实例的即为包装版本
|
|
9
|
+
var b=e.beforeCreate;return e.beforeCreate=function(a){b.call(this,a),wrapInstanceMethods(this)},"vue2"===a?Object.defineProperty(vueCache.config,"errorHandler",{get:function a(){var e=this;return function(f,a,b){d(f,a,b),e.__errorHandler&&e.__errorHandler(f,a,b)}},set:function b(a){this.__errorHandler=a}}):Object.defineProperty(vueCache.config,"onErrorCaptured",{get:function a(){var e=this;return function(f,a,b){d(f,a,b),e.__onErrorCaptured&&e.__onErrorCaptured(f,a,b)}},set:function b(a){this.__onErrorCaptured=a}}),e}function mixin(a){if(!vueCache){vueCache=a;var b=getVueRuntimeKind(a);if(b)try{a.mixin(createMixinOptions(b))}catch(a){_rumCore.logger.error("vue-mixin","vue.mixin failed",a)}}}function addEventListener(a,b){a in listeners||(listeners[a]=[]),listeners[a].push(b)}function removeEventListener(a,b){if(a in listeners&&b){var c=listeners[a],d=c.indexOf(b);return c.splice(d,1),!0}return!1}
|
package/lib/utils/platform.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RumEventBundle } from
|
|
1
|
+
import { RumEventBundle } from '@arms/rum-core';
|
|
2
2
|
export declare const global2: any;
|
|
3
3
|
export declare const VERSION: string;
|
|
4
4
|
interface CommonOption {
|
|
@@ -14,7 +14,9 @@ interface SDK {
|
|
|
14
14
|
setStorageSync: (key: any, data?: string) => void;
|
|
15
15
|
onError: (listener: Function) => void;
|
|
16
16
|
onPageNotFound: (listener: Function) => void;
|
|
17
|
-
|
|
17
|
+
onUnhandledRejection?: (listener: Function) => void;
|
|
18
|
+
offError?: (listener: Function) => void;
|
|
19
|
+
offUnhandledRejection?: (listener: Function) => void;
|
|
18
20
|
navigateTo: (options: any) => void;
|
|
19
21
|
redirectTo: (options: any) => void;
|
|
20
22
|
switchTab: (options: any) => void;
|
package/lib/utils/platform.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports.fixAttrs=exports.appName=exports.VERSION=void 0,exports.getNetType=getNetType,exports.getPerformance=getPerformance,exports.getStorageSync=getStorageSync,exports.sdk=exports.global2=void 0,exports.setStorageSync=setStorageSync;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")),_rumCore=require("@arms/rum-core"),global2=exports.global2=global||window,VERSION=exports.VERSION='npm-0.1.
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=!0,exports.fixAttrs=exports.appName=exports.VERSION=void 0,exports.getNetType=getNetType,exports.getPerformance=getPerformance,exports.getStorageSync=getStorageSync,exports.sdk=exports.global2=void 0,exports.setStorageSync=setStorageSync;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends")),_asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")),_rumCore=require("@arms/rum-core"),global2=exports.global2=global||window,VERSION=exports.VERSION='npm-0.1.5',sdk=exports.sdk=uni,appName=exports.appName="uniapp";// export {
|
|
2
2
|
// // sdk: global.uni,
|
|
3
3
|
// appName: 'uniapp',
|
|
4
4
|
// }
|
package/lib/utils/session.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IContext, IRumSession, RumEvent, SessionConfig } from
|
|
1
|
+
import { IContext, IRumSession, RumEvent, SessionConfig } from '@arms/rum-core';
|
|
2
2
|
interface SessionInfo {
|
|
3
3
|
sessionId: string;
|
|
4
4
|
sampled: boolean;
|
|
@@ -8,6 +8,8 @@ interface SessionInfo {
|
|
|
8
8
|
}
|
|
9
9
|
export declare class RumSession implements IRumSession {
|
|
10
10
|
ctx: IContext;
|
|
11
|
+
appType: string;
|
|
12
|
+
sdkVersion: string;
|
|
11
13
|
sessionConfig: SessionConfig;
|
|
12
14
|
init(ctx: IContext): void;
|
|
13
15
|
getSessionId(): string;
|
package/lib/utils/session.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";exports.__esModule=!0,exports.RumSession=void 0;var _rumCore=require("@arms/rum-core"),_base=require("./base"),_view=require("./view"),_platform=require("./platform"),USER_ID="_arms_uid",RUM_SESSION="_arms_session",RumSession=exports.RumSession=/*#__PURE__*/function(){function a(){this.ctx=void 0,this.sessionConfig=void 0}var b=a.prototype;return b.init=function(a){var b;this.ctx=a,this.sessionConfig=this.fixSessionConfig(null===(b=a.
|
|
1
|
+
"use strict";exports.__esModule=!0,exports.RumSession=void 0;var _rumCore=require("@arms/rum-core"),_base=require("./base"),_view=require("./view"),_platform=require("./platform"),USER_ID="_arms_uid",RUM_SESSION="_arms_session",RumSession=exports.RumSession=/*#__PURE__*/function(){function a(){this.ctx=void 0,this.appType="uniapp",this.sdkVersion=_platform.VERSION,this.sessionConfig=void 0}var b=a.prototype;return b.init=function(a){var b;this.ctx=a,this.sessionConfig=this.fixSessionConfig(null===(b=a.getConfig())||void 0===b?void 0:b.sessionConfig)},b.getSessionId=function(){return this.getSessionInfo().sessionId},b.getSampled=function(){return this.getSessionInfo().sampled},b.checkSession=function(a){var b=this.sessionConfig,c=b.overtime,d=b.maxDuration,e=(0,_base.getCurrentTime)();return!(a.startTime+d<e||a.lastTime+c<e)},b.updateSession=function(){var a=this.getSessionInfo();if(!a.isNew){var b=a.startTime,c=(0,_base.getCurrentTime)(),d=a.sampled?1:0;(0,_platform.setStorageSync)(RUM_SESSION,a.sessionId+"-"+d+"-"+b+"-"+c)}},b.getSessionInfo=function(){var a=((0,_platform.getStorageSync)(RUM_SESSION)||"").split("-"),b=a[0],c=a[1],d=a[2],e=a[3],f={sessionId:b,sampled:"0"!==c,startTime:parseInt(d||"")||0,lastTime:parseInt(e||"")||0};return this.checkSession(f)||(f=this.resetSession()),f},b.getEventId=function(){return(0,_rumCore.generateEventId)(this.getSessionId())},b.getViewId=function(){return this.getUUID()},b.getUserId=function(){var a=(0,_platform.getStorageSync)(USER_ID);return a&&0===a.indexOf("user_")&&(a=""),a||(a="uid_"+(0,_rumCore.generateSpanId)(16,36),(0,_platform.setStorageSync)(USER_ID,a)),a},b.resetSession=function(){var a=this.sessionConfig.sampling,b=this.getUUID(),c=(0,_base.getCurrentTime)(),d=(0,_rumCore.performDraw)(a),e=b+"-"+(d?1:0)+"-"+c+"-"+c;return(0,_platform.setStorageSync)(RUM_SESSION,e),{sessionId:b,sampled:d,startTime:c,lastTime:c,isNew:!0}},b.getUUID=function(){return(0,_rumCore.generateGUID)().replace(/-/g,"")},b.fixSessionConfig=function(a){void 0===a&&(a={});var b=a,c=b.sampleRate,d=b.sampling,e=b.maxDuration,f=b.overtime;// 优先使用 sampling(0-100),若未配置则从旧字段 sampleRate(0-1)迁移
|
|
2
2
|
return(!(0,_rumCore.isNumber)(d)||0>d||100<d)&&((0,_rumCore.isNumber)(c)&&0<=c&&1>=c?d=100*c:d=100),(!(0,_rumCore.isNumber)(e)||e<4*_rumCore.ONE_HOUR||e>_rumCore.ONE_DAY)&&(e=_rumCore.ONE_DAY),(!(0,_rumCore.isNumber)(f)||f>_rumCore.ONE_HOUR||f<10*_rumCore.ONE_MINUTE)&&(f=30*_rumCore.ONE_MINUTE),{sampling:d,maxDuration:e,overtime:f}},b.getBaseEvent=function(){return{timestamp:(0,_base.getCurrentTime)(),session_id:this.getSessionId(),event_id:this.getEventId(),view:this.ctx?(0,_view.getCurView)(this.ctx):void 0,times:1}},a}();// 存储userID的键名
|
|
3
3
|
// 存储session
|
package/lib/utils/view.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";exports.__esModule=!0,exports.getCurView=getCurView,exports.getCurViews=getCurViews,exports.getCurrentPage=getCurrentPage;var _rumCore=require("@arms/rum-core"),PAGE_KEY="__rum_view";/**
|
|
2
2
|
* 获取当前 page
|
|
3
3
|
* @returns
|
|
4
|
-
*/function getCurrentPage(){if("function"==typeof getCurrentPages)try{var a=getCurrentPages()||[];return a[a.length-1]}catch(a){
|
|
5
|
-
}}/**
|
|
4
|
+
*/function getCurrentPage(){if("function"==typeof getCurrentPages)try{var a=getCurrentPages()||[];return a[a.length-1]}catch(a){_rumCore.logger.warn("view","getCurrentPage failed",a)}}/**
|
|
6
5
|
* 获取当前 view
|
|
7
6
|
* @param ctx
|
|
8
7
|
* @returns
|
|
@@ -10,4 +9,4 @@
|
|
|
10
9
|
* 获取当前 view
|
|
11
10
|
* @param ctx
|
|
12
11
|
* @returns
|
|
13
|
-
*/function getCurViews(){var a=[];if("function"==typeof getCurrentPages)try{(getCurrentPages()||[]).forEach(function(b){PAGE_KEY in b&&a.push(b[PAGE_KEY])})}catch(a){}return a}
|
|
12
|
+
*/function getCurViews(){var a=[];if("function"==typeof getCurrentPages)try{(getCurrentPages()||[]).forEach(function(b){PAGE_KEY in b&&a.push(b[PAGE_KEY])})}catch(a){_rumCore.logger.warn("view","getCurViews failed",a)}return a}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arms/rum-uniapp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "arms rum javascript sdk for uniapp native",
|
|
5
5
|
"author": "guangli.fj <guangli.fj@alibaba-inc.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"prepublishOnly": "npm run build"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@arms/rum-core": "0.1.
|
|
28
|
+
"@arms/rum-core": "0.1.11"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"typescript": "^4.9.4"
|