@arms/rum-core 0.1.8 → 0.1.10
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/es/model/client.js +3 -1
- package/es/model/configManager.d.ts +1 -1
- package/es/model/configManager.js +43 -96
- package/es/model/reporter.js +24 -49
- package/es/model/shell.d.ts +22 -0
- package/es/model/shell.js +77 -26
- package/es/monitor/logger.d.ts +6 -1
- package/es/monitor/logger.js +1 -1
- package/es/monitor/telemetry.js +7 -8
- package/es/types/shell.d.ts +9 -0
- package/es/utils/base.js +7 -0
- package/lib/index.js +1 -1
- package/lib/model/client.js +4 -2
- package/lib/model/configManager.d.ts +1 -1
- package/lib/model/configManager.js +43 -97
- package/lib/model/reporter.js +24 -50
- package/lib/model/shell.d.ts +22 -0
- package/lib/model/shell.js +79 -28
- package/lib/monitor/logger.d.ts +6 -1
- package/lib/monitor/logger.js +1 -1
- package/lib/monitor/telemetry.js +7 -9
- package/lib/types/shell.d.ts +9 -0
- package/lib/utils/base.js +7 -0
- package/package.json +1 -4
package/es/model/client.js
CHANGED
|
@@ -75,7 +75,9 @@ var Client = /*#__PURE__*/function () {
|
|
|
75
75
|
}
|
|
76
76
|
reporter.report(ctx, options);
|
|
77
77
|
});
|
|
78
|
-
|
|
78
|
+
|
|
79
|
+
// 采集器可全部经 Shell 扩展通道注册,此处允许为空
|
|
80
|
+
(collectors || []).forEach(function (collector) {
|
|
79
81
|
collector.setup(ctx, _this2.sendEvent);
|
|
80
82
|
});
|
|
81
83
|
};
|
|
@@ -21,7 +21,7 @@ export declare abstract class ConfigManager implements IConfigManager {
|
|
|
21
21
|
* 更新配置
|
|
22
22
|
* @param config 新配置
|
|
23
23
|
*/
|
|
24
|
-
setConfig(config: Partial<IConfiguration>):
|
|
24
|
+
setConfig(config: Partial<IConfiguration>): void;
|
|
25
25
|
/**
|
|
26
26
|
* 检查缓存是否有效
|
|
27
27
|
* @param cachedData 缓存数据
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
|
-
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
1
|
function parseRemoteConfig(config) {
|
|
5
2
|
var remoteConfig = config.remoteConfig || {};
|
|
6
3
|
var enable = false;
|
|
@@ -33,75 +30,46 @@ export var ConfigManager = /*#__PURE__*/function () {
|
|
|
33
30
|
* 初始化配置管理器
|
|
34
31
|
* @param config 初始配置
|
|
35
32
|
*/
|
|
36
|
-
_proto.init =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var _this = this;
|
|
41
|
-
var remoteConfig, cacheConfig, asyncConfigPromise;
|
|
42
|
-
return _regeneratorRuntime.wrap(function (_context) {
|
|
43
|
-
while (1) switch (_context.prev = _context.next) {
|
|
44
|
-
case 0:
|
|
45
|
-
if (!this.initialized) {
|
|
46
|
-
_context.next = 1;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
return _context.abrupt("return");
|
|
50
|
-
case 1:
|
|
51
|
-
this.currentConfig = _extends({}, config);
|
|
52
|
-
this.initialized = true;
|
|
53
|
-
remoteConfig = parseRemoteConfig(config);
|
|
54
|
-
this.currentConfig.remoteConfig = remoteConfig;
|
|
55
|
-
if (remoteConfig.enable) {
|
|
56
|
-
_context.next = 2;
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
return _context.abrupt("return");
|
|
60
|
-
case 2:
|
|
61
|
-
_context.next = 3;
|
|
62
|
-
return this.getCacheConfig();
|
|
63
|
-
case 3:
|
|
64
|
-
cacheConfig = _context.sent;
|
|
65
|
-
if (cacheConfig && cacheConfig.content) {
|
|
66
|
-
this.currentConfig = this.mergeRemoteCfg(cacheConfig.content);
|
|
67
|
-
}
|
|
68
|
-
if (!this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
|
|
69
|
-
_context.next = 4;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
return _context.abrupt("return");
|
|
73
|
-
case 4:
|
|
74
|
-
asyncConfigPromise = this.fetchRemoteCfg(this.currentConfig).then(function (resp) {
|
|
75
|
-
if (!resp) return;
|
|
76
|
-
var asyncRemoteConfig = _this.parseConfig(resp);
|
|
77
|
-
_this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
|
|
78
|
-
_this.setCacheConfig({
|
|
79
|
-
timestamp: Date.now(),
|
|
80
|
-
content: resp
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
if (!(remoteConfig.mode === 'remote-first')) {
|
|
84
|
-
_context.next = 5;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
_context.next = 5;
|
|
88
|
-
return asyncConfigPromise;
|
|
89
|
-
case 5:
|
|
90
|
-
case "end":
|
|
91
|
-
return _context.stop();
|
|
92
|
-
}
|
|
93
|
-
}, _callee, this);
|
|
94
|
-
}));
|
|
95
|
-
function init(_x) {
|
|
96
|
-
return _init.apply(this, arguments);
|
|
33
|
+
_proto.init = function init(config) {
|
|
34
|
+
var _this = this;
|
|
35
|
+
if (this.initialized) {
|
|
36
|
+
return Promise.resolve();
|
|
97
37
|
}
|
|
98
|
-
|
|
99
|
-
|
|
38
|
+
this.currentConfig = Object.assign({}, config);
|
|
39
|
+
this.initialized = true;
|
|
40
|
+
var remoteConfig = parseRemoteConfig(config);
|
|
41
|
+
this.currentConfig.remoteConfig = remoteConfig;
|
|
42
|
+
if (!remoteConfig.enable) {
|
|
43
|
+
return Promise.resolve();
|
|
44
|
+
}
|
|
45
|
+
return Promise.resolve(this.getCacheConfig()).then(function (cacheConfig) {
|
|
46
|
+
if (cacheConfig && cacheConfig.content) {
|
|
47
|
+
_this.currentConfig = _this.mergeRemoteCfg(cacheConfig.content);
|
|
48
|
+
}
|
|
49
|
+
if (_this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
|
|
50
|
+
// 配置有效期内直接返回,不抓取远端配置
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var asyncConfigPromise = _this.fetchRemoteCfg(_this.currentConfig).then(function (resp) {
|
|
54
|
+
if (!resp) return;
|
|
55
|
+
var asyncRemoteConfig = _this.parseConfig(resp);
|
|
56
|
+
_this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
|
|
57
|
+
_this.setCacheConfig({
|
|
58
|
+
timestamp: Date.now(),
|
|
59
|
+
content: resp
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
if (remoteConfig.mode === 'remote-first') {
|
|
63
|
+
// 远端配置优先情况下,要等待获取完成后返回
|
|
64
|
+
return asyncConfigPromise;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
100
69
|
/**
|
|
101
70
|
* 获取配置
|
|
102
71
|
* @returns 配置数据
|
|
103
|
-
|
|
104
|
-
;
|
|
72
|
+
*/;
|
|
105
73
|
_proto.getConfig = function getConfig() {
|
|
106
74
|
if (!this.currentConfig) {
|
|
107
75
|
throw new Error('Config not initialized');
|
|
@@ -113,37 +81,16 @@ export var ConfigManager = /*#__PURE__*/function () {
|
|
|
113
81
|
* 更新配置
|
|
114
82
|
* @param config 新配置
|
|
115
83
|
*/;
|
|
116
|
-
_proto.setConfig =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
while (1) switch (_context2.prev = _context2.next) {
|
|
122
|
-
case 0:
|
|
123
|
-
if (this.currentConfig) {
|
|
124
|
-
_context2.next = 1;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
return _context2.abrupt("return");
|
|
128
|
-
case 1:
|
|
129
|
-
this.currentConfig = _extends({}, this.currentConfig, config);
|
|
130
|
-
case 2:
|
|
131
|
-
case "end":
|
|
132
|
-
return _context2.stop();
|
|
133
|
-
}
|
|
134
|
-
}, _callee2, this);
|
|
135
|
-
}));
|
|
136
|
-
function setConfig(_x2) {
|
|
137
|
-
return _setConfig.apply(this, arguments);
|
|
138
|
-
}
|
|
139
|
-
return setConfig;
|
|
140
|
-
}()
|
|
84
|
+
_proto.setConfig = function setConfig(config) {
|
|
85
|
+
if (!this.currentConfig) return;
|
|
86
|
+
this.currentConfig = Object.assign({}, this.currentConfig, config);
|
|
87
|
+
}
|
|
88
|
+
|
|
141
89
|
/**
|
|
142
90
|
* 检查缓存是否有效
|
|
143
91
|
* @param cachedData 缓存数据
|
|
144
92
|
* @param cacheTimeout 缓存超时时间
|
|
145
|
-
|
|
146
|
-
;
|
|
93
|
+
*/;
|
|
147
94
|
_proto.isCacheValid = function isCacheValid(cachedData, cacheTimeout) {
|
|
148
95
|
if (!cachedData || !cachedData.timestamp) {
|
|
149
96
|
return false;
|
|
@@ -165,7 +112,7 @@ export var ConfigManager = /*#__PURE__*/function () {
|
|
|
165
112
|
remoteConfig = _this$currentConfig.remoteConfig,
|
|
166
113
|
beforeReport = _this$currentConfig.beforeReport,
|
|
167
114
|
properties = _this$currentConfig.properties;
|
|
168
|
-
return
|
|
115
|
+
return Object.assign({}, this.currentConfig, remoteCfg, {
|
|
169
116
|
pid: pid,
|
|
170
117
|
app: app,
|
|
171
118
|
endpoint: endpoint,
|
package/es/model/reporter.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
-
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
1
|
import { logger } from '../monitor/logger';
|
|
5
2
|
import { RumEventType } from '../types/rum-event';
|
|
6
3
|
import { getErrorID } from '../utils/exception';
|
|
@@ -207,7 +204,7 @@ var Reporter = /*#__PURE__*/function () {
|
|
|
207
204
|
*/;
|
|
208
205
|
_proto.buildAndSend = function buildAndSend(ctx, config, session, sessionId, events, view) {
|
|
209
206
|
var extend = getUrlParams(config.endpoint);
|
|
210
|
-
var bundle =
|
|
207
|
+
var bundle = Object.assign({
|
|
211
208
|
app: {
|
|
212
209
|
id: config.pid,
|
|
213
210
|
env: config.env || 'prod',
|
|
@@ -246,54 +243,32 @@ var Reporter = /*#__PURE__*/function () {
|
|
|
246
243
|
}
|
|
247
244
|
this.tryRequest(bundle);
|
|
248
245
|
};
|
|
249
|
-
_proto.tryRequest =
|
|
250
|
-
var
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return _regeneratorRuntime.wrap(function (_context) {
|
|
257
|
-
while (1) switch (_context.prev = _context.next) {
|
|
258
|
-
case 0:
|
|
259
|
-
if (retry === void 0) {
|
|
260
|
-
retry = 0;
|
|
261
|
-
}
|
|
262
|
-
reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
|
|
263
|
-
maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
|
|
264
|
-
retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
|
|
265
|
-
_context.prev = 1;
|
|
266
|
-
bundle._retry = retry;
|
|
267
|
-
_context.next = 2;
|
|
268
|
-
return this.request(this.ctx, bundle);
|
|
269
|
-
case 2:
|
|
270
|
-
_context.next = 4;
|
|
271
|
-
break;
|
|
272
|
-
case 3:
|
|
273
|
-
_context.prev = 3;
|
|
274
|
-
_t = _context["catch"](1);
|
|
275
|
-
if (retry < maxRetryCount - 1) {
|
|
276
|
-
setTimeout(function () {
|
|
277
|
-
return _this2.tryRequest(bundle, retry + 1);
|
|
278
|
-
}, retryDelay);
|
|
279
|
-
} else {
|
|
280
|
-
logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", _t);
|
|
281
|
-
}
|
|
282
|
-
case 4:
|
|
283
|
-
case "end":
|
|
284
|
-
return _context.stop();
|
|
285
|
-
}
|
|
286
|
-
}, _callee, this, [[1, 3]]);
|
|
287
|
-
}));
|
|
288
|
-
function tryRequest(_x, _x2) {
|
|
289
|
-
return _tryRequest.apply(this, arguments);
|
|
246
|
+
_proto.tryRequest = function tryRequest(bundle, retry) {
|
|
247
|
+
var _this$ctx$getConfig,
|
|
248
|
+
_reportConfig$maxRetr,
|
|
249
|
+
_reportConfig$retryDe,
|
|
250
|
+
_this2 = this;
|
|
251
|
+
if (retry === void 0) {
|
|
252
|
+
retry = 0;
|
|
290
253
|
}
|
|
291
|
-
|
|
292
|
-
|
|
254
|
+
var reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
|
|
255
|
+
var maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
|
|
256
|
+
var retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
|
|
257
|
+
bundle._retry = retry;
|
|
258
|
+
Promise.resolve(this.request(this.ctx, bundle))["catch"](function (e) {
|
|
259
|
+
if (retry < maxRetryCount - 1) {
|
|
260
|
+
setTimeout(function () {
|
|
261
|
+
return _this2.tryRequest(bundle, retry + 1);
|
|
262
|
+
}, retryDelay);
|
|
263
|
+
} else {
|
|
264
|
+
logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", e);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
293
269
|
/**
|
|
294
270
|
* 接口请求由各平台 sdk reporter 实现
|
|
295
|
-
|
|
296
|
-
;
|
|
271
|
+
*/;
|
|
297
272
|
/**
|
|
298
273
|
* 初始化时
|
|
299
274
|
*/
|
package/es/model/shell.d.ts
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
import { IClient, IConfiguration } from '../types/client';
|
|
2
|
+
import { ICollector } from '../types/collector';
|
|
2
3
|
import { RumCustomEvent, RumEvent, RumExceptionEvent, RumResourceEvent, RumViewEvent, SendEventOptions } from '../types/rum-event';
|
|
3
4
|
import { IShell } from '../types/shell';
|
|
4
5
|
export default abstract class Shell implements IShell {
|
|
5
6
|
client: IClient;
|
|
7
|
+
protected initialized: boolean;
|
|
8
|
+
private extensionCollectors;
|
|
9
|
+
private static instances;
|
|
6
10
|
constructor(config?: IConfiguration);
|
|
11
|
+
/**
|
|
12
|
+
* 注册扩展采集器(实例方法,支持 per-instance 隔离)
|
|
13
|
+
* 支持在 init 之前或之后调用;若已初始化则立即 setup
|
|
14
|
+
*/
|
|
15
|
+
useCollectors(...collectors: ICollector[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
|
|
18
|
+
*/
|
|
19
|
+
getCollectors(): ICollector[];
|
|
20
|
+
/**
|
|
21
|
+
* 向所有已初始化的实例广播事件
|
|
22
|
+
*/
|
|
23
|
+
static broadcastEvent(event: RumEvent, options?: SendEventOptions): void;
|
|
24
|
+
/**
|
|
25
|
+
* 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
|
|
26
|
+
* 由 client.init 拦截器自动调用,子包无需手动调用。
|
|
27
|
+
*/
|
|
28
|
+
protected initClient(): void;
|
|
7
29
|
/**
|
|
8
30
|
* 初始化
|
|
9
31
|
*/
|
package/es/model/shell.js
CHANGED
|
@@ -1,40 +1,89 @@
|
|
|
1
|
-
|
|
1
|
+
var _Shell;
|
|
2
2
|
import { RumEventType } from '../types/rum-event';
|
|
3
3
|
import Client from '../model/client';
|
|
4
4
|
import { isNumber, isObject } from '../utils/is';
|
|
5
5
|
var Shell = /*#__PURE__*/function () {
|
|
6
6
|
function Shell(config) {
|
|
7
|
-
|
|
8
|
-
// private initialized = false;
|
|
7
|
+
var _this = this;
|
|
9
8
|
this.client = void 0;
|
|
9
|
+
this.initialized = false;
|
|
10
|
+
this.extensionCollectors = [];
|
|
10
11
|
this.client = new Client();
|
|
12
|
+
|
|
13
|
+
// 拦截 client.init,自动在其后挂载扩展采集器
|
|
14
|
+
var originalInit = this.client.init.bind(this.client);
|
|
15
|
+
this.client.init = function () {
|
|
16
|
+
originalInit.apply(void 0, arguments);
|
|
17
|
+
_this.initClient();
|
|
18
|
+
};
|
|
11
19
|
if (config && this.init) {
|
|
12
20
|
this.init(config);
|
|
13
|
-
// const p = this.init(config) as Promise<Shell>;
|
|
14
|
-
// if(isFunction(p?.then)){
|
|
15
|
-
// p.then(this.shellReady);
|
|
16
|
-
// } else {
|
|
17
|
-
// this.shellReady()
|
|
18
|
-
// }
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
// private shellReady = () => {
|
|
23
|
-
// this.initialized = true;
|
|
24
|
-
// this.callbacks.forEach(cb => cb());
|
|
25
|
-
// }
|
|
26
|
-
//
|
|
27
|
-
// onReady(callback: Function) {
|
|
28
|
-
// if (this.initialized) {
|
|
29
|
-
// callback();
|
|
30
|
-
// }
|
|
31
|
-
// this.callbacks.push(callback);
|
|
32
|
-
// }
|
|
33
|
-
|
|
34
24
|
/**
|
|
35
|
-
*
|
|
25
|
+
* 注册扩展采集器(实例方法,支持 per-instance 隔离)
|
|
26
|
+
* 支持在 init 之前或之后调用;若已初始化则立即 setup
|
|
36
27
|
*/
|
|
37
28
|
var _proto = Shell.prototype;
|
|
29
|
+
_proto.useCollectors = function useCollectors() {
|
|
30
|
+
var _this$extensionCollec,
|
|
31
|
+
_this2 = this;
|
|
32
|
+
for (var _len = arguments.length, collectors = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33
|
+
collectors[_key] = arguments[_key];
|
|
34
|
+
}
|
|
35
|
+
(_this$extensionCollec = this.extensionCollectors).push.apply(_this$extensionCollec, collectors);
|
|
36
|
+
if (this.initialized && this.client) {
|
|
37
|
+
var ctx = this.client.getContext();
|
|
38
|
+
if (ctx) {
|
|
39
|
+
collectors.forEach(function (collector) {
|
|
40
|
+
collector.setup(ctx, _this2.client.sendEvent);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
|
|
48
|
+
*/;
|
|
49
|
+
_proto.getCollectors = function getCollectors() {
|
|
50
|
+
var clientCollectors = this.client && this.client.getCollectors() || [];
|
|
51
|
+
// 用 concat 替代数组 spread,避免依赖 babel 降级注入 helper(项目去 @babel/runtime 规范)
|
|
52
|
+
return clientCollectors.concat(this.extensionCollectors);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 向所有已初始化的实例广播事件
|
|
57
|
+
*/;
|
|
58
|
+
Shell.broadcastEvent = function broadcastEvent(event, options) {
|
|
59
|
+
Shell.instances.forEach(function (instance) {
|
|
60
|
+
if (instance.initialized && instance.client) {
|
|
61
|
+
instance.client.sendEvent(event, options);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
|
|
68
|
+
* 由 client.init 拦截器自动调用,子包无需手动调用。
|
|
69
|
+
*/;
|
|
70
|
+
_proto.initClient = function initClient() {
|
|
71
|
+
var _this3 = this;
|
|
72
|
+
if (this.extensionCollectors.length > 0) {
|
|
73
|
+
var ctx = this.client.getContext();
|
|
74
|
+
if (ctx) {
|
|
75
|
+
this.extensionCollectors.forEach(function (collector) {
|
|
76
|
+
collector.setup(ctx, _this3.client.sendEvent);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.initialized = true;
|
|
81
|
+
Shell.instances.push(this);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 初始化
|
|
86
|
+
*/;
|
|
38
87
|
_proto.sendEvent = function sendEvent(payload, options) {
|
|
39
88
|
if (this.client) {
|
|
40
89
|
this.client.sendEvent(payload, options);
|
|
@@ -60,7 +109,7 @@ var Shell = /*#__PURE__*/function () {
|
|
|
60
109
|
if (!payload.name || !payload.type) {
|
|
61
110
|
return;
|
|
62
111
|
}
|
|
63
|
-
var data =
|
|
112
|
+
var data = Object.assign({}, payload, {
|
|
64
113
|
event_type: RumEventType.CUSTOM
|
|
65
114
|
});
|
|
66
115
|
this.sendEvent(data);
|
|
@@ -86,7 +135,7 @@ var Shell = /*#__PURE__*/function () {
|
|
|
86
135
|
});
|
|
87
136
|
if (n === 0) return;
|
|
88
137
|
}
|
|
89
|
-
var data =
|
|
138
|
+
var data = Object.assign({}, payload, {
|
|
90
139
|
event_type: RumEventType.VIEW
|
|
91
140
|
});
|
|
92
141
|
this.sendEvent(data);
|
|
@@ -102,7 +151,7 @@ var Shell = /*#__PURE__*/function () {
|
|
|
102
151
|
var name = payload.name,
|
|
103
152
|
message = payload.message,
|
|
104
153
|
stack = payload.stack;
|
|
105
|
-
var data =
|
|
154
|
+
var data = Object.assign({
|
|
106
155
|
times: 1,
|
|
107
156
|
name: name,
|
|
108
157
|
message: message,
|
|
@@ -122,7 +171,7 @@ var Shell = /*#__PURE__*/function () {
|
|
|
122
171
|
if (!payload.name || !payload.type || !isNumber(payload.duration)) {
|
|
123
172
|
return;
|
|
124
173
|
}
|
|
125
|
-
var data =
|
|
174
|
+
var data = Object.assign({
|
|
126
175
|
times: 1
|
|
127
176
|
}, payload, {
|
|
128
177
|
event_type: RumEventType.RESOURCE
|
|
@@ -131,4 +180,6 @@ var Shell = /*#__PURE__*/function () {
|
|
|
131
180
|
};
|
|
132
181
|
return Shell;
|
|
133
182
|
}();
|
|
183
|
+
_Shell = Shell;
|
|
184
|
+
Shell.instances = [];
|
|
134
185
|
export { Shell as default };
|
package/es/monitor/logger.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { MonitorLogEvent, MonitorLogLevel } from './types';
|
|
2
|
-
type LogArgs = [
|
|
2
|
+
type LogArgs = [
|
|
3
|
+
module: string,
|
|
4
|
+
message: string,
|
|
5
|
+
error?: unknown,
|
|
6
|
+
context?: Record<string, unknown>
|
|
7
|
+
];
|
|
3
8
|
export interface ILogger {
|
|
4
9
|
debug(...args: LogArgs): void;
|
|
5
10
|
info(...args: LogArgs): void;
|
package/es/monitor/logger.js
CHANGED
package/es/monitor/telemetry.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
2
1
|
var _Telemetry;
|
|
3
2
|
import { logger } from './logger';
|
|
4
3
|
import { getUrlParams } from '../utils/url';
|
|
@@ -75,12 +74,12 @@ export var Telemetry = /*#__PURE__*/function () {
|
|
|
75
74
|
var _this$context$getSess, _this$context, _this$context$getView, _this$context2;
|
|
76
75
|
if (!this.enabled || !event) return;
|
|
77
76
|
if (event.content && event.content.length > LOG_CONTENT_MAX_SIZE) {
|
|
78
|
-
event =
|
|
77
|
+
event = Object.assign({}, event, {
|
|
79
78
|
content: event.content.slice(0, LOG_CONTENT_MAX_SIZE)
|
|
80
79
|
});
|
|
81
80
|
}
|
|
82
81
|
if (event.stack && event.stack.length > LOG_CONTENT_MAX_SIZE) {
|
|
83
|
-
event =
|
|
82
|
+
event = Object.assign({}, event, {
|
|
84
83
|
stack: event.stack.slice(0, LOG_CONTENT_MAX_SIZE)
|
|
85
84
|
});
|
|
86
85
|
}
|
|
@@ -149,7 +148,7 @@ export var Telemetry = /*#__PURE__*/function () {
|
|
|
149
148
|
appType = _this$context3.appType,
|
|
150
149
|
sdkVersion = _this$context3.sdkVersion,
|
|
151
150
|
endpoint = _this$context3.endpoint;
|
|
152
|
-
return
|
|
151
|
+
return Object.assign({
|
|
153
152
|
'app.type': appType,
|
|
154
153
|
_v: sdkVersion,
|
|
155
154
|
endpoint: endpoint,
|
|
@@ -189,11 +188,11 @@ export function convertBundlesToLogGroup(data) {
|
|
|
189
188
|
var contents = [];
|
|
190
189
|
|
|
191
190
|
// 遍历 bundle 顶层字段,跳过 timestamp(映射到 time),对象类型整体序列化
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
val = _Object$entries$_i[1];
|
|
191
|
+
var bundleKeys = Object.keys(bundle);
|
|
192
|
+
for (var i = 0; i < bundleKeys.length; i++) {
|
|
193
|
+
var _key = bundleKeys[i];
|
|
196
194
|
if (_key === 'timestamp') continue;
|
|
195
|
+
var val = bundle[_key];
|
|
197
196
|
if (val !== undefined && val !== null) {
|
|
198
197
|
contents.push({
|
|
199
198
|
key: _key,
|
package/es/types/shell.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IConfiguration } from './client';
|
|
2
|
+
import { ICollector } from './collector';
|
|
2
3
|
import { RumEvent, SendEventOptions } from './rum-event';
|
|
3
4
|
/**
|
|
4
5
|
* 每个 sdk shell 导出固定需要实现的基础 api
|
|
@@ -8,6 +9,14 @@ import { RumEvent, SendEventOptions } from './rum-event';
|
|
|
8
9
|
* 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
|
9
10
|
*/
|
|
10
11
|
export interface IShell {
|
|
12
|
+
/**
|
|
13
|
+
* 注册扩展采集器(per-instance 隔离)
|
|
14
|
+
*/
|
|
15
|
+
useCollectors(...collectors: ICollector[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* 返回当前实例装载的全部采集器
|
|
18
|
+
*/
|
|
19
|
+
getCollectors(): ICollector[];
|
|
11
20
|
/**
|
|
12
21
|
* 初始化
|
|
13
22
|
*/
|
package/es/utils/base.js
CHANGED
|
@@ -10,6 +10,13 @@ export function interceptFunction(target, name, callback, isPrototype) {
|
|
|
10
10
|
}
|
|
11
11
|
try {
|
|
12
12
|
var registeredMethod = target[name];
|
|
13
|
+
// 目标方法不存在时不注入空 wrapper:
|
|
14
|
+
// 空 wrapper 会覆盖 Behavior 提供的方法并使其静默失效,
|
|
15
|
+
// 且原函数为 undefined 时 disguiseProxy 不会安装 toString 伪装,
|
|
16
|
+
// 依赖注入等通过 fn.toString() 读取函数源码的场景将拿到 proxyMethod 源码
|
|
17
|
+
if (!isFunction(registeredMethod)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
13
20
|
var proxyMethod = function proxyMethod() {
|
|
14
21
|
var ctx = isPrototype ? this : target;
|
|
15
22
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
package/lib/index.js
CHANGED
package/lib/model/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}
|
|
4
4
|
exports.__esModule = true;
|
|
5
5
|
exports["default"] = void 0;
|
|
6
6
|
var _client = require("../types/client");
|
|
@@ -80,7 +80,9 @@ var Client = /*#__PURE__*/function () {
|
|
|
80
80
|
}
|
|
81
81
|
reporter.report(ctx, options);
|
|
82
82
|
});
|
|
83
|
-
|
|
83
|
+
|
|
84
|
+
// 采集器可全部经 Shell 扩展通道注册,此处允许为空
|
|
85
|
+
(collectors || []).forEach(function (collector) {
|
|
84
86
|
collector.setup(ctx, _this2.sendEvent);
|
|
85
87
|
});
|
|
86
88
|
};
|
|
@@ -21,7 +21,7 @@ export declare abstract class ConfigManager implements IConfigManager {
|
|
|
21
21
|
* 更新配置
|
|
22
22
|
* @param config 新配置
|
|
23
23
|
*/
|
|
24
|
-
setConfig(config: Partial<IConfiguration>):
|
|
24
|
+
setConfig(config: Partial<IConfiguration>): void;
|
|
25
25
|
/**
|
|
26
26
|
* 检查缓存是否有效
|
|
27
27
|
* @param cachedData 缓存数据
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
exports.__esModule = true;
|
|
5
4
|
exports.ConfigManager = void 0;
|
|
6
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
7
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
8
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
9
5
|
function parseRemoteConfig(config) {
|
|
10
6
|
var remoteConfig = config.remoteConfig || {};
|
|
11
7
|
var enable = false;
|
|
@@ -38,75 +34,46 @@ var ConfigManager = exports.ConfigManager = /*#__PURE__*/function () {
|
|
|
38
34
|
* 初始化配置管理器
|
|
39
35
|
* @param config 初始配置
|
|
40
36
|
*/
|
|
41
|
-
_proto.init =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
var _this = this;
|
|
46
|
-
var remoteConfig, cacheConfig, asyncConfigPromise;
|
|
47
|
-
return _regenerator["default"].wrap(function (_context) {
|
|
48
|
-
while (1) switch (_context.prev = _context.next) {
|
|
49
|
-
case 0:
|
|
50
|
-
if (!this.initialized) {
|
|
51
|
-
_context.next = 1;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
return _context.abrupt("return");
|
|
55
|
-
case 1:
|
|
56
|
-
this.currentConfig = (0, _extends2["default"])({}, config);
|
|
57
|
-
this.initialized = true;
|
|
58
|
-
remoteConfig = parseRemoteConfig(config);
|
|
59
|
-
this.currentConfig.remoteConfig = remoteConfig;
|
|
60
|
-
if (remoteConfig.enable) {
|
|
61
|
-
_context.next = 2;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
return _context.abrupt("return");
|
|
65
|
-
case 2:
|
|
66
|
-
_context.next = 3;
|
|
67
|
-
return this.getCacheConfig();
|
|
68
|
-
case 3:
|
|
69
|
-
cacheConfig = _context.sent;
|
|
70
|
-
if (cacheConfig && cacheConfig.content) {
|
|
71
|
-
this.currentConfig = this.mergeRemoteCfg(cacheConfig.content);
|
|
72
|
-
}
|
|
73
|
-
if (!this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
|
|
74
|
-
_context.next = 4;
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
return _context.abrupt("return");
|
|
78
|
-
case 4:
|
|
79
|
-
asyncConfigPromise = this.fetchRemoteCfg(this.currentConfig).then(function (resp) {
|
|
80
|
-
if (!resp) return;
|
|
81
|
-
var asyncRemoteConfig = _this.parseConfig(resp);
|
|
82
|
-
_this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
|
|
83
|
-
_this.setCacheConfig({
|
|
84
|
-
timestamp: Date.now(),
|
|
85
|
-
content: resp
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
if (!(remoteConfig.mode === 'remote-first')) {
|
|
89
|
-
_context.next = 5;
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
_context.next = 5;
|
|
93
|
-
return asyncConfigPromise;
|
|
94
|
-
case 5:
|
|
95
|
-
case "end":
|
|
96
|
-
return _context.stop();
|
|
97
|
-
}
|
|
98
|
-
}, _callee, this);
|
|
99
|
-
}));
|
|
100
|
-
function init(_x) {
|
|
101
|
-
return _init.apply(this, arguments);
|
|
37
|
+
_proto.init = function init(config) {
|
|
38
|
+
var _this = this;
|
|
39
|
+
if (this.initialized) {
|
|
40
|
+
return Promise.resolve();
|
|
102
41
|
}
|
|
103
|
-
|
|
104
|
-
|
|
42
|
+
this.currentConfig = Object.assign({}, config);
|
|
43
|
+
this.initialized = true;
|
|
44
|
+
var remoteConfig = parseRemoteConfig(config);
|
|
45
|
+
this.currentConfig.remoteConfig = remoteConfig;
|
|
46
|
+
if (!remoteConfig.enable) {
|
|
47
|
+
return Promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
return Promise.resolve(this.getCacheConfig()).then(function (cacheConfig) {
|
|
50
|
+
if (cacheConfig && cacheConfig.content) {
|
|
51
|
+
_this.currentConfig = _this.mergeRemoteCfg(cacheConfig.content);
|
|
52
|
+
}
|
|
53
|
+
if (_this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
|
|
54
|
+
// 配置有效期内直接返回,不抓取远端配置
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
var asyncConfigPromise = _this.fetchRemoteCfg(_this.currentConfig).then(function (resp) {
|
|
58
|
+
if (!resp) return;
|
|
59
|
+
var asyncRemoteConfig = _this.parseConfig(resp);
|
|
60
|
+
_this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
|
|
61
|
+
_this.setCacheConfig({
|
|
62
|
+
timestamp: Date.now(),
|
|
63
|
+
content: resp
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
if (remoteConfig.mode === 'remote-first') {
|
|
67
|
+
// 远端配置优先情况下,要等待获取完成后返回
|
|
68
|
+
return asyncConfigPromise;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
105
73
|
/**
|
|
106
74
|
* 获取配置
|
|
107
75
|
* @returns 配置数据
|
|
108
|
-
|
|
109
|
-
;
|
|
76
|
+
*/;
|
|
110
77
|
_proto.getConfig = function getConfig() {
|
|
111
78
|
if (!this.currentConfig) {
|
|
112
79
|
throw new Error('Config not initialized');
|
|
@@ -118,37 +85,16 @@ var ConfigManager = exports.ConfigManager = /*#__PURE__*/function () {
|
|
|
118
85
|
* 更新配置
|
|
119
86
|
* @param config 新配置
|
|
120
87
|
*/;
|
|
121
|
-
_proto.setConfig =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
while (1) switch (_context2.prev = _context2.next) {
|
|
127
|
-
case 0:
|
|
128
|
-
if (this.currentConfig) {
|
|
129
|
-
_context2.next = 1;
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
return _context2.abrupt("return");
|
|
133
|
-
case 1:
|
|
134
|
-
this.currentConfig = (0, _extends2["default"])({}, this.currentConfig, config);
|
|
135
|
-
case 2:
|
|
136
|
-
case "end":
|
|
137
|
-
return _context2.stop();
|
|
138
|
-
}
|
|
139
|
-
}, _callee2, this);
|
|
140
|
-
}));
|
|
141
|
-
function setConfig(_x2) {
|
|
142
|
-
return _setConfig.apply(this, arguments);
|
|
143
|
-
}
|
|
144
|
-
return setConfig;
|
|
145
|
-
}()
|
|
88
|
+
_proto.setConfig = function setConfig(config) {
|
|
89
|
+
if (!this.currentConfig) return;
|
|
90
|
+
this.currentConfig = Object.assign({}, this.currentConfig, config);
|
|
91
|
+
}
|
|
92
|
+
|
|
146
93
|
/**
|
|
147
94
|
* 检查缓存是否有效
|
|
148
95
|
* @param cachedData 缓存数据
|
|
149
96
|
* @param cacheTimeout 缓存超时时间
|
|
150
|
-
|
|
151
|
-
;
|
|
97
|
+
*/;
|
|
152
98
|
_proto.isCacheValid = function isCacheValid(cachedData, cacheTimeout) {
|
|
153
99
|
if (!cachedData || !cachedData.timestamp) {
|
|
154
100
|
return false;
|
|
@@ -170,7 +116,7 @@ var ConfigManager = exports.ConfigManager = /*#__PURE__*/function () {
|
|
|
170
116
|
remoteConfig = _this$currentConfig.remoteConfig,
|
|
171
117
|
beforeReport = _this$currentConfig.beforeReport,
|
|
172
118
|
properties = _this$currentConfig.properties;
|
|
173
|
-
return (
|
|
119
|
+
return Object.assign({}, this.currentConfig, remoteCfg, {
|
|
174
120
|
pid: pid,
|
|
175
121
|
app: app,
|
|
176
122
|
endpoint: endpoint,
|
package/lib/model/reporter.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
exports.__esModule = true;
|
|
5
4
|
exports["default"] = void 0;
|
|
6
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
7
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
8
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
5
|
var _logger = require("../monitor/logger");
|
|
10
6
|
var _rumEvent = require("../types/rum-event");
|
|
11
7
|
var _exception = require("../utils/exception");
|
|
@@ -212,7 +208,7 @@ var Reporter = exports["default"] = /*#__PURE__*/function () {
|
|
|
212
208
|
*/;
|
|
213
209
|
_proto.buildAndSend = function buildAndSend(ctx, config, session, sessionId, events, view) {
|
|
214
210
|
var extend = (0, _url.getUrlParams)(config.endpoint);
|
|
215
|
-
var bundle = (
|
|
211
|
+
var bundle = Object.assign({
|
|
216
212
|
app: {
|
|
217
213
|
id: config.pid,
|
|
218
214
|
env: config.env || 'prod',
|
|
@@ -251,54 +247,32 @@ var Reporter = exports["default"] = /*#__PURE__*/function () {
|
|
|
251
247
|
}
|
|
252
248
|
this.tryRequest(bundle);
|
|
253
249
|
};
|
|
254
|
-
_proto.tryRequest =
|
|
255
|
-
var
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return _regenerator["default"].wrap(function (_context) {
|
|
262
|
-
while (1) switch (_context.prev = _context.next) {
|
|
263
|
-
case 0:
|
|
264
|
-
if (retry === void 0) {
|
|
265
|
-
retry = 0;
|
|
266
|
-
}
|
|
267
|
-
reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
|
|
268
|
-
maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
|
|
269
|
-
retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
|
|
270
|
-
_context.prev = 1;
|
|
271
|
-
bundle._retry = retry;
|
|
272
|
-
_context.next = 2;
|
|
273
|
-
return this.request(this.ctx, bundle);
|
|
274
|
-
case 2:
|
|
275
|
-
_context.next = 4;
|
|
276
|
-
break;
|
|
277
|
-
case 3:
|
|
278
|
-
_context.prev = 3;
|
|
279
|
-
_t = _context["catch"](1);
|
|
280
|
-
if (retry < maxRetryCount - 1) {
|
|
281
|
-
setTimeout(function () {
|
|
282
|
-
return _this2.tryRequest(bundle, retry + 1);
|
|
283
|
-
}, retryDelay);
|
|
284
|
-
} else {
|
|
285
|
-
_logger.logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", _t);
|
|
286
|
-
}
|
|
287
|
-
case 4:
|
|
288
|
-
case "end":
|
|
289
|
-
return _context.stop();
|
|
290
|
-
}
|
|
291
|
-
}, _callee, this, [[1, 3]]);
|
|
292
|
-
}));
|
|
293
|
-
function tryRequest(_x, _x2) {
|
|
294
|
-
return _tryRequest.apply(this, arguments);
|
|
250
|
+
_proto.tryRequest = function tryRequest(bundle, retry) {
|
|
251
|
+
var _this$ctx$getConfig,
|
|
252
|
+
_reportConfig$maxRetr,
|
|
253
|
+
_reportConfig$retryDe,
|
|
254
|
+
_this2 = this;
|
|
255
|
+
if (retry === void 0) {
|
|
256
|
+
retry = 0;
|
|
295
257
|
}
|
|
296
|
-
|
|
297
|
-
|
|
258
|
+
var reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
|
|
259
|
+
var maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
|
|
260
|
+
var retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
|
|
261
|
+
bundle._retry = retry;
|
|
262
|
+
Promise.resolve(this.request(this.ctx, bundle))["catch"](function (e) {
|
|
263
|
+
if (retry < maxRetryCount - 1) {
|
|
264
|
+
setTimeout(function () {
|
|
265
|
+
return _this2.tryRequest(bundle, retry + 1);
|
|
266
|
+
}, retryDelay);
|
|
267
|
+
} else {
|
|
268
|
+
_logger.logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", e);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
298
273
|
/**
|
|
299
274
|
* 接口请求由各平台 sdk reporter 实现
|
|
300
|
-
|
|
301
|
-
;
|
|
275
|
+
*/;
|
|
302
276
|
/**
|
|
303
277
|
* 初始化时
|
|
304
278
|
*/
|
package/lib/model/shell.d.ts
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
import { IClient, IConfiguration } from '../types/client';
|
|
2
|
+
import { ICollector } from '../types/collector';
|
|
2
3
|
import { RumCustomEvent, RumEvent, RumExceptionEvent, RumResourceEvent, RumViewEvent, SendEventOptions } from '../types/rum-event';
|
|
3
4
|
import { IShell } from '../types/shell';
|
|
4
5
|
export default abstract class Shell implements IShell {
|
|
5
6
|
client: IClient;
|
|
7
|
+
protected initialized: boolean;
|
|
8
|
+
private extensionCollectors;
|
|
9
|
+
private static instances;
|
|
6
10
|
constructor(config?: IConfiguration);
|
|
11
|
+
/**
|
|
12
|
+
* 注册扩展采集器(实例方法,支持 per-instance 隔离)
|
|
13
|
+
* 支持在 init 之前或之后调用;若已初始化则立即 setup
|
|
14
|
+
*/
|
|
15
|
+
useCollectors(...collectors: ICollector[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
|
|
18
|
+
*/
|
|
19
|
+
getCollectors(): ICollector[];
|
|
20
|
+
/**
|
|
21
|
+
* 向所有已初始化的实例广播事件
|
|
22
|
+
*/
|
|
23
|
+
static broadcastEvent(event: RumEvent, options?: SendEventOptions): void;
|
|
24
|
+
/**
|
|
25
|
+
* 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
|
|
26
|
+
* 由 client.init 拦截器自动调用,子包无需手动调用。
|
|
27
|
+
*/
|
|
28
|
+
protected initClient(): void;
|
|
7
29
|
/**
|
|
8
30
|
* 初始化
|
|
9
31
|
*/
|
package/lib/model/shell.js
CHANGED
|
@@ -1,45 +1,94 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}
|
|
4
4
|
exports.__esModule = true;
|
|
5
5
|
exports["default"] = void 0;
|
|
6
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
7
6
|
var _rumEvent = require("../types/rum-event");
|
|
8
7
|
var _client = _interopRequireDefault(require("../model/client"));
|
|
9
8
|
var _is = require("../utils/is");
|
|
9
|
+
var _Shell;
|
|
10
10
|
var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
11
11
|
function Shell(config) {
|
|
12
|
-
|
|
13
|
-
// private initialized = false;
|
|
12
|
+
var _this = this;
|
|
14
13
|
this.client = void 0;
|
|
14
|
+
this.initialized = false;
|
|
15
|
+
this.extensionCollectors = [];
|
|
15
16
|
this.client = new _client["default"]();
|
|
17
|
+
|
|
18
|
+
// 拦截 client.init,自动在其后挂载扩展采集器
|
|
19
|
+
var originalInit = this.client.init.bind(this.client);
|
|
20
|
+
this.client.init = function () {
|
|
21
|
+
originalInit.apply(void 0, arguments);
|
|
22
|
+
_this.initClient();
|
|
23
|
+
};
|
|
16
24
|
if (config && this.init) {
|
|
17
25
|
this.init(config);
|
|
18
|
-
// const p = this.init(config) as Promise<Shell>;
|
|
19
|
-
// if(isFunction(p?.then)){
|
|
20
|
-
// p.then(this.shellReady);
|
|
21
|
-
// } else {
|
|
22
|
-
// this.shellReady()
|
|
23
|
-
// }
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
// private shellReady = () => {
|
|
28
|
-
// this.initialized = true;
|
|
29
|
-
// this.callbacks.forEach(cb => cb());
|
|
30
|
-
// }
|
|
31
|
-
//
|
|
32
|
-
// onReady(callback: Function) {
|
|
33
|
-
// if (this.initialized) {
|
|
34
|
-
// callback();
|
|
35
|
-
// }
|
|
36
|
-
// this.callbacks.push(callback);
|
|
37
|
-
// }
|
|
38
|
-
|
|
39
29
|
/**
|
|
40
|
-
*
|
|
30
|
+
* 注册扩展采集器(实例方法,支持 per-instance 隔离)
|
|
31
|
+
* 支持在 init 之前或之后调用;若已初始化则立即 setup
|
|
41
32
|
*/
|
|
42
33
|
var _proto = Shell.prototype;
|
|
34
|
+
_proto.useCollectors = function useCollectors() {
|
|
35
|
+
var _this$extensionCollec,
|
|
36
|
+
_this2 = this;
|
|
37
|
+
for (var _len = arguments.length, collectors = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
38
|
+
collectors[_key] = arguments[_key];
|
|
39
|
+
}
|
|
40
|
+
(_this$extensionCollec = this.extensionCollectors).push.apply(_this$extensionCollec, collectors);
|
|
41
|
+
if (this.initialized && this.client) {
|
|
42
|
+
var ctx = this.client.getContext();
|
|
43
|
+
if (ctx) {
|
|
44
|
+
collectors.forEach(function (collector) {
|
|
45
|
+
collector.setup(ctx, _this2.client.sendEvent);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
|
|
53
|
+
*/;
|
|
54
|
+
_proto.getCollectors = function getCollectors() {
|
|
55
|
+
var clientCollectors = this.client && this.client.getCollectors() || [];
|
|
56
|
+
// 用 concat 替代数组 spread,避免依赖 babel 降级注入 helper(项目去 @babel/runtime 规范)
|
|
57
|
+
return clientCollectors.concat(this.extensionCollectors);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 向所有已初始化的实例广播事件
|
|
62
|
+
*/;
|
|
63
|
+
Shell.broadcastEvent = function broadcastEvent(event, options) {
|
|
64
|
+
Shell.instances.forEach(function (instance) {
|
|
65
|
+
if (instance.initialized && instance.client) {
|
|
66
|
+
instance.client.sendEvent(event, options);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
|
|
73
|
+
* 由 client.init 拦截器自动调用,子包无需手动调用。
|
|
74
|
+
*/;
|
|
75
|
+
_proto.initClient = function initClient() {
|
|
76
|
+
var _this3 = this;
|
|
77
|
+
if (this.extensionCollectors.length > 0) {
|
|
78
|
+
var ctx = this.client.getContext();
|
|
79
|
+
if (ctx) {
|
|
80
|
+
this.extensionCollectors.forEach(function (collector) {
|
|
81
|
+
collector.setup(ctx, _this3.client.sendEvent);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
this.initialized = true;
|
|
86
|
+
Shell.instances.push(this);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 初始化
|
|
91
|
+
*/;
|
|
43
92
|
_proto.sendEvent = function sendEvent(payload, options) {
|
|
44
93
|
if (this.client) {
|
|
45
94
|
this.client.sendEvent(payload, options);
|
|
@@ -65,7 +114,7 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
|
65
114
|
if (!payload.name || !payload.type) {
|
|
66
115
|
return;
|
|
67
116
|
}
|
|
68
|
-
var data = (
|
|
117
|
+
var data = Object.assign({}, payload, {
|
|
69
118
|
event_type: _rumEvent.RumEventType.CUSTOM
|
|
70
119
|
});
|
|
71
120
|
this.sendEvent(data);
|
|
@@ -91,7 +140,7 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
|
91
140
|
});
|
|
92
141
|
if (n === 0) return;
|
|
93
142
|
}
|
|
94
|
-
var data = (
|
|
143
|
+
var data = Object.assign({}, payload, {
|
|
95
144
|
event_type: _rumEvent.RumEventType.VIEW
|
|
96
145
|
});
|
|
97
146
|
this.sendEvent(data);
|
|
@@ -107,7 +156,7 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
|
107
156
|
var name = payload.name,
|
|
108
157
|
message = payload.message,
|
|
109
158
|
stack = payload.stack;
|
|
110
|
-
var data = (
|
|
159
|
+
var data = Object.assign({
|
|
111
160
|
times: 1,
|
|
112
161
|
name: name,
|
|
113
162
|
message: message,
|
|
@@ -127,7 +176,7 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
|
127
176
|
if (!payload.name || !payload.type || !(0, _is.isNumber)(payload.duration)) {
|
|
128
177
|
return;
|
|
129
178
|
}
|
|
130
|
-
var data = (
|
|
179
|
+
var data = Object.assign({
|
|
131
180
|
times: 1
|
|
132
181
|
}, payload, {
|
|
133
182
|
event_type: _rumEvent.RumEventType.RESOURCE
|
|
@@ -135,4 +184,6 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
|
|
|
135
184
|
this.sendEvent(data);
|
|
136
185
|
};
|
|
137
186
|
return Shell;
|
|
138
|
-
}();
|
|
187
|
+
}();
|
|
188
|
+
_Shell = Shell;
|
|
189
|
+
Shell.instances = [];
|
package/lib/monitor/logger.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { MonitorLogEvent, MonitorLogLevel } from './types';
|
|
2
|
-
type LogArgs = [
|
|
2
|
+
type LogArgs = [
|
|
3
|
+
module: string,
|
|
4
|
+
message: string,
|
|
5
|
+
error?: unknown,
|
|
6
|
+
context?: Record<string, unknown>
|
|
7
|
+
];
|
|
3
8
|
export interface ILogger {
|
|
4
9
|
debug(...args: LogArgs): void;
|
|
5
10
|
info(...args: LogArgs): void;
|
package/lib/monitor/logger.js
CHANGED
package/lib/monitor/telemetry.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
exports.__esModule = true;
|
|
5
4
|
exports.Telemetry = void 0;
|
|
6
5
|
exports.convertBundlesToLogGroup = convertBundlesToLogGroup;
|
|
7
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
8
6
|
var _logger = require("./logger");
|
|
9
7
|
var _url = require("../utils/url");
|
|
10
8
|
var _protobuf = require("../utils/protobuf");
|
|
@@ -80,12 +78,12 @@ var Telemetry = exports.Telemetry = /*#__PURE__*/function () {
|
|
|
80
78
|
var _this$context$getSess, _this$context, _this$context$getView, _this$context2;
|
|
81
79
|
if (!this.enabled || !event) return;
|
|
82
80
|
if (event.content && event.content.length > LOG_CONTENT_MAX_SIZE) {
|
|
83
|
-
event = (
|
|
81
|
+
event = Object.assign({}, event, {
|
|
84
82
|
content: event.content.slice(0, LOG_CONTENT_MAX_SIZE)
|
|
85
83
|
});
|
|
86
84
|
}
|
|
87
85
|
if (event.stack && event.stack.length > LOG_CONTENT_MAX_SIZE) {
|
|
88
|
-
event = (
|
|
86
|
+
event = Object.assign({}, event, {
|
|
89
87
|
stack: event.stack.slice(0, LOG_CONTENT_MAX_SIZE)
|
|
90
88
|
});
|
|
91
89
|
}
|
|
@@ -154,7 +152,7 @@ var Telemetry = exports.Telemetry = /*#__PURE__*/function () {
|
|
|
154
152
|
appType = _this$context3.appType,
|
|
155
153
|
sdkVersion = _this$context3.sdkVersion,
|
|
156
154
|
endpoint = _this$context3.endpoint;
|
|
157
|
-
return (
|
|
155
|
+
return Object.assign({
|
|
158
156
|
'app.type': appType,
|
|
159
157
|
_v: sdkVersion,
|
|
160
158
|
endpoint: endpoint,
|
|
@@ -193,11 +191,11 @@ function convertBundlesToLogGroup(data) {
|
|
|
193
191
|
var contents = [];
|
|
194
192
|
|
|
195
193
|
// 遍历 bundle 顶层字段,跳过 timestamp(映射到 time),对象类型整体序列化
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
val = _Object$entries$_i[1];
|
|
194
|
+
var bundleKeys = Object.keys(bundle);
|
|
195
|
+
for (var i = 0; i < bundleKeys.length; i++) {
|
|
196
|
+
var _key = bundleKeys[i];
|
|
200
197
|
if (_key === 'timestamp') continue;
|
|
198
|
+
var val = bundle[_key];
|
|
201
199
|
if (val !== undefined && val !== null) {
|
|
202
200
|
contents.push({
|
|
203
201
|
key: _key,
|
package/lib/types/shell.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IConfiguration } from './client';
|
|
2
|
+
import { ICollector } from './collector';
|
|
2
3
|
import { RumEvent, SendEventOptions } from './rum-event';
|
|
3
4
|
/**
|
|
4
5
|
* 每个 sdk shell 导出固定需要实现的基础 api
|
|
@@ -8,6 +9,14 @@ import { RumEvent, SendEventOptions } from './rum-event';
|
|
|
8
9
|
* 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
|
9
10
|
*/
|
|
10
11
|
export interface IShell {
|
|
12
|
+
/**
|
|
13
|
+
* 注册扩展采集器(per-instance 隔离)
|
|
14
|
+
*/
|
|
15
|
+
useCollectors(...collectors: ICollector[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* 返回当前实例装载的全部采集器
|
|
18
|
+
*/
|
|
19
|
+
getCollectors(): ICollector[];
|
|
11
20
|
/**
|
|
12
21
|
* 初始化
|
|
13
22
|
*/
|
package/lib/utils/base.js
CHANGED
|
@@ -21,6 +21,13 @@ function interceptFunction(target, name, callback, isPrototype) {
|
|
|
21
21
|
}
|
|
22
22
|
try {
|
|
23
23
|
var registeredMethod = target[name];
|
|
24
|
+
// 目标方法不存在时不注入空 wrapper:
|
|
25
|
+
// 空 wrapper 会覆盖 Behavior 提供的方法并使其静默失效,
|
|
26
|
+
// 且原函数为 undefined 时 disguiseProxy 不会安装 toString 伪装,
|
|
27
|
+
// 依赖注入等通过 fn.toString() 读取函数源码的场景将拿到 proxyMethod 源码
|
|
28
|
+
if (!(0, _is.isFunction)(registeredMethod)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
24
31
|
var proxyMethod = function proxyMethod() {
|
|
25
32
|
var ctx = isPrototype ? this : target;
|
|
26
33
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arms/rum-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "arms rum javascript sdk core",
|
|
5
5
|
"author": "guangli.fj <guangli.fj@alibaba-inc.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -34,9 +34,6 @@
|
|
|
34
34
|
"prepublishOnly": "npm run build",
|
|
35
35
|
"test": "npm run build && jest ./__tests__"
|
|
36
36
|
},
|
|
37
|
-
"peerDependencies": {
|
|
38
|
-
"@babel/runtime": "^7.24.5"
|
|
39
|
-
},
|
|
40
37
|
"devDependencies": {
|
|
41
38
|
"typescript": "^4.9.4"
|
|
42
39
|
}
|