monitor-track 1.14.0 → 1.15.0
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/CHANGELOG.md +10 -0
- package/README.md +1 -0
- package/cjs/config/global.d.ts +0 -2
- package/cjs/config/request.d.ts +15 -0
- package/cjs/handlers/websocket.d.ts +16 -0
- package/cjs/index.d.ts +0 -5
- package/cjs/index.js +425 -170
- package/cjs/reporter.d.ts +2 -0
- package/cjs/types/config.d.ts +2 -0
- package/cjs/types/global.d.ts +2 -1
- package/esm/config/global.d.ts +0 -2
- package/esm/config/global.js +2 -167
- package/esm/config/index.js +3 -2
- package/esm/config/request.d.ts +15 -0
- package/esm/config/request.js +158 -0
- package/esm/handlers/websocket.d.ts +16 -0
- package/esm/handlers/websocket.js +277 -0
- package/esm/index.d.ts +0 -5
- package/esm/index.js +7 -15
- package/esm/package.json.js +1 -1
- package/esm/reporter.d.ts +2 -0
- package/esm/reporter.js +6 -0
- package/esm/types/config.d.ts +2 -0
- package/esm/types/global.d.ts +2 -1
- package/index.js +460 -166
- package/package.json +1 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import { Config } from '../config/index.js';
|
|
3
|
+
import { getReport } from '../config/global.js';
|
|
4
|
+
import { getUid } from '../utils/index.js';
|
|
5
|
+
|
|
6
|
+
let reconnectAndSendTimeout, websocketHeartBeatInterval, ws, userId = '';
|
|
7
|
+
let remoteDebugEnable = false;
|
|
8
|
+
let targetPlatform = '';
|
|
9
|
+
let targetUserId = '';
|
|
10
|
+
const originConsole = Object.assign({}, console);
|
|
11
|
+
const formatConsole = () => {
|
|
12
|
+
if (remoteDebugEnable)
|
|
13
|
+
return;
|
|
14
|
+
remoteDebugEnable = true;
|
|
15
|
+
window.console = Object.assign({}, originConsole);
|
|
16
|
+
const arr = ['debug', 'log', 'info', 'warn', 'error'];
|
|
17
|
+
arr.forEach((item) => {
|
|
18
|
+
//@ts-ignore
|
|
19
|
+
window.console[item] = function (...args) {
|
|
20
|
+
//@ts-ignore
|
|
21
|
+
originConsole[item](...args);
|
|
22
|
+
const data = {
|
|
23
|
+
origin: 'console',
|
|
24
|
+
level: item,
|
|
25
|
+
userId,
|
|
26
|
+
time: new Date().toLocaleString(),
|
|
27
|
+
page: location.href,
|
|
28
|
+
content: '',
|
|
29
|
+
targetPlatform,
|
|
30
|
+
targetUserId,
|
|
31
|
+
};
|
|
32
|
+
try {
|
|
33
|
+
const content = JSON.stringify(args);
|
|
34
|
+
data.content = content;
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
data.content = 'console内容解析错误: ' + err.stack || err.message || err.toString();
|
|
38
|
+
}
|
|
39
|
+
const msg = {
|
|
40
|
+
type: WEBSOCKET_TYPE.DEBUG_INFO_UPLOAD,
|
|
41
|
+
userId,
|
|
42
|
+
platform: 'monitor-track-sdk',
|
|
43
|
+
data,
|
|
44
|
+
};
|
|
45
|
+
wsSendFunc(msg);
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
const resetConsole = () => {
|
|
50
|
+
window.console = originConsole;
|
|
51
|
+
remoteDebugEnable = false;
|
|
52
|
+
};
|
|
53
|
+
const uploadRequest = (requestInfo) => {
|
|
54
|
+
// console.log('monitor-track-sdk: uploadRequest remoteDebugEnable', remoteDebugEnable);
|
|
55
|
+
if (remoteDebugEnable) {
|
|
56
|
+
const data = {
|
|
57
|
+
origin: 'request',
|
|
58
|
+
userId,
|
|
59
|
+
time: new Date().toLocaleString(),
|
|
60
|
+
page: location.href,
|
|
61
|
+
content: requestInfo,
|
|
62
|
+
targetPlatform,
|
|
63
|
+
targetUserId,
|
|
64
|
+
};
|
|
65
|
+
const msg = {
|
|
66
|
+
type: WEBSOCKET_TYPE.DEBUG_INFO_UPLOAD,
|
|
67
|
+
userId,
|
|
68
|
+
platform: 'monitor-track-sdk',
|
|
69
|
+
data,
|
|
70
|
+
};
|
|
71
|
+
// console.log('monitor-track-sdk: request-upload sent');
|
|
72
|
+
wsSendFunc(msg);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function enableOnlinePersonsFunc() {
|
|
76
|
+
initWebsocket();
|
|
77
|
+
}
|
|
78
|
+
const WEBSOCKET_TYPE = {
|
|
79
|
+
TRY_CONNECT: 'try-connect',
|
|
80
|
+
CHECK_CONNECT: 'check-connect',
|
|
81
|
+
PING: 'ping',
|
|
82
|
+
PONG: 'pong',
|
|
83
|
+
REPLY_SERVER_HEART_BEAT: 'reply-server-heart-beat',
|
|
84
|
+
SOCKET_HEART_BEAT: 'socket-heart-beat',
|
|
85
|
+
RESPONSE_DATE: 'response-date',
|
|
86
|
+
REMOTE_DEBUG_ENABLE: 'remote-debug-enable',
|
|
87
|
+
DEBUG_INFO_UPLOAD: 'debug-info-upload',
|
|
88
|
+
REPlY_MESSAGE: 'reply-message',
|
|
89
|
+
};
|
|
90
|
+
let mounted = false;
|
|
91
|
+
const initWebsocket = () => {
|
|
92
|
+
if (window.WebSocket) {
|
|
93
|
+
userId = localStorage.getItem('username') || getUid();
|
|
94
|
+
closeWebsocket('');
|
|
95
|
+
websocketHeartBeatInterval = setInterval(reconnectAndSend, 30000);
|
|
96
|
+
const isLocal = Config.reportUrl.includes('http://');
|
|
97
|
+
ws = new WebSocket(`ws${isLocal ? '' : 's'}://${Config.reportUrl.replace(isLocal ? 'http://' : 'https://', '').replace('/s/r', '')}?type=monitor-dsk`);
|
|
98
|
+
ws.onopen = () => openWS();
|
|
99
|
+
ws.onmessage = (data) => incomingMessage(data);
|
|
100
|
+
ws.onerror = () => {
|
|
101
|
+
ws.close(1000);
|
|
102
|
+
if (websocketHeartBeatInterval)
|
|
103
|
+
clearInterval(websocketHeartBeatInterval);
|
|
104
|
+
websocketHeartBeatInterval = setInterval(reconnectAndSend, 10000);
|
|
105
|
+
};
|
|
106
|
+
ws.onclose = () => {
|
|
107
|
+
ws.close(1000);
|
|
108
|
+
if (websocketHeartBeatInterval)
|
|
109
|
+
clearInterval(websocketHeartBeatInterval);
|
|
110
|
+
websocketHeartBeatInterval = setInterval(reconnectAndSend, 10000);
|
|
111
|
+
};
|
|
112
|
+
if (!mounted) {
|
|
113
|
+
reconnectNetwork();
|
|
114
|
+
mounted = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const openWS = () => {
|
|
119
|
+
const data = getReport();
|
|
120
|
+
const { page, projectID, host, pageTitle } = data;
|
|
121
|
+
const msg = {
|
|
122
|
+
type: WEBSOCKET_TYPE.TRY_CONNECT,
|
|
123
|
+
userId,
|
|
124
|
+
platform: 'monitor-track-sdk',
|
|
125
|
+
data: {
|
|
126
|
+
p: page,
|
|
127
|
+
pid: projectID,
|
|
128
|
+
host,
|
|
129
|
+
pt: pageTitle,
|
|
130
|
+
platform: 'web',
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
wsSendFunc(msg);
|
|
134
|
+
};
|
|
135
|
+
const reconnectAndSend = () => {
|
|
136
|
+
try {
|
|
137
|
+
if (ws.readyState !== 1) {
|
|
138
|
+
reconnectSocket();
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const msg = {
|
|
142
|
+
type: WEBSOCKET_TYPE.CHECK_CONNECT,
|
|
143
|
+
userId,
|
|
144
|
+
data: WEBSOCKET_TYPE.PING,
|
|
145
|
+
date: Date.now(),
|
|
146
|
+
};
|
|
147
|
+
wsSendFunc(msg, 'reconnectAndSend');
|
|
148
|
+
// 20秒超时,如果收不到服务端pong响应则表示服务端已主动断开连接,此时需客户端重新开启websocket连接
|
|
149
|
+
reconnectAndSendTimeout = setTimeout(() => {
|
|
150
|
+
reconnectSocket();
|
|
151
|
+
}, 20000);
|
|
152
|
+
}
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
154
|
+
}
|
|
155
|
+
catch (_err) {
|
|
156
|
+
// console.error('monitor-track-sdk: reconnectAndSend err', err);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const closeWebsocket = (info) => {
|
|
160
|
+
if (ws) {
|
|
161
|
+
ws.onopen = null;
|
|
162
|
+
ws.onmessage = null;
|
|
163
|
+
ws.onerror = null;
|
|
164
|
+
ws.onclose = null;
|
|
165
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
166
|
+
ws.close(1000, info);
|
|
167
|
+
}
|
|
168
|
+
//@ts-ignore
|
|
169
|
+
ws = null; // 释放引用
|
|
170
|
+
}
|
|
171
|
+
if (websocketHeartBeatInterval)
|
|
172
|
+
clearInterval(websocketHeartBeatInterval);
|
|
173
|
+
};
|
|
174
|
+
const reconnectSocket = () => {
|
|
175
|
+
// console.warn('monitor-track-sdk: 正在重新建立websocket连接...');
|
|
176
|
+
initWebsocket();
|
|
177
|
+
};
|
|
178
|
+
const incomingMessage = (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
179
|
+
let data = {};
|
|
180
|
+
try {
|
|
181
|
+
data = JSON.parse(e.data);
|
|
182
|
+
// console.info('incomingMessage data', data);
|
|
183
|
+
switch (data.type) {
|
|
184
|
+
case WEBSOCKET_TYPE.PONG:
|
|
185
|
+
// console.info('monitor-track-sdk: incomingMessage 响应客户端的心跳: ping => pong');
|
|
186
|
+
clearTimeout(reconnectAndSendTimeout);
|
|
187
|
+
break;
|
|
188
|
+
case WEBSOCKET_TYPE.SOCKET_HEART_BEAT: {
|
|
189
|
+
// console.info('monitor-track-sdk: incomingMessage 响应服务端的心跳: heart beat => ', new Date().toLocaleString());
|
|
190
|
+
const msg = {
|
|
191
|
+
type: WEBSOCKET_TYPE.CHECK_CONNECT,
|
|
192
|
+
userId,
|
|
193
|
+
data: WEBSOCKET_TYPE.REPLY_SERVER_HEART_BEAT,
|
|
194
|
+
date: Date.now(),
|
|
195
|
+
};
|
|
196
|
+
wsSendFunc(msg, 'socket-heart-beat reply-server-heart-beat');
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case WEBSOCKET_TYPE.RESPONSE_DATE:
|
|
200
|
+
// console.info(`monitor-track-sdk: incomingMessage WS connected, Roundtrip time: ${Date.now() - data.data} ms`);
|
|
201
|
+
break;
|
|
202
|
+
case WEBSOCKET_TYPE.REMOTE_DEBUG_ENABLE: {
|
|
203
|
+
// console.log('monitor-track-sdk REMOTE_DEBUG_ENABLE data.data', data.data);
|
|
204
|
+
const { enable, platform, userId } = data.data;
|
|
205
|
+
if (enable && platform && userId) {
|
|
206
|
+
targetPlatform = platform;
|
|
207
|
+
targetUserId = userId;
|
|
208
|
+
formatConsole();
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
resetConsole();
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case WEBSOCKET_TYPE.REPlY_MESSAGE: {
|
|
216
|
+
// eslint-disable-next-line no-console
|
|
217
|
+
console.info('incomingMessage REPlY_MESSAGE, data: ', data.data);
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
default:
|
|
221
|
+
// console.error('incomingMessage default error', data);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
// eslint-disable-next-line no-console
|
|
227
|
+
console.error('monitor-track-sdk incomingMessage JSON.parse', err);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
const wsSendFunc = (msg, _info) => {
|
|
231
|
+
if (ws.readyState === 1) {
|
|
232
|
+
msg.platform = 'monitor-track-sdk';
|
|
233
|
+
const message = JSON.stringify(msg);
|
|
234
|
+
ws.send(message);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// console.warn('monitor-track-sdk: window.ws.readyState === 1 info', info);
|
|
238
|
+
reconnectSocket();
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const reconnectNetwork = () => {
|
|
242
|
+
let networkFlag = false;
|
|
243
|
+
let debounceTimeout = null;
|
|
244
|
+
document.addEventListener('offline', function () {
|
|
245
|
+
// 断开网络
|
|
246
|
+
try {
|
|
247
|
+
// console.info('monitor-track-sdk: 客户端网络已断开,正在关闭websocket');
|
|
248
|
+
ws.close(1000);
|
|
249
|
+
networkFlag = true;
|
|
250
|
+
debounceTimeout = setTimeout(() => {
|
|
251
|
+
// console.warn('monitor-track-sdk: reconnectNetwork offline 无法访问网络');
|
|
252
|
+
// message.error('无法访问网络');
|
|
253
|
+
}, 5000);
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
// console.error('monitor-track-sdk: addEventListener offline after setTimeout', err);
|
|
257
|
+
}
|
|
258
|
+
}, false);
|
|
259
|
+
document.addEventListener('online', function () {
|
|
260
|
+
// 连接到网络
|
|
261
|
+
try {
|
|
262
|
+
if (networkFlag === true) {
|
|
263
|
+
clearTimeout(debounceTimeout);
|
|
264
|
+
// console.info('monitor-track-sdk: addEventListener reconnectNetwork online');
|
|
265
|
+
// message.success('网络已恢复');
|
|
266
|
+
networkFlag = false;
|
|
267
|
+
// console.warn('monitor-track-sdk: addEventListener online websocket 正在重新建立连接...');
|
|
268
|
+
initWebsocket();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
// console.error('monitor-track-sdk: document.addEventListener online', err);
|
|
273
|
+
}
|
|
274
|
+
}, false);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export { WEBSOCKET_TYPE, closeWebsocket, enableOnlinePersonsFunc, uploadRequest };
|
package/esm/index.d.ts
CHANGED
package/esm/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Config, setConfig } from './config/index.js';
|
|
2
|
-
import { initReport
|
|
2
|
+
import { initReport } from './config/global.js';
|
|
3
|
+
import { recordXMLHttpRequest, recordFetch } from './config/request.js';
|
|
3
4
|
import { monitorTrackSessionId } from './constant.js';
|
|
4
5
|
import { handlePageLag, _history, handleHistoryChange } from './handlers/pv.js';
|
|
5
6
|
import { enableRecordFunc, handleError } from './handlers/error.js';
|
|
6
7
|
import { handleClick, handleBlur, handleScroll } from './handlers/user-activity.js';
|
|
8
|
+
import { enableOnlinePersonsFunc, closeWebsocket } from './handlers/websocket.js';
|
|
7
9
|
import { initWindowObjectFunction, on, off, visualTrackFunc, handleLocationChange } from './utils/index.js';
|
|
8
10
|
|
|
9
11
|
class Track {
|
|
@@ -29,7 +31,6 @@ class Track {
|
|
|
29
31
|
};
|
|
30
32
|
}
|
|
31
33
|
init(config) {
|
|
32
|
-
var _a;
|
|
33
34
|
// 是否开启日志收集
|
|
34
35
|
if (!config || !config.enable) {
|
|
35
36
|
return;
|
|
@@ -46,19 +47,17 @@ class Track {
|
|
|
46
47
|
console.warn('缺少上报地址!');
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
49
|
-
if (this.ignoreUrl(((_a = config === null || config === void 0 ? void 0 : config.ignore) === null || _a === void 0 ? void 0 : _a.urls) || [])) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
50
|
setConfig(config);
|
|
53
51
|
initReport();
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
recordXMLHttpRequest(config.XMLHttpRequestTimeout || 2500);
|
|
53
|
+
recordFetch(config.XMLHttpRequestTimeout || 2500);
|
|
56
54
|
Config.spa && this.addListenRouterChange();
|
|
57
55
|
Config.enableBehavior && this.addListenUserActivity();
|
|
58
56
|
Config.enableError && this.addListenJSUncaught();
|
|
59
57
|
Config.enableVisualTrack && this.visualTrack();
|
|
60
58
|
Config.enableLagTrack && this.listenPageLag();
|
|
61
59
|
Config.enableRecord && enableRecordFunc();
|
|
60
|
+
Config.enableOnlinePersons && enableOnlinePersonsFunc();
|
|
62
61
|
this.addListenUnload();
|
|
63
62
|
initWindowObjectFunction();
|
|
64
63
|
}
|
|
@@ -98,14 +97,6 @@ class Track {
|
|
|
98
97
|
this.destroy();
|
|
99
98
|
});
|
|
100
99
|
}
|
|
101
|
-
/**
|
|
102
|
-
* 忽略的url
|
|
103
|
-
* @param urls
|
|
104
|
-
*/
|
|
105
|
-
ignoreUrl(urls) {
|
|
106
|
-
const someUrl = urls.some((url) => location.href.includes(url));
|
|
107
|
-
return someUrl;
|
|
108
|
-
}
|
|
109
100
|
/**
|
|
110
101
|
* @description 销毁监听器
|
|
111
102
|
*/
|
|
@@ -128,6 +119,7 @@ class Track {
|
|
|
128
119
|
this.lagTimer && clearInterval(this.lagTimer);
|
|
129
120
|
(_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
130
121
|
sessionStorage.removeItem(monitorTrackSessionId);
|
|
122
|
+
closeWebsocket('destroy');
|
|
131
123
|
}
|
|
132
124
|
}
|
|
133
125
|
|
package/esm/package.json.js
CHANGED
package/esm/reporter.d.ts
CHANGED
package/esm/reporter.js
CHANGED
|
@@ -188,6 +188,8 @@ const reportMap = {
|
|
|
188
188
|
detail: 'de',
|
|
189
189
|
/** 上报时带上的请求参数 */
|
|
190
190
|
requestData: 'rD',
|
|
191
|
+
/** 上报时带上的响应结果 */
|
|
192
|
+
responseBody: 'rB',
|
|
191
193
|
/** 上报时带上的请求方法 */
|
|
192
194
|
method: 'rM',
|
|
193
195
|
},
|
|
@@ -316,6 +318,10 @@ function reportFunc(data) {
|
|
|
316
318
|
// 上报
|
|
317
319
|
function report(data) {
|
|
318
320
|
return new Promise((res) => {
|
|
321
|
+
var _a;
|
|
322
|
+
if ((((_a = Config.ignore) === null || _a === void 0 ? void 0 : _a.urls) || []).some((url) => location.href.includes(url))) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
319
325
|
//在帧的空闲时间上报
|
|
320
326
|
const dataCopy = JSON.parse(JSON.stringify(data));
|
|
321
327
|
if (typeof window.requestIdleCallback === 'function') {
|
package/esm/types/config.d.ts
CHANGED
package/esm/types/global.d.ts
CHANGED