@cloudcare/rum-uniapp 1.0.1 → 2.0.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/README.md +1 -1
- package/cjs/boot/buildEnv.js +1 -1
- package/cjs/boot/rum.entry.js +56 -1
- package/cjs/boot/rum.js +2 -2
- package/cjs/core/boundedBuffer.js +28 -0
- package/cjs/core/configuration.js +22 -1
- package/cjs/core/dataMap.js +5 -1
- package/cjs/core/transport.js +123 -69
- package/cjs/core/xhrProxy.js +3 -2
- package/cjs/helper/enums.js +11 -2
- package/cjs/helper/utils.js +189 -6
- package/cjs/rumEventsCollection/assembly.js +19 -2
- package/cjs/rumEventsCollection/page/index.js +1 -11
- package/cjs/rumEventsCollection/requestCollection.js +9 -2
- package/cjs/rumEventsCollection/resource/resourceCollection.js +21 -1
- package/cjs/rumEventsCollection/tracing/ddtraceTracer.js +50 -0
- package/cjs/rumEventsCollection/tracing/jaegerTracer.js +58 -0
- package/cjs/rumEventsCollection/tracing/skywalkingTracer.js +75 -0
- package/cjs/rumEventsCollection/tracing/tracer.js +108 -0
- package/cjs/rumEventsCollection/tracing/w3cTraceParentTracer.js +51 -0
- package/cjs/rumEventsCollection/tracing/zipkinMultiTracer.js +58 -0
- package/cjs/rumEventsCollection/tracing/zipkinSingleTracer.js +51 -0
- package/esm/boot/buildEnv.js +1 -1
- package/esm/boot/rum.entry.js +55 -2
- package/esm/boot/rum.js +2 -2
- package/esm/core/boundedBuffer.js +20 -0
- package/esm/core/configuration.js +24 -3
- package/esm/core/dataMap.js +5 -1
- package/esm/core/transport.js +120 -70
- package/esm/core/xhrProxy.js +3 -2
- package/esm/helper/enums.js +8 -0
- package/esm/helper/utils.js +168 -5
- package/esm/rumEventsCollection/assembly.js +20 -3
- package/esm/rumEventsCollection/page/index.js +1 -11
- package/esm/rumEventsCollection/requestCollection.js +8 -2
- package/esm/rumEventsCollection/resource/resourceCollection.js +22 -2
- package/esm/rumEventsCollection/tracing/ddtraceTracer.js +42 -0
- package/esm/rumEventsCollection/tracing/jaegerTracer.js +50 -0
- package/esm/rumEventsCollection/tracing/skywalkingTracer.js +66 -0
- package/esm/rumEventsCollection/tracing/tracer.js +90 -0
- package/esm/rumEventsCollection/tracing/w3cTraceParentTracer.js +43 -0
- package/esm/rumEventsCollection/tracing/zipkinMultiTracer.js +50 -0
- package/esm/rumEventsCollection/tracing/zipkinSingleTracer.js +43 -0
- package/package.json +5 -1
package/esm/helper/enums.js
CHANGED
|
@@ -33,4 +33,12 @@ export var MpHook = {
|
|
|
33
33
|
onResize: 1,
|
|
34
34
|
onHide: 1,
|
|
35
35
|
onUnload: 1
|
|
36
|
+
};
|
|
37
|
+
export var TraceType = {
|
|
38
|
+
DDTRACE: 'ddtrace',
|
|
39
|
+
ZIPKIN_MULTI_HEADER: 'zipkin',
|
|
40
|
+
ZIPKIN_SINGLE_HEADER: 'zipkin_single_header',
|
|
41
|
+
W3C_TRACEPARENT: 'w3c_traceparent',
|
|
42
|
+
SKYWALKING_V3: 'skywalking_v3',
|
|
43
|
+
JAEGER: 'jaeger'
|
|
36
44
|
};
|
package/esm/helper/utils.js
CHANGED
|
@@ -6,6 +6,7 @@ var hasOwnProperty = ObjProto.hasOwnProperty;
|
|
|
6
6
|
var slice = ArrayProto.slice;
|
|
7
7
|
var toString = ObjProto.toString;
|
|
8
8
|
var nativeForEach = ArrayProto.forEach;
|
|
9
|
+
var nativeIsArray = Array.isArray;
|
|
9
10
|
var breaker = false;
|
|
10
11
|
export var isArguments = function isArguments(obj) {
|
|
11
12
|
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
|
@@ -46,6 +47,13 @@ export var values = function values(obj) {
|
|
|
46
47
|
export function round(num, decimals) {
|
|
47
48
|
return +num.toFixed(decimals);
|
|
48
49
|
}
|
|
50
|
+
export function toServerDuration(duration) {
|
|
51
|
+
if (!isNumber(duration)) {
|
|
52
|
+
return duration;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return round(duration * 1e6, 0);
|
|
56
|
+
}
|
|
49
57
|
export function msToNs(duration) {
|
|
50
58
|
if (typeof duration !== 'number') {
|
|
51
59
|
return duration;
|
|
@@ -68,6 +76,9 @@ export var isBoolean = function isBoolean(obj) {
|
|
|
68
76
|
export var isNumber = function isNumber(obj) {
|
|
69
77
|
return toString.call(obj) === '[object Number]' && /[\d\.]+/.test(String(obj));
|
|
70
78
|
};
|
|
79
|
+
export var isArray = nativeIsArray || function (obj) {
|
|
80
|
+
return toString.call(obj) === '[object Array]';
|
|
81
|
+
};
|
|
71
82
|
export var toArray = function toArray(iterable) {
|
|
72
83
|
if (!iterable) return [];
|
|
73
84
|
|
|
@@ -149,6 +160,92 @@ export function jsonStringify(value, replacer, space) {
|
|
|
149
160
|
|
|
150
161
|
return result;
|
|
151
162
|
}
|
|
163
|
+
export var utf8Encode = function utf8Encode(string) {
|
|
164
|
+
string = (string + '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
165
|
+
var utftext = '',
|
|
166
|
+
start,
|
|
167
|
+
end;
|
|
168
|
+
var stringl = 0,
|
|
169
|
+
n;
|
|
170
|
+
start = end = 0;
|
|
171
|
+
stringl = string.length;
|
|
172
|
+
|
|
173
|
+
for (n = 0; n < stringl; n++) {
|
|
174
|
+
var c1 = string.charCodeAt(n);
|
|
175
|
+
var enc = null;
|
|
176
|
+
|
|
177
|
+
if (c1 < 128) {
|
|
178
|
+
end++;
|
|
179
|
+
} else if (c1 > 127 && c1 < 2048) {
|
|
180
|
+
enc = String.fromCharCode(c1 >> 6 | 192, c1 & 63 | 128);
|
|
181
|
+
} else {
|
|
182
|
+
enc = String.fromCharCode(c1 >> 12 | 224, c1 >> 6 & 63 | 128, c1 & 63 | 128);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (enc !== null) {
|
|
186
|
+
if (end > start) {
|
|
187
|
+
utftext += string.substring(start, end);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
utftext += enc;
|
|
191
|
+
start = end = n + 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (end > start) {
|
|
196
|
+
utftext += string.substring(start, string.length);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return utftext;
|
|
200
|
+
};
|
|
201
|
+
export var base64Encode = function base64Encode(data) {
|
|
202
|
+
data = String(data);
|
|
203
|
+
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
204
|
+
var o1,
|
|
205
|
+
o2,
|
|
206
|
+
o3,
|
|
207
|
+
h1,
|
|
208
|
+
h2,
|
|
209
|
+
h3,
|
|
210
|
+
h4,
|
|
211
|
+
bits,
|
|
212
|
+
i = 0,
|
|
213
|
+
ac = 0,
|
|
214
|
+
enc = '',
|
|
215
|
+
tmp_arr = [];
|
|
216
|
+
|
|
217
|
+
if (!data) {
|
|
218
|
+
return data;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
data = utf8Encode(data);
|
|
222
|
+
|
|
223
|
+
do {
|
|
224
|
+
o1 = data.charCodeAt(i++);
|
|
225
|
+
o2 = data.charCodeAt(i++);
|
|
226
|
+
o3 = data.charCodeAt(i++);
|
|
227
|
+
bits = o1 << 16 | o2 << 8 | o3;
|
|
228
|
+
h1 = bits >> 18 & 0x3f;
|
|
229
|
+
h2 = bits >> 12 & 0x3f;
|
|
230
|
+
h3 = bits >> 6 & 0x3f;
|
|
231
|
+
h4 = bits & 0x3f;
|
|
232
|
+
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
|
|
233
|
+
} while (i < data.length);
|
|
234
|
+
|
|
235
|
+
enc = tmp_arr.join('');
|
|
236
|
+
|
|
237
|
+
switch (data.length % 3) {
|
|
238
|
+
case 1:
|
|
239
|
+
enc = enc.slice(0, -2) + '==';
|
|
240
|
+
break;
|
|
241
|
+
|
|
242
|
+
case 2:
|
|
243
|
+
enc = enc.slice(0, -1) + '=';
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return enc;
|
|
248
|
+
};
|
|
152
249
|
|
|
153
250
|
function hasToJSON(value) {
|
|
154
251
|
return typeof value === 'object' && value !== null && value.hasOwnProperty('toJSON');
|
|
@@ -191,6 +288,29 @@ export var getQueryParamsFromUrl = function getQueryParamsFromUrl(url) {
|
|
|
191
288
|
|
|
192
289
|
return result;
|
|
193
290
|
};
|
|
291
|
+
export var getURLSearchParams = function getURLSearchParams(queryString) {
|
|
292
|
+
queryString = queryString || '';
|
|
293
|
+
|
|
294
|
+
var decodeParam = function decodeParam(str) {
|
|
295
|
+
return decodeURIComponent(str);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
var args = {};
|
|
299
|
+
var query = queryString.substring(1);
|
|
300
|
+
var pairs = query.split('&');
|
|
301
|
+
|
|
302
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
303
|
+
var pos = pairs[i].indexOf('=');
|
|
304
|
+
if (pos === -1) continue;
|
|
305
|
+
var name = pairs[i].substring(0, pos);
|
|
306
|
+
var value = pairs[i].substring(pos + 1);
|
|
307
|
+
name = decodeParam(name);
|
|
308
|
+
value = decodeParam(value);
|
|
309
|
+
args[name] = value;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return args;
|
|
313
|
+
};
|
|
194
314
|
export function isPercentage(value) {
|
|
195
315
|
return isNumber(value) && value >= 0 && value <= 100;
|
|
196
316
|
}
|
|
@@ -353,7 +473,12 @@ export function toSnakeCase(word) {
|
|
|
353
473
|
}).replace(/-/g, '_');
|
|
354
474
|
}
|
|
355
475
|
export function escapeRowData(str) {
|
|
356
|
-
if (
|
|
476
|
+
if (typeof str === 'object' && str) {
|
|
477
|
+
str = jsonStringify(str);
|
|
478
|
+
} else if (!isString(str)) {
|
|
479
|
+
return str;
|
|
480
|
+
}
|
|
481
|
+
|
|
357
482
|
var reg = /[\s=,"]/g;
|
|
358
483
|
return String(str).replace(reg, function (word) {
|
|
359
484
|
return '\\' + word;
|
|
@@ -423,8 +548,8 @@ export var urlParse = function urlParse(para) {
|
|
|
423
548
|
|
|
424
549
|
URLParser.prototype.getUrl = function () {
|
|
425
550
|
var url = '';
|
|
426
|
-
url += this._values.Origin;
|
|
427
|
-
|
|
551
|
+
url += this._values.Origin; // url += this._values.Port ? ':' + this._values.Port : ''
|
|
552
|
+
|
|
428
553
|
url += this._values.Path;
|
|
429
554
|
url += this._values.QueryString ? '?' + this._values.QueryString : '';
|
|
430
555
|
return url;
|
|
@@ -445,8 +570,9 @@ export var urlParse = function urlParse(para) {
|
|
|
445
570
|
}
|
|
446
571
|
}
|
|
447
572
|
|
|
573
|
+
this._values['Path'] = this._values['Path'] || '/';
|
|
448
574
|
this._values['Hostname'] = this._values['Host'].replace(/:\d+$/, '');
|
|
449
|
-
this._values['Origin'] = this._values['Protocol'] + '://' + this._values['Hostname'];
|
|
575
|
+
this._values['Origin'] = this._values['Protocol'] + '://' + this._values['Hostname'] + (this._values.Port ? ':' + this._values.Port : '');
|
|
450
576
|
};
|
|
451
577
|
|
|
452
578
|
return new URLParser(para);
|
|
@@ -502,4 +628,41 @@ export var deepMixObject = function deepMixObject(targetObj) {
|
|
|
502
628
|
}
|
|
503
629
|
|
|
504
630
|
return targetObj;
|
|
505
|
-
};
|
|
631
|
+
};
|
|
632
|
+
export function getOrigin(url) {
|
|
633
|
+
return urlParse(url).getParse().Origin;
|
|
634
|
+
}
|
|
635
|
+
export function createContextManager() {
|
|
636
|
+
var context = {};
|
|
637
|
+
return {
|
|
638
|
+
get: function get() {
|
|
639
|
+
return context;
|
|
640
|
+
},
|
|
641
|
+
add: function add(key, value) {
|
|
642
|
+
if (isString(key)) {
|
|
643
|
+
context[key] = value;
|
|
644
|
+
} else {
|
|
645
|
+
console.error('key 需要传递字符串类型');
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
remove: function remove(key) {
|
|
649
|
+
delete context[key];
|
|
650
|
+
},
|
|
651
|
+
set: function set(newContext) {
|
|
652
|
+
if (isObject(newContext)) {
|
|
653
|
+
context = newContext;
|
|
654
|
+
} else {
|
|
655
|
+
console.error('content 需要传递对象类型数据');
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
export function getActivePage() {
|
|
661
|
+
var curPages = typeof getCurrentPages === 'function' ? getCurrentPages() : [];
|
|
662
|
+
|
|
663
|
+
if (curPages.length) {
|
|
664
|
+
return curPages[curPages.length - 1];
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return {};
|
|
668
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extend2Lev, withSnakeCaseKeys, performDraw } from '../helper/utils';
|
|
1
|
+
import { extend2Lev, withSnakeCaseKeys, performDraw, isEmptyObject } from '../helper/utils';
|
|
2
2
|
import { LifeCycleEventType } from '../core/lifeCycle';
|
|
3
3
|
import { RumEventType } from '../helper/enums';
|
|
4
4
|
import baseInfo from '../core/baseInfo';
|
|
@@ -11,17 +11,20 @@ var SessionType = {
|
|
|
11
11
|
SYNTHETICS: 'synthetics',
|
|
12
12
|
USER: 'user'
|
|
13
13
|
};
|
|
14
|
-
export function startRumAssembly(applicationId, configuration, lifeCycle, parentContexts) {
|
|
14
|
+
export function startRumAssembly(applicationId, configuration, lifeCycle, parentContexts, getCommonContext) {
|
|
15
15
|
lifeCycle.subscribe(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, function (data) {
|
|
16
16
|
var startTime = data.startTime;
|
|
17
17
|
var rawRumEvent = data.rawRumEvent;
|
|
18
18
|
var viewContext = parentContexts.findView(startTime);
|
|
19
|
+
var savedCommonContext = data.savedGlobalContext;
|
|
20
|
+
var customerContext = data.customerContext;
|
|
19
21
|
var deviceContext = {
|
|
20
22
|
device: baseInfo.deviceInfo
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
if (isTracked(configuration) && (viewContext || rawRumEvent.type === RumEventType.APP)) {
|
|
24
26
|
var actionContext = parentContexts.findAction(startTime);
|
|
27
|
+
var commonContext = savedCommonContext || getCommonContext();
|
|
25
28
|
var rumContext = {
|
|
26
29
|
_dd: {
|
|
27
30
|
sdkName: configuration.sdkName,
|
|
@@ -40,12 +43,26 @@ export function startRumAssembly(applicationId, configuration, lifeCycle, parent
|
|
|
40
43
|
type: SessionType.USER
|
|
41
44
|
},
|
|
42
45
|
user: {
|
|
43
|
-
|
|
46
|
+
id: configuration.user_id || baseInfo.getClientID(),
|
|
44
47
|
is_signin: configuration.user_id ? 'T' : 'F'
|
|
45
48
|
}
|
|
46
49
|
};
|
|
47
50
|
var rumEvent = extend2Lev(rumContext, deviceContext, viewContext, actionContext, rawRumEvent);
|
|
48
51
|
var serverRumEvent = withSnakeCaseKeys(rumEvent);
|
|
52
|
+
var context = extend2Lev(commonContext.context, customerContext);
|
|
53
|
+
|
|
54
|
+
if (!isEmptyObject(context)) {
|
|
55
|
+
serverRumEvent.tags = context;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!isEmptyObject(commonContext.user)) {
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
60
|
+
serverRumEvent.user = extend2Lev({
|
|
61
|
+
id: baseInfo.getClientID(),
|
|
62
|
+
is_signin: 'T'
|
|
63
|
+
}, commonContext.user);
|
|
64
|
+
}
|
|
65
|
+
|
|
49
66
|
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, serverRumEvent);
|
|
50
67
|
}
|
|
51
68
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extend, now, throttle, UUID, isNumber } from '../../helper/utils';
|
|
1
|
+
import { extend, now, throttle, UUID, isNumber, getActivePage } from '../../helper/utils';
|
|
2
2
|
import { trackEventCounts } from '../trackEventCounts';
|
|
3
3
|
import { LifeCycleEventType } from '../../core/lifeCycle';
|
|
4
4
|
import { sdk } from '../../core/sdk'; // 劫持原小程序App方法
|
|
@@ -213,14 +213,4 @@ function trackSetDataTime(lifeCycle, callback) {
|
|
|
213
213
|
return {
|
|
214
214
|
stop: subscribe.unsubscribe
|
|
215
215
|
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function getActivePage() {
|
|
219
|
-
var curPages = getCurrentPages();
|
|
220
|
-
|
|
221
|
-
if (curPages.length) {
|
|
222
|
-
return curPages[curPages.length - 1];
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return {};
|
|
226
216
|
}
|
|
@@ -3,9 +3,11 @@ import { startDownloadProxy } from '../core/downloadProxy';
|
|
|
3
3
|
import { LifeCycleEventType } from '../core/lifeCycle';
|
|
4
4
|
import { isObject } from '../helper/utils';
|
|
5
5
|
import { isAllowedRequestUrl } from '../rumEventsCollection/resource/resourceUtils';
|
|
6
|
+
import { startTracer } from '../rumEventsCollection/tracing/tracer';
|
|
6
7
|
var nextRequestIndex = 1;
|
|
7
8
|
export function startRequestCollection(lifeCycle, configuration) {
|
|
8
|
-
|
|
9
|
+
var tracer = startTracer(configuration);
|
|
10
|
+
trackXhr(lifeCycle, configuration, tracer);
|
|
9
11
|
trackDownload(lifeCycle, configuration);
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -28,10 +30,11 @@ function getHeaderString(header) {
|
|
|
28
30
|
return headerStr;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
export function trackXhr(lifeCycle, configuration) {
|
|
33
|
+
export function trackXhr(lifeCycle, configuration, tracer) {
|
|
32
34
|
var xhrProxy = startXhrProxy();
|
|
33
35
|
xhrProxy.beforeSend(function (context) {
|
|
34
36
|
if (isAllowedRequestUrl(configuration, context.url)) {
|
|
37
|
+
tracer.traceXhr(context);
|
|
35
38
|
context.requestIndex = getNextRequestIndex();
|
|
36
39
|
lifeCycle.notify(LifeCycleEventType.REQUEST_STARTED, {
|
|
37
40
|
requestIndex: context.requestIndex
|
|
@@ -40,6 +43,7 @@ export function trackXhr(lifeCycle, configuration) {
|
|
|
40
43
|
});
|
|
41
44
|
xhrProxy.onRequestComplete(function (context) {
|
|
42
45
|
if (isAllowedRequestUrl(configuration, context.url)) {
|
|
46
|
+
tracer.clearTracingIfCancelled(context);
|
|
43
47
|
lifeCycle.notify(LifeCycleEventType.REQUEST_COMPLETED, {
|
|
44
48
|
duration: context.duration,
|
|
45
49
|
method: context.method,
|
|
@@ -48,6 +52,8 @@ export function trackXhr(lifeCycle, configuration) {
|
|
|
48
52
|
response: context.response,
|
|
49
53
|
startTime: context.startTime,
|
|
50
54
|
status: context.status,
|
|
55
|
+
traceId: context.traceId,
|
|
56
|
+
spanId: context.spanId,
|
|
51
57
|
type: context.type,
|
|
52
58
|
url: context.url
|
|
53
59
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computePerformanceResourceDuration, computePerformanceResourceDetails, computeSize } from './resourceUtils';
|
|
2
2
|
import { LifeCycleEventType } from '../../core/lifeCycle';
|
|
3
|
-
import { msToNs, extend2Lev, urlParse, getQueryParamsFromUrl, replaceNumberCharByPath, jsonStringify, getStatusGroup } from '../../helper/utils';
|
|
3
|
+
import { msToNs, extend2Lev, urlParse, getQueryParamsFromUrl, replaceNumberCharByPath, jsonStringify, UUID, getStatusGroup } from '../../helper/utils';
|
|
4
4
|
import { RumEventType } from '../../helper/enums';
|
|
5
5
|
export function startResourceCollection(lifeCycle, configuration) {
|
|
6
6
|
lifeCycle.subscribe(LifeCycleEventType.REQUEST_COMPLETED, function (request) {
|
|
@@ -12,8 +12,10 @@ function processRequest(request) {
|
|
|
12
12
|
var type = request.type;
|
|
13
13
|
var timing = request.performance;
|
|
14
14
|
var correspondingTimingOverrides = timing ? computePerformanceEntryMetrics(timing) : undefined;
|
|
15
|
+
var tracingInfo = computeRequestTracingInfo(request);
|
|
15
16
|
var urlObj = urlParse(request.url).getParse();
|
|
16
17
|
var startTime = request.startTime;
|
|
18
|
+
console.log(request, 'request=========');
|
|
17
19
|
var resourceEvent = extend2Lev({
|
|
18
20
|
date: startTime,
|
|
19
21
|
resource: {
|
|
@@ -29,13 +31,31 @@ function processRequest(request) {
|
|
|
29
31
|
urlQuery: jsonStringify(getQueryParamsFromUrl(request.url))
|
|
30
32
|
},
|
|
31
33
|
type: RumEventType.RESOURCE
|
|
32
|
-
}, correspondingTimingOverrides);
|
|
34
|
+
}, tracingInfo, correspondingTimingOverrides);
|
|
33
35
|
return {
|
|
34
36
|
startTime: startTime,
|
|
35
37
|
rawRumEvent: resourceEvent
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
function computeRequestTracingInfo(request) {
|
|
42
|
+
var hasBeenTraced = request.traceId && request.spanId;
|
|
43
|
+
|
|
44
|
+
if (!hasBeenTraced) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
_dd: {
|
|
50
|
+
spanId: request.spanId,
|
|
51
|
+
traceId: request.traceId
|
|
52
|
+
},
|
|
53
|
+
resource: {
|
|
54
|
+
id: UUID()
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
39
59
|
function computePerformanceEntryMetrics(timing) {
|
|
40
60
|
return {
|
|
41
61
|
resource: extend2Lev({}, {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// === Generate a random 64-bit number in fixed-length hex format
|
|
2
|
+
function randomTraceId() {
|
|
3
|
+
var digits = '0123456789abcdef';
|
|
4
|
+
var n = '';
|
|
5
|
+
|
|
6
|
+
for (var i = 0; i < 19; i += 1) {
|
|
7
|
+
var rand = Math.floor(Math.random() * 10);
|
|
8
|
+
n += digits[rand];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return n;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {*} configuration 配置信息
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export function DDtraceTracer(configuration) {
|
|
20
|
+
this._spanId = randomTraceId();
|
|
21
|
+
this._traceId = randomTraceId();
|
|
22
|
+
}
|
|
23
|
+
DDtraceTracer.prototype = {
|
|
24
|
+
isTracingSupported: function isTracingSupported() {
|
|
25
|
+
return true;
|
|
26
|
+
},
|
|
27
|
+
getSpanId: function getSpanId() {
|
|
28
|
+
return this._spanId;
|
|
29
|
+
},
|
|
30
|
+
getTraceId: function getTraceId() {
|
|
31
|
+
return this._traceId;
|
|
32
|
+
},
|
|
33
|
+
makeTracingHeaders: function makeTracingHeaders() {
|
|
34
|
+
return {
|
|
35
|
+
'x-datadog-origin': 'rum',
|
|
36
|
+
// 'x-datadog-parent-id': spanId.toDecimalString(),
|
|
37
|
+
'x-datadog-sampled': '1',
|
|
38
|
+
'x-datadog-sampling-priority': '1',
|
|
39
|
+
'x-datadog-trace-id': this.getTraceId()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// === Generate a random 64-bit number in fixed-length hex format
|
|
2
|
+
function randomTraceId() {
|
|
3
|
+
var digits = '0123456789abcdef';
|
|
4
|
+
var n = '';
|
|
5
|
+
|
|
6
|
+
for (var i = 0; i < 16; i += 1) {
|
|
7
|
+
var rand = Math.floor(Math.random() * 16);
|
|
8
|
+
n += digits[rand];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return n;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {*} configuration 配置信息
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export function JaegerTracer(configuration) {
|
|
20
|
+
var rootSpanId = randomTraceId(); // this._traceId = randomTraceId() + rootSpanId // 默认用128bit,兼容其他配置
|
|
21
|
+
|
|
22
|
+
if (configuration.traceId128Bit) {
|
|
23
|
+
// 128bit生成traceid
|
|
24
|
+
this._traceId = randomTraceId() + rootSpanId;
|
|
25
|
+
} else {
|
|
26
|
+
this._traceId = rootSpanId;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this._spanId = rootSpanId;
|
|
30
|
+
}
|
|
31
|
+
JaegerTracer.prototype = {
|
|
32
|
+
isTracingSupported: function isTracingSupported() {
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
getSpanId: function getSpanId() {
|
|
36
|
+
return this._spanId;
|
|
37
|
+
},
|
|
38
|
+
getTraceId: function getTraceId() {
|
|
39
|
+
return this._traceId;
|
|
40
|
+
},
|
|
41
|
+
getUberTraceId: function getUberTraceId() {
|
|
42
|
+
//{trace-id}:{span-id}:{parent-span-id}:{flags}
|
|
43
|
+
return this._traceId + ':' + this._spanId + ':' + '0' + ':' + '1';
|
|
44
|
+
},
|
|
45
|
+
makeTracingHeaders: function makeTracingHeaders() {
|
|
46
|
+
return {
|
|
47
|
+
'uber-trace-id': this.getUberTraceId()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { base64Encode, urlParse, getActivePage } from '../../helper/utils'; // start SkyWalking
|
|
2
|
+
|
|
3
|
+
function uuid() {
|
|
4
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
5
|
+
/* tslint:disable */
|
|
6
|
+
var r = Math.random() * 16 | 0;
|
|
7
|
+
/* tslint:disable */
|
|
8
|
+
|
|
9
|
+
var v = c === 'x' ? r : r & 0x3 | 0x8;
|
|
10
|
+
return v.toString(16);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {*} configuration 配置信息
|
|
16
|
+
* @param {*} requestUrl 请求的url
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export function SkyWalkingTracer(configuration, requestUrl) {
|
|
21
|
+
this._spanId = uuid();
|
|
22
|
+
this._traceId = uuid();
|
|
23
|
+
this._applicationId = configuration.applicationId;
|
|
24
|
+
this._env = configuration.env;
|
|
25
|
+
this._version = configuration.version;
|
|
26
|
+
this._urlParse = urlParse(requestUrl).getParse();
|
|
27
|
+
}
|
|
28
|
+
SkyWalkingTracer.prototype = {
|
|
29
|
+
isTracingSupported: function isTracingSupported() {
|
|
30
|
+
if (this._env && this._version && this._urlParse) return true;
|
|
31
|
+
return false;
|
|
32
|
+
},
|
|
33
|
+
getSpanId: function getSpanId() {
|
|
34
|
+
return this._spanId;
|
|
35
|
+
},
|
|
36
|
+
getTraceId: function getTraceId() {
|
|
37
|
+
return this._traceId;
|
|
38
|
+
},
|
|
39
|
+
getSkyWalkingSw8: function getSkyWalkingSw8() {
|
|
40
|
+
try {
|
|
41
|
+
var traceIdStr = String(base64Encode(this._traceId));
|
|
42
|
+
var segmentId = String(base64Encode(this._spanId));
|
|
43
|
+
var service = String(base64Encode(this._applicationId + '_rum_' + this.env));
|
|
44
|
+
var instance = String(base64Encode(this._version));
|
|
45
|
+
var activePage = getActivePage();
|
|
46
|
+
var endpointPage = '';
|
|
47
|
+
|
|
48
|
+
if (activePage && activePage.route) {
|
|
49
|
+
endpointPage = activePage.route;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var endpoint = String(base64Encode(endpointPage));
|
|
53
|
+
var peer = String(base64Encode(this._urlParse.Host));
|
|
54
|
+
var index = '0'; // var values = `${1}-${traceIdStr}-${segmentId}-${index}-${service}-${instance}-${endpoint}-${peer}`;
|
|
55
|
+
|
|
56
|
+
return '1-' + traceIdStr + '-' + segmentId + '-' + index + '-' + service + '-' + instance + '-' + endpoint + '-' + peer;
|
|
57
|
+
} catch (err) {
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
makeTracingHeaders: function makeTracingHeaders() {
|
|
62
|
+
return {
|
|
63
|
+
'sw8': this.getSkyWalkingSw8()
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { each, extend, getOrigin } from '../../helper/utils';
|
|
2
|
+
import { TraceType } from '../../helper/enums';
|
|
3
|
+
import { DDtraceTracer } from './ddtraceTracer';
|
|
4
|
+
import { SkyWalkingTracer } from './skywalkingTracer';
|
|
5
|
+
import { JaegerTracer } from './jaegerTracer';
|
|
6
|
+
import { ZipkinSingleTracer } from './zipkinSingleTracer';
|
|
7
|
+
import { ZipkinMultiTracer } from './zipkinMultiTracer';
|
|
8
|
+
import { W3cTraceParentTracer } from './w3cTraceParentTracer';
|
|
9
|
+
export function clearTracingIfCancelled(context) {
|
|
10
|
+
if (context.status === 0) {
|
|
11
|
+
context.traceId = undefined;
|
|
12
|
+
context.spanId = undefined;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function startTracer(configuration) {
|
|
16
|
+
return {
|
|
17
|
+
clearTracingIfCancelled: clearTracingIfCancelled,
|
|
18
|
+
traceXhr: function traceXhr(context) {
|
|
19
|
+
return injectHeadersIfTracingAllowed(configuration, context, function (tracingHeaders) {
|
|
20
|
+
context.option = extend({}, context.option);
|
|
21
|
+
var header = {};
|
|
22
|
+
|
|
23
|
+
if (context.option.header) {
|
|
24
|
+
each(context.option.header, function (value, key) {
|
|
25
|
+
header[key] = value;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
context.option.header = extend(header, tracingHeaders);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isAllowedUrl(configuration, requestUrl) {
|
|
36
|
+
var requestOrigin = getOrigin(requestUrl);
|
|
37
|
+
var flag = false;
|
|
38
|
+
each(configuration.allowedTracingOrigins, function (allowedOrigin) {
|
|
39
|
+
if (requestOrigin === allowedOrigin || allowedOrigin instanceof RegExp && allowedOrigin.test(requestOrigin)) {
|
|
40
|
+
flag = true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return flag;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function injectHeadersIfTracingAllowed(configuration, context, inject) {
|
|
48
|
+
if (!isAllowedUrl(configuration, context.url) || !configuration.traceType) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var tracer;
|
|
53
|
+
|
|
54
|
+
switch (configuration.traceType) {
|
|
55
|
+
case TraceType.DDTRACE:
|
|
56
|
+
tracer = new DDtraceTracer();
|
|
57
|
+
break;
|
|
58
|
+
|
|
59
|
+
case TraceType.SKYWALKING_V3:
|
|
60
|
+
tracer = new SkyWalkingTracer(configuration, context.url);
|
|
61
|
+
break;
|
|
62
|
+
|
|
63
|
+
case TraceType.ZIPKIN_MULTI_HEADER:
|
|
64
|
+
tracer = new ZipkinMultiTracer(configuration);
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case TraceType.JAEGER:
|
|
68
|
+
tracer = new JaegerTracer(configuration);
|
|
69
|
+
break;
|
|
70
|
+
|
|
71
|
+
case TraceType.W3C_TRACEPARENT:
|
|
72
|
+
tracer = new W3cTraceParentTracer(configuration);
|
|
73
|
+
break;
|
|
74
|
+
|
|
75
|
+
case TraceType.ZIPKIN_SINGLE_HEADER:
|
|
76
|
+
tracer = new ZipkinSingleTracer(configuration);
|
|
77
|
+
break;
|
|
78
|
+
|
|
79
|
+
default:
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!tracer || !tracer.isTracingSupported()) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
context.traceId = tracer.getTraceId();
|
|
88
|
+
context.spanId = tracer.getSpanId();
|
|
89
|
+
inject(tracer.makeTracingHeaders());
|
|
90
|
+
}
|