spy-client 2.1.14 → 2.2.1
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/.travis.yml +7 -4
- package/AGENTS.md +132 -0
- package/README.md +29 -18
- package/dist/head/base.d.ts +27 -25
- package/dist/head/error.d.ts +6 -6
- package/dist/head/observer.d.ts +5 -5
- package/dist/head/whitescreen.d.ts +6 -6
- package/dist/lib/data.d.ts +6 -6
- package/dist/lib/huffman.d.ts +9 -9
- package/dist/lib/interface.d.ts +209 -209
- package/dist/lib/spyHeadInterface.d.ts +36 -28
- package/dist/lib/util.d.ts +22 -22
- package/dist/module/fid.d.ts +15 -15
- package/dist/module/layoutShift.d.ts +18 -18
- package/dist/module/lcp.d.ts +17 -17
- package/dist/module/longtask.d.ts +46 -46
- package/dist/module/memory.d.ts +11 -11
- package/dist/module/navigatorInfo.d.ts +9 -9
- package/dist/module/resource.d.ts +39 -39
- package/dist/module/timing.d.ts +11 -11
- package/dist/module/tti.d.ts +19 -19
- package/dist/spy-client-basic.d.ts +118 -104
- package/dist/spy-client-basic.esm.js +298 -294
- package/dist/spy-client-basic.iife.js +298 -294
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +298 -294
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +298 -294
- package/dist/spy-client.d.ts +32 -32
- package/dist/spy-client.esm.js +1430 -1419
- package/dist/spy-client.iife.js +1430 -1419
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +1430 -1419
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +1430 -1419
- package/dist/spy-head.d.ts +6 -6
- package/dist/spy-head.js +359 -355
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.d.ts +18 -18
- package/dist/spy-local-cache.js +718 -711
- package/dist/spy-local-cache.min.js +1 -1
- package/package.json +26 -73
- package/test-results/.last-run.json +4 -0
- package/karma.conf.js +0 -111
|
@@ -1,302 +1,306 @@
|
|
|
1
1
|
var SpyClient = (function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* @file utils
|
|
6
|
-
* @author kaivean
|
|
7
|
-
*/
|
|
8
|
-
function assign() {
|
|
9
|
-
var args = [];
|
|
10
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
11
|
-
args[_i] = arguments[_i];
|
|
12
|
-
}
|
|
13
|
-
var __assign = Object.assign || function __assign(t) {
|
|
14
|
-
for (var s = void 0, i = 1, n = arguments.length; i < n; i++) {
|
|
15
|
-
// eslint-disable-next-line prefer-rest-params
|
|
16
|
-
s = arguments[i];
|
|
17
|
-
for (var p in s) {
|
|
18
|
-
if (Object.prototype.hasOwnProperty.call(s, p)) {
|
|
19
|
-
t[p] = s[p];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return t;
|
|
24
|
-
};
|
|
25
|
-
return __assign.apply(
|
|
4
|
+
/**
|
|
5
|
+
* @file utils
|
|
6
|
+
* @author kaivean
|
|
7
|
+
*/
|
|
8
|
+
function assign() {
|
|
9
|
+
var args = [];
|
|
10
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
11
|
+
args[_i] = arguments[_i];
|
|
12
|
+
}
|
|
13
|
+
var __assign = Object.assign || function __assign(t) {
|
|
14
|
+
for (var s = void 0, i = 1, n = arguments.length; i < n; i++) {
|
|
15
|
+
// eslint-disable-next-line prefer-rest-params
|
|
16
|
+
s = arguments[i];
|
|
17
|
+
for (var p in s) {
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(s, p)) {
|
|
19
|
+
t[p] = s[p];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
return __assign.apply(null, args);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* @file SpyClient
|
|
30
|
-
* @author kaivean
|
|
31
|
-
*/
|
|
32
|
-
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
33
|
-
// 基础版本兼容非浏览器环境
|
|
34
|
-
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
35
|
-
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
36
|
-
function err(msg) {
|
|
37
|
-
console.error("[SpyClient_log]".concat(msg));
|
|
38
|
-
// throw new Error(msg);
|
|
39
|
-
}
|
|
40
|
-
function stringify(obj) {
|
|
41
|
-
return Object.keys(obj).map(function (key) {
|
|
42
|
-
var value = obj[key];
|
|
43
|
-
if (typeof value === 'undefined') {
|
|
44
|
-
value = '';
|
|
45
|
-
}
|
|
46
|
-
else if (typeof value !== 'string') {
|
|
47
|
-
value = JSON.stringify(value);
|
|
48
|
-
}
|
|
49
|
-
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
50
|
-
}).join('&');
|
|
51
|
-
}
|
|
52
|
-
function isArray(arr) {
|
|
53
|
-
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
54
|
-
}
|
|
55
|
-
var SpyClient = /** @class */ (function () {
|
|
56
|
-
function SpyClient(option) {
|
|
57
|
-
this.sample = {};
|
|
58
|
-
this.markCache = {};
|
|
59
|
-
if (!option.pid) {
|
|
60
|
-
throw new Error('pid is required');
|
|
61
|
-
}
|
|
62
|
-
this.option = {
|
|
63
|
-
pid: option.pid,
|
|
64
|
-
lid: option.lid,
|
|
65
|
-
check: option.check !== false,
|
|
66
|
-
sample: option.sample,
|
|
67
|
-
localCache: option.localCache,
|
|
68
|
-
logServer: option.logServer || defaultLogServer,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
SpyClient.prototype.handle = function (logItem) {
|
|
72
|
-
if (!this.check(logItem)) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
logItem = assign({
|
|
76
|
-
pid: this.option.pid,
|
|
77
|
-
lid: this.option.lid,
|
|
78
|
-
ts: Date.now(),
|
|
79
|
-
group: 'common',
|
|
80
|
-
}, logItem);
|
|
81
|
-
if (this.option.localCache) {
|
|
82
|
-
this.option.localCache.addLog(logItem);
|
|
83
|
-
}
|
|
84
|
-
// 当前api设置了抽样,
|
|
85
|
-
if (typeof logItem.sample === 'number') {
|
|
86
|
-
if (Math.random() > logItem.sample) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
delete logItem.sample;
|
|
94
|
-
return logItem;
|
|
95
|
-
};
|
|
96
|
-
SpyClient.prototype.send = function (data, post) {
|
|
97
|
-
if (post === void 0) { post = false; }
|
|
98
|
-
var logItems = isArray(data) ? data : [data];
|
|
99
|
-
var postData = [];
|
|
100
|
-
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
101
|
-
var logItem = logItems_1[_i];
|
|
102
|
-
logItem = this.handle(logItem);
|
|
103
|
-
if (!logItem) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
postData.push(logItem);
|
|
107
|
-
// 期望通过post方式上传日志
|
|
108
|
-
if (post) {
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
var url = this.option.logServer + stringify(logItem);
|
|
112
|
-
this.request(url);
|
|
113
|
-
}
|
|
114
|
-
if (post) {
|
|
115
|
-
this.sendPost(postData);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
SpyClient.prototype.check = function (query) {
|
|
119
|
-
if (!this.option.check) {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
var types = ['perf', 'except', 'dist', 'count'];
|
|
123
|
-
if (types.indexOf(query.type) === -1) {
|
|
124
|
-
err('type only is one of ' + types.join(', '));
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
if (query.group && query.group.length > 30) {
|
|
128
|
-
err('group length execeeds 30');
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
var simpleReg = /^[a-zA-Z0-9-_]{0,30}$/;
|
|
132
|
-
if (query.type === 'except') {
|
|
133
|
-
if (!(typeof query.info.msg === 'string' && query.info.msg.length)) {
|
|
134
|
-
err('info.msg field must be not empty and is String');
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
for (var _i = 0, _a = Object.keys(query.info); _i < _a.length; _i++) {
|
|
140
|
-
var infoKey = _a[_i];
|
|
141
|
-
if (!simpleReg.test(infoKey)) {
|
|
142
|
-
err("info.".concat(infoKey, " is unexpected. ")
|
|
143
|
-
+ 'Length must be not more than 30. '
|
|
144
|
-
+ 'Supported chars: a-zA-Z0-9-_');
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
var infoVal = query.info[infoKey];
|
|
148
|
-
if (query.type === 'dist') {
|
|
149
|
-
if (infoVal.length > 30) {
|
|
150
|
-
err("info.".concat(infoKey, " value length execeeds 30 when type == 'dist'"));
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
else if (typeof infoVal !== 'number') {
|
|
155
|
-
err("info.".concat(infoKey, " value must be number"));
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (query.dim) {
|
|
161
|
-
for (var _b = 0, _c = Object.keys(query.dim); _b < _c.length; _b++) {
|
|
162
|
-
var dimKey = _c[_b];
|
|
163
|
-
if (!simpleReg.test(dimKey)) {
|
|
164
|
-
err("dim key [".concat(dimKey, "] is unexpected. ")
|
|
165
|
-
+ 'Length must be not more than 30. '
|
|
166
|
-
+ 'Supported chars: a-zA-Z0-9-_');
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
var dimVal = query.dim[dimKey];
|
|
170
|
-
if (!/^[a-zA-Z0-9\-_\*\.\s\/#\+@\&\u4e00-\u9fa5]{0,30}$/.test(dimVal)) {
|
|
171
|
-
err("dim.".concat(dimKey, " value [").concat(dimVal, "] is unexpected. ")
|
|
172
|
-
+ 'Length must be not more than 30. '
|
|
173
|
-
+ 'Supported chars: a-zA-Z0-9-_*. /#+@& and Chinese');
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return true;
|
|
179
|
-
};
|
|
180
|
-
/**
|
|
181
|
-
*
|
|
182
|
-
* @param option 配置
|
|
183
|
-
*/
|
|
184
|
-
SpyClient.prototype.sendPerf = function (option) {
|
|
185
|
-
this.send(assign({
|
|
186
|
-
type: 'perf',
|
|
187
|
-
}, option));
|
|
188
|
-
};
|
|
189
|
-
/**
|
|
190
|
-
*
|
|
191
|
-
* @param option 错误配置项
|
|
192
|
-
*/
|
|
193
|
-
SpyClient.prototype.sendExcept = function (option) {
|
|
194
|
-
this.send(assign({
|
|
195
|
-
type: 'except',
|
|
196
|
-
}, option));
|
|
197
|
-
};
|
|
198
|
-
/**
|
|
199
|
-
*
|
|
200
|
-
* @param option 配置
|
|
201
|
-
*/
|
|
202
|
-
SpyClient.prototype.sendDist = function (option) {
|
|
203
|
-
this.send(assign({
|
|
204
|
-
type: 'dist',
|
|
205
|
-
}, option));
|
|
206
|
-
};
|
|
207
|
-
/**
|
|
208
|
-
*
|
|
209
|
-
* @param option 配置
|
|
210
|
-
*/
|
|
211
|
-
SpyClient.prototype.sendCount = function (option) {
|
|
212
|
-
this.send(assign({
|
|
213
|
-
type: 'count',
|
|
214
|
-
}, option));
|
|
215
|
-
};
|
|
216
|
-
/**
|
|
217
|
-
*
|
|
218
|
-
* @param e 错误实例
|
|
219
|
-
* @param option 错误配置项
|
|
220
|
-
*/
|
|
221
|
-
SpyClient.prototype.sendExceptForError = function (e, option) {
|
|
222
|
-
var newOpt = assign({}, option);
|
|
223
|
-
newOpt.info = assign({}, option.info || {}, {
|
|
224
|
-
msg: e.message,
|
|
225
|
-
stack: e.stack,
|
|
226
|
-
});
|
|
227
|
-
this.sendExcept(newOpt);
|
|
228
|
-
};
|
|
229
|
-
SpyClient.prototype.startMark = function (sign) {
|
|
230
|
-
this.markCache[sign] = {
|
|
231
|
-
start: Date.now(),
|
|
232
|
-
};
|
|
233
|
-
};
|
|
234
|
-
SpyClient.prototype.endMark = function (sign) {
|
|
235
|
-
if (this.markCache[sign]) {
|
|
236
|
-
this.markCache[sign].total = Date.now() - this.markCache[sign].start;
|
|
237
|
-
return this.markCache[sign].total;
|
|
238
|
-
}
|
|
239
|
-
return 0;
|
|
240
|
-
};
|
|
241
|
-
SpyClient.prototype.clearMark = function (sign) {
|
|
242
|
-
if (this.markCache[sign]) {
|
|
243
|
-
delete this.markCache[sign];
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
SpyClient.prototype.getAllMark = function () {
|
|
247
|
-
var ret = {};
|
|
248
|
-
for (var _i = 0, _a = Object.keys(this.markCache); _i < _a.length; _i++) {
|
|
249
|
-
var sign = _a[_i];
|
|
250
|
-
ret[sign] = this.markCache[sign].total;
|
|
251
|
-
}
|
|
252
|
-
return ret;
|
|
253
|
-
};
|
|
254
|
-
SpyClient.prototype.clearAllMark = function () {
|
|
255
|
-
this.markCache = {};
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
fetch
|
|
291
|
-
method
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @file SpyClient
|
|
30
|
+
* @author kaivean
|
|
31
|
+
*/
|
|
32
|
+
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
33
|
+
// 基础版本兼容非浏览器环境
|
|
34
|
+
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
35
|
+
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
36
|
+
function err(msg) {
|
|
37
|
+
console.error("[SpyClient_log]".concat(msg));
|
|
38
|
+
// throw new Error(msg);
|
|
39
|
+
}
|
|
40
|
+
function stringify(obj) {
|
|
41
|
+
return Object.keys(obj).map(function (key) {
|
|
42
|
+
var value = obj[key];
|
|
43
|
+
if (typeof value === 'undefined') {
|
|
44
|
+
value = '';
|
|
45
|
+
}
|
|
46
|
+
else if (typeof value !== 'string') {
|
|
47
|
+
value = JSON.stringify(value);
|
|
48
|
+
}
|
|
49
|
+
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
50
|
+
}).join('&');
|
|
51
|
+
}
|
|
52
|
+
function isArray(arr) {
|
|
53
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
54
|
+
}
|
|
55
|
+
var SpyClient = /** @class */ (function () {
|
|
56
|
+
function SpyClient(option) {
|
|
57
|
+
this.sample = {};
|
|
58
|
+
this.markCache = {};
|
|
59
|
+
if (!option.pid) {
|
|
60
|
+
throw new Error('pid is required');
|
|
61
|
+
}
|
|
62
|
+
this.option = {
|
|
63
|
+
pid: option.pid,
|
|
64
|
+
lid: option.lid,
|
|
65
|
+
check: option.check !== false,
|
|
66
|
+
sample: option.sample,
|
|
67
|
+
localCache: option.localCache,
|
|
68
|
+
logServer: option.logServer || defaultLogServer,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
SpyClient.prototype.handle = function (logItem) {
|
|
72
|
+
if (!this.check(logItem)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
logItem = assign({
|
|
76
|
+
pid: this.option.pid,
|
|
77
|
+
lid: this.option.lid,
|
|
78
|
+
ts: Date.now(),
|
|
79
|
+
group: 'common',
|
|
80
|
+
}, logItem);
|
|
81
|
+
if (this.option.localCache) {
|
|
82
|
+
this.option.localCache.addLog(logItem);
|
|
83
|
+
}
|
|
84
|
+
// 当前api设置了抽样,
|
|
85
|
+
if (typeof logItem.sample === 'number') {
|
|
86
|
+
if (Math.random() > logItem.sample) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
delete logItem.sample;
|
|
94
|
+
return logItem;
|
|
95
|
+
};
|
|
96
|
+
SpyClient.prototype.send = function (data, post) {
|
|
97
|
+
if (post === void 0) { post = false; }
|
|
98
|
+
var logItems = isArray(data) ? data : [data];
|
|
99
|
+
var postData = [];
|
|
100
|
+
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
101
|
+
var logItem = logItems_1[_i];
|
|
102
|
+
logItem = this.handle(logItem);
|
|
103
|
+
if (!logItem) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
postData.push(logItem);
|
|
107
|
+
// 期望通过post方式上传日志
|
|
108
|
+
if (post) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
var url = this.option.logServer + stringify(logItem);
|
|
112
|
+
this.request(url);
|
|
113
|
+
}
|
|
114
|
+
if (post) {
|
|
115
|
+
this.sendPost(postData);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
SpyClient.prototype.check = function (query) {
|
|
119
|
+
if (!this.option.check) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
var types = ['perf', 'except', 'dist', 'count'];
|
|
123
|
+
if (types.indexOf(query.type) === -1) {
|
|
124
|
+
err('type only is one of ' + types.join(', '));
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (query.group && query.group.length > 30) {
|
|
128
|
+
err('group length execeeds 30');
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
var simpleReg = /^[a-zA-Z0-9-_]{0,30}$/;
|
|
132
|
+
if (query.type === 'except') {
|
|
133
|
+
if (!(typeof query.info.msg === 'string' && query.info.msg.length)) {
|
|
134
|
+
err('info.msg field must be not empty and is String');
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
for (var _i = 0, _a = Object.keys(query.info); _i < _a.length; _i++) {
|
|
140
|
+
var infoKey = _a[_i];
|
|
141
|
+
if (!simpleReg.test(infoKey)) {
|
|
142
|
+
err("info.".concat(infoKey, " is unexpected. ")
|
|
143
|
+
+ 'Length must be not more than 30. '
|
|
144
|
+
+ 'Supported chars: a-zA-Z0-9-_');
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
var infoVal = query.info[infoKey];
|
|
148
|
+
if (query.type === 'dist') {
|
|
149
|
+
if (infoVal.length > 30) {
|
|
150
|
+
err("info.".concat(infoKey, " value length execeeds 30 when type == 'dist'"));
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (typeof infoVal !== 'number') {
|
|
155
|
+
err("info.".concat(infoKey, " value must be number"));
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (query.dim) {
|
|
161
|
+
for (var _b = 0, _c = Object.keys(query.dim); _b < _c.length; _b++) {
|
|
162
|
+
var dimKey = _c[_b];
|
|
163
|
+
if (!simpleReg.test(dimKey)) {
|
|
164
|
+
err("dim key [".concat(dimKey, "] is unexpected. ")
|
|
165
|
+
+ 'Length must be not more than 30. '
|
|
166
|
+
+ 'Supported chars: a-zA-Z0-9-_');
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
var dimVal = query.dim[dimKey];
|
|
170
|
+
if (!/^[a-zA-Z0-9\-_\*\.\s\/#\+@\&\u4e00-\u9fa5]{0,30}$/.test(dimVal)) {
|
|
171
|
+
err("dim.".concat(dimKey, " value [").concat(dimVal, "] is unexpected. ")
|
|
172
|
+
+ 'Length must be not more than 30. '
|
|
173
|
+
+ 'Supported chars: a-zA-Z0-9-_*. /#+@& and Chinese');
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param option 配置
|
|
183
|
+
*/
|
|
184
|
+
SpyClient.prototype.sendPerf = function (option) {
|
|
185
|
+
this.send(assign({
|
|
186
|
+
type: 'perf',
|
|
187
|
+
}, option));
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* @param option 错误配置项
|
|
192
|
+
*/
|
|
193
|
+
SpyClient.prototype.sendExcept = function (option) {
|
|
194
|
+
this.send(assign({
|
|
195
|
+
type: 'except',
|
|
196
|
+
}, option));
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* @param option 配置
|
|
201
|
+
*/
|
|
202
|
+
SpyClient.prototype.sendDist = function (option) {
|
|
203
|
+
this.send(assign({
|
|
204
|
+
type: 'dist',
|
|
205
|
+
}, option));
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @param option 配置
|
|
210
|
+
*/
|
|
211
|
+
SpyClient.prototype.sendCount = function (option) {
|
|
212
|
+
this.send(assign({
|
|
213
|
+
type: 'count',
|
|
214
|
+
}, option));
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
*
|
|
218
|
+
* @param e 错误实例
|
|
219
|
+
* @param option 错误配置项
|
|
220
|
+
*/
|
|
221
|
+
SpyClient.prototype.sendExceptForError = function (e, option) {
|
|
222
|
+
var newOpt = assign({}, option);
|
|
223
|
+
newOpt.info = assign({}, option.info || {}, {
|
|
224
|
+
msg: e.message,
|
|
225
|
+
stack: e.stack,
|
|
226
|
+
});
|
|
227
|
+
this.sendExcept(newOpt);
|
|
228
|
+
};
|
|
229
|
+
SpyClient.prototype.startMark = function (sign) {
|
|
230
|
+
this.markCache[sign] = {
|
|
231
|
+
start: Date.now(),
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
SpyClient.prototype.endMark = function (sign) {
|
|
235
|
+
if (this.markCache[sign]) {
|
|
236
|
+
this.markCache[sign].total = Date.now() - this.markCache[sign].start;
|
|
237
|
+
return this.markCache[sign].total;
|
|
238
|
+
}
|
|
239
|
+
return 0;
|
|
240
|
+
};
|
|
241
|
+
SpyClient.prototype.clearMark = function (sign) {
|
|
242
|
+
if (this.markCache[sign]) {
|
|
243
|
+
delete this.markCache[sign];
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
SpyClient.prototype.getAllMark = function () {
|
|
247
|
+
var ret = {};
|
|
248
|
+
for (var _i = 0, _a = Object.keys(this.markCache); _i < _a.length; _i++) {
|
|
249
|
+
var sign = _a[_i];
|
|
250
|
+
ret[sign] = this.markCache[sign].total;
|
|
251
|
+
}
|
|
252
|
+
return ret;
|
|
253
|
+
};
|
|
254
|
+
SpyClient.prototype.clearAllMark = function () {
|
|
255
|
+
this.markCache = {};
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* sendPost能以post请求发送,可以承接多个日志项,上报内容size可以提升,但没有前端校验
|
|
259
|
+
* send(data, true) 也能以post请求发送,但是会有严格校验
|
|
260
|
+
* 要求:发送的多条日志必须是同一个pid,同一类型type,同一分组group
|
|
261
|
+
* @param data 日志项或者日志项数组
|
|
262
|
+
*/
|
|
263
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
264
|
+
var logItems = isArray(data) ? data : [data];
|
|
265
|
+
var first = logItems[0];
|
|
266
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
267
|
+
var query = {
|
|
268
|
+
pid: first.pid,
|
|
269
|
+
type: first.type,
|
|
270
|
+
group: first.group,
|
|
271
|
+
};
|
|
272
|
+
var url = this.option.logServer + stringify(query);
|
|
273
|
+
this.request(url, data);
|
|
274
|
+
};
|
|
275
|
+
// 有data时,意味着要用post发送请求
|
|
276
|
+
SpyClient.prototype.request = function (url, data) {
|
|
277
|
+
if (!(!isLtIos14
|
|
278
|
+
&& navigator
|
|
279
|
+
&& navigator.sendBeacon
|
|
280
|
+
&& navigator.sendBeacon(url, data ? JSON.stringify(data) : undefined))) {
|
|
281
|
+
if (data) {
|
|
282
|
+
this.fetch(url, data);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
(new Image()).src = url;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
290
|
+
if (!fetch) {
|
|
291
|
+
err('Global fetch method doesn\'t exist');
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
fetch(url, {
|
|
295
|
+
method: 'POST',
|
|
296
|
+
credentials: 'include',
|
|
297
|
+
headers: {
|
|
298
|
+
'Content-Type': 'application/json',
|
|
299
|
+
},
|
|
300
|
+
body: JSON.stringify(data),
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
return SpyClient;
|
|
300
304
|
}());
|
|
301
305
|
|
|
302
306
|
return SpyClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var SpyClient=(
|
|
1
|
+
var SpyClient=function(){"use strict";function t(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=Object.assign||function(t){for(var e=void 0,n=1,o=arguments.length;n<o;n++)for(var r in e=arguments[n])Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t};return n.apply(null,t)}var e=navigator&&navigator.userAgent?navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/):"",n=e&&e[2]&&+e[2]<14;function o(t){console.error("[SpyClient_log]".concat(t))}function r(t){return Object.keys(t).map(function(e){var n=t[e];return void 0===n?n="":"string"!=typeof n&&(n=JSON.stringify(n)),encodeURIComponent(e)+"="+encodeURIComponent(n)}).join("&")}function i(t){return"[object Array]"===Object.prototype.toString.call(t)}return function(){function e(t){if(this.sample={},this.markCache={},!t.pid)throw new Error("pid is required");this.option={pid:t.pid,lid:t.lid,check:!1!==t.check,sample:t.sample,localCache:t.localCache,logServer:t.logServer||"https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?"}}return e.prototype.handle=function(e){if(this.check(e)){if(e=t({pid:this.option.pid,lid:this.option.lid,ts:Date.now(),group:"common"},e),this.option.localCache&&this.option.localCache.addLog(e),"number"==typeof e.sample){if(Math.random()>e.sample)return}else if("number"==typeof this.option.sample&&Math.random()>this.option.sample)return;return delete e.sample,e}},e.prototype.send=function(t,e){void 0===e&&(e=!1);for(var n=[],o=0,a=i(t)?t:[t];o<a.length;o++){var s=a[o];if((s=this.handle(s))&&(n.push(s),!e)){var p=this.option.logServer+r(s);this.request(p)}}e&&this.sendPost(n)},e.prototype.check=function(t){if(!this.option.check)return!0;var e=["perf","except","dist","count"];if(-1===e.indexOf(t.type))return o("type only is one of "+e.join(", ")),!1;if(t.group&&t.group.length>30)return o("group length execeeds 30"),!1;var n=/^[a-zA-Z0-9-_]{0,30}$/;if("except"===t.type){if("string"!=typeof t.info.msg||!t.info.msg.length)return o("info.msg field must be not empty and is String"),!1}else for(var r=0,i=Object.keys(t.info);r<i.length;r++){var a=i[r];if(!n.test(a))return o("info.".concat(a," is unexpected. ")+"Length must be not more than 30. Supported chars: a-zA-Z0-9-_"),!1;var s=t.info[a];if("dist"===t.type){if(s.length>30)return o("info.".concat(a," value length execeeds 30 when type == 'dist'")),!1}else if("number"!=typeof s)return o("info.".concat(a," value must be number")),!1}if(t.dim)for(var p=0,c=Object.keys(t.dim);p<c.length;p++){var h=c[p];if(!n.test(h))return o("dim key [".concat(h,"] is unexpected. ")+"Length must be not more than 30. Supported chars: a-zA-Z0-9-_"),!1;var u=t.dim[h];if(!/^[a-zA-Z0-9\-_\*\.\s\/#\+@\&\u4e00-\u9fa5]{0,30}$/.test(u))return o("dim.".concat(h," value [").concat(u,"] is unexpected. ")+"Length must be not more than 30. Supported chars: a-zA-Z0-9-_*. /#+@& and Chinese"),!1}return!0},e.prototype.sendPerf=function(e){this.send(t({type:"perf"},e))},e.prototype.sendExcept=function(e){this.send(t({type:"except"},e))},e.prototype.sendDist=function(e){this.send(t({type:"dist"},e))},e.prototype.sendCount=function(e){this.send(t({type:"count"},e))},e.prototype.sendExceptForError=function(e,n){var o=t({},n);o.info=t({},n.info||{},{msg:e.message,stack:e.stack}),this.sendExcept(o)},e.prototype.startMark=function(t){this.markCache[t]={start:Date.now()}},e.prototype.endMark=function(t){return this.markCache[t]?(this.markCache[t].total=Date.now()-this.markCache[t].start,this.markCache[t].total):0},e.prototype.clearMark=function(t){this.markCache[t]&&delete this.markCache[t]},e.prototype.getAllMark=function(){for(var t={},e=0,n=Object.keys(this.markCache);e<n.length;e++){var o=n[e];t[o]=this.markCache[o].total}return t},e.prototype.clearAllMark=function(){this.markCache={}},e.prototype.sendPost=function(t){var e=(i(t)?t:[t])[0],n={pid:e.pid,type:e.type,group:e.group},o=this.option.logServer+r(n);this.request(o,t)},e.prototype.request=function(t,e){!n&&navigator&&navigator.sendBeacon&&navigator.sendBeacon(t,e?JSON.stringify(e):void 0)||(e?this.fetch(t,e):(new Image).src=t)},e.prototype.fetch=function(t,e){fetch?fetch(t,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}):o("Global fetch method doesn't exist")},e}()}();
|