@newrelic/browser-agent 1.232.1 → 1.233.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/dist/cjs/cdn/polyfills.js +5 -2
- package/dist/cjs/common/config/state/configurable.js +15 -26
- package/dist/cjs/common/config/state/info.js +1 -1
- package/dist/cjs/common/config/state/init.js +101 -56
- package/dist/cjs/common/config/state/loader-config.js +1 -1
- package/dist/cjs/common/config/state/runtime.js +1 -5
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/harvest/harvest-scheduler.js +30 -10
- package/dist/cjs/common/harvest/harvest.js +119 -55
- package/dist/cjs/common/session/session-entity.js +35 -22
- package/dist/cjs/common/session/session-entity.test.js +73 -49
- package/dist/cjs/common/timer/interaction-timer.js +9 -12
- package/dist/cjs/common/url/protocol.test.js +0 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/util/submit-data.js +57 -18
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -1
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/common/wrap/wrap-promise.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +7 -5
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +67 -0
- package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +137 -0
- package/dist/cjs/features/metrics/aggregate/index.js +7 -3
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +14 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +17 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +53 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +165 -0
- package/dist/cjs/features/page_action/aggregate/index.js +2 -2
- package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
- package/dist/cjs/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/cjs/features/session_replay/aggregate/index.js +333 -0
- package/dist/cjs/features/session_replay/constants.js +9 -0
- package/dist/cjs/features/session_replay/index.js +12 -0
- package/dist/cjs/features/session_replay/instrument/index.js +29 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +163 -162
- package/dist/cjs/features/session_trace/constants.js +2 -9
- package/dist/cjs/features/session_trace/instrument/index.js +24 -66
- package/dist/cjs/features/spa/aggregate/index.js +2 -2
- package/dist/cjs/features/utils/agent-session.js +1 -2
- package/dist/cjs/features/utils/aggregate-base.js +64 -0
- package/dist/cjs/features/utils/feature-base.js +0 -31
- package/dist/cjs/features/utils/handler-cache.js +3 -4
- package/dist/cjs/features/utils/instrument-base.js +42 -10
- package/dist/cjs/features/utils/{lazy-loader.js → lazy-feature-loader.js} +4 -2
- package/dist/cjs/loaders/agent.js +1 -1
- package/dist/cjs/loaders/api/apiAsync.js +3 -1
- package/dist/cjs/loaders/configure/configure.js +3 -3
- package/dist/cjs/loaders/features/featureDependencies.js +0 -12
- package/dist/cjs/loaders/features/features.js +3 -1
- package/dist/cjs/loaders/micro-agent.js +6 -6
- package/dist/esm/cdn/polyfills.js +5 -2
- package/dist/esm/common/config/state/configurable.js +14 -24
- package/dist/esm/common/config/state/info.js +2 -2
- package/dist/esm/common/config/state/init.js +102 -57
- package/dist/esm/common/config/state/loader-config.js +2 -2
- package/dist/esm/common/config/state/runtime.js +2 -4
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +30 -10
- package/dist/esm/common/harvest/harvest.js +121 -56
- package/dist/esm/common/session/session-entity.js +35 -22
- package/dist/esm/common/session/session-entity.test.js +73 -49
- package/dist/esm/common/timer/interaction-timer.js +9 -12
- package/dist/esm/common/url/protocol.test.js +0 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/util/submit-data.js +57 -18
- package/dist/esm/common/wrap/wrap-fetch.js +1 -1
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-promise.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/jserrors/aggregate/index.js +7 -5
- package/dist/esm/features/metrics/aggregate/framework-detection.js +61 -0
- package/dist/esm/features/metrics/aggregate/framework-detection.test.js +133 -0
- package/dist/esm/features/metrics/aggregate/index.js +7 -3
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +8 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +15 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.js +47 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/dist/esm/features/page_action/aggregate/index.js +2 -2
- package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
- package/dist/esm/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/esm/features/session_replay/aggregate/index.js +327 -0
- package/dist/esm/features/session_replay/constants.js +2 -0
- package/dist/esm/features/session_replay/index.js +12 -0
- package/dist/esm/features/session_replay/instrument/index.js +21 -0
- package/dist/esm/features/session_trace/aggregate/index.js +163 -162
- package/dist/esm/features/session_trace/constants.js +1 -5
- package/dist/esm/features/session_trace/instrument/index.js +24 -66
- package/dist/esm/features/spa/aggregate/index.js +2 -2
- package/dist/esm/features/utils/agent-session.js +1 -2
- package/dist/esm/features/utils/aggregate-base.js +57 -0
- package/dist/esm/features/utils/feature-base.js +1 -32
- package/dist/esm/features/utils/handler-cache.js +3 -4
- package/dist/esm/features/utils/instrument-base.js +42 -10
- package/dist/esm/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/dist/esm/loaders/agent.js +1 -1
- package/dist/esm/loaders/api/apiAsync.js +3 -1
- package/dist/esm/loaders/configure/configure.js +3 -3
- package/dist/esm/loaders/features/featureDependencies.js +0 -11
- package/dist/esm/loaders/features/features.js +3 -1
- package/dist/esm/loaders/micro-agent.js +6 -6
- package/dist/types/common/config/state/configurable.d.ts +1 -3
- package/dist/types/common/config/state/configurable.d.ts.map +1 -1
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +37 -34
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +6 -3
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +2 -1
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/submit-data.d.ts +40 -14
- package/dist/types/common/util/submit-data.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +6 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +7 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -0
- package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +96 -0
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/constants.d.ts +2 -0
- package/dist/types/features/session_replay/constants.d.ts.map +1 -0
- package/dist/types/features/session_replay/index.d.ts +2 -0
- package/dist/types/features/session_replay/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts +6 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -0
- package/dist/types/features/session_trace/aggregate/index.d.ts +8 -57
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts +0 -3
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +1 -3
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +2 -2
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +11 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -0
- package/dist/types/features/utils/feature-base.d.ts +0 -5
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +3 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/features/utils/{lazy-loader.d.ts → lazy-feature-loader.d.ts} +2 -2
- package/dist/types/features/utils/lazy-feature-loader.d.ts.map +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/featureDependencies.d.ts +0 -1
- package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +1 -0
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/package.json +28 -19
- package/src/cdn/polyfills.js +4 -1
- package/src/common/config/state/configurable.js +18 -24
- package/src/common/config/state/info.js +2 -2
- package/src/common/config/state/init.js +62 -28
- package/src/common/config/state/loader-config.js +2 -2
- package/src/common/config/state/runtime.js +2 -4
- package/src/common/drain/drain.js +1 -1
- package/src/common/harvest/harvest-scheduler.js +35 -10
- package/src/common/harvest/harvest.js +73 -50
- package/src/common/session/session-entity.js +34 -23
- package/src/common/session/session-entity.test.js +57 -51
- package/src/common/timer/interaction-timer.js +9 -12
- package/src/common/url/protocol.test.js +0 -1
- package/src/common/util/feature-flags.js +2 -2
- package/src/common/util/submit-data.js +28 -17
- package/src/common/wrap/wrap-fetch.js +1 -1
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-promise.js +1 -1
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/jserrors/aggregate/index.js +7 -5
- package/src/features/metrics/aggregate/framework-detection.js +73 -0
- package/src/features/metrics/aggregate/framework-detection.test.js +201 -0
- package/src/features/metrics/aggregate/index.js +8 -3
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +9 -0
- package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +16 -0
- package/src/features/metrics/aggregate/polyfill-detection.js +48 -0
- package/src/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/src/features/page_action/aggregate/index.js +2 -2
- package/src/features/page_view_event/aggregate/index.js +5 -5
- package/src/features/page_view_timing/aggregate/index.js +2 -2
- package/src/features/session_replay/aggregate/index.js +314 -0
- package/src/features/session_replay/constants.js +3 -0
- package/src/features/session_replay/index.js +12 -0
- package/src/features/session_replay/instrument/index.js +22 -0
- package/src/features/session_trace/aggregate/index.js +148 -187
- package/src/features/session_trace/constants.js +0 -4
- package/src/features/session_trace/instrument/index.js +17 -69
- package/src/features/spa/aggregate/index.js +2 -2
- package/src/features/utils/agent-session.js +1 -2
- package/src/features/utils/aggregate-base.js +51 -0
- package/src/features/utils/feature-base.js +1 -31
- package/src/features/utils/handler-cache.js +3 -4
- package/src/features/utils/instrument-base.js +40 -8
- package/src/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/src/loaders/agent.js +1 -1
- package/src/loaders/api/apiAsync.js +1 -1
- package/src/loaders/configure/configure.js +4 -3
- package/src/loaders/features/featureDependencies.js +0 -12
- package/src/loaders/features/features.js +3 -1
- package/src/loaders/micro-agent.js +4 -4
- package/dist/cjs/common/metrics/framework-detection.js +0 -72
- package/dist/cjs/common/util/user-agent.js +0 -57
- package/dist/cjs/common/window/supports-performance-observer.js +0 -15
- package/dist/esm/common/metrics/framework-detection.js +0 -66
- package/dist/esm/common/util/user-agent.js +0 -48
- package/dist/esm/common/window/supports-performance-observer.js +0 -9
- package/dist/types/common/metrics/framework-detection.d.ts.map +0 -1
- package/dist/types/common/util/user-agent.d.ts +0 -5
- package/dist/types/common/util/user-agent.d.ts.map +0 -1
- package/dist/types/common/window/supports-performance-observer.d.ts +0 -2
- package/dist/types/common/window/supports-performance-observer.d.ts.map +0 -1
- package/dist/types/features/utils/lazy-loader.d.ts.map +0 -1
- package/src/common/metrics/framework-detection.js +0 -71
- package/src/common/util/user-agent.js +0 -56
- package/src/common/window/supports-performance-observer.js +0 -10
- /package/dist/types/{common/metrics → features/metrics/aggregate}/framework-detection.d.ts +0 -0
|
@@ -4,86 +4,62 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
6
6
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
7
|
-
import { mapOwn } from '../../../common/util/map-own';
|
|
8
7
|
import { stringify } from '../../../common/util/stringify';
|
|
9
8
|
import { parseUrl } from '../../../common/url/parse-url';
|
|
10
|
-
import { supportsPerformanceObserver } from '../../../common/window/supports-performance-observer';
|
|
11
9
|
import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
|
|
12
10
|
import { now } from '../../../common/timing/now';
|
|
13
11
|
import { FEATURE_NAME } from '../constants';
|
|
14
12
|
import { drain } from '../../../common/drain/drain';
|
|
15
13
|
import { HandlerCache } from '../../utils/handler-cache';
|
|
16
|
-
import {
|
|
17
|
-
|
|
14
|
+
import { AggregateBase } from '../../utils/aggregate-base';
|
|
15
|
+
const ignoredEvents = {
|
|
16
|
+
// we find that certain events make the data too noisy to be useful
|
|
17
|
+
global: {
|
|
18
|
+
mouseup: true,
|
|
19
|
+
mousedown: true
|
|
20
|
+
},
|
|
21
|
+
// certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
|
|
22
|
+
window: {
|
|
23
|
+
load: true,
|
|
24
|
+
pagehide: true
|
|
25
|
+
},
|
|
26
|
+
// when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
|
|
27
|
+
xhrOriginMissing: {
|
|
28
|
+
ignoreAll: true
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const toAggregate = {
|
|
32
|
+
typing: [1000, 2000],
|
|
33
|
+
scrolling: [100, 1000],
|
|
34
|
+
mousing: [1000, 2000],
|
|
35
|
+
touching: [1000, 2000]
|
|
36
|
+
};
|
|
37
|
+
const MAX_TRACE_DURATION = 15 * 60 * 1000; // 15 minutes
|
|
38
|
+
|
|
39
|
+
export class Aggregate extends AggregateBase {
|
|
18
40
|
static featureName = FEATURE_NAME;
|
|
19
|
-
constructor(agentIdentifier, aggregator) {
|
|
41
|
+
constructor(agentIdentifier, aggregator, argsObj) {
|
|
20
42
|
var _this;
|
|
21
43
|
// Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
|
|
22
44
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
23
45
|
_this = this;
|
|
24
46
|
if (!getRuntime(agentIdentifier).xhrWrappable) return;
|
|
25
|
-
|
|
47
|
+
this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
|
|
26
48
|
this.ptid = '';
|
|
27
|
-
this.ignoredEvents = {
|
|
28
|
-
// we find that certain events make the data too noisy to be useful
|
|
29
|
-
global: {
|
|
30
|
-
mouseup: true,
|
|
31
|
-
mousedown: true
|
|
32
|
-
},
|
|
33
|
-
// certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
|
|
34
|
-
window: {
|
|
35
|
-
load: true,
|
|
36
|
-
pagehide: true
|
|
37
|
-
},
|
|
38
|
-
// when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
|
|
39
|
-
xhrOriginMissing: {
|
|
40
|
-
ignoreAll: true
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
this.toAggregate = {
|
|
44
|
-
typing: [1000, 2000],
|
|
45
|
-
scrolling: [100, 1000],
|
|
46
|
-
mousing: [1000, 2000],
|
|
47
|
-
touching: [1000, 2000]
|
|
48
|
-
};
|
|
49
|
-
this.rename = {
|
|
50
|
-
typing: {
|
|
51
|
-
keydown: true,
|
|
52
|
-
keyup: true,
|
|
53
|
-
keypress: true
|
|
54
|
-
},
|
|
55
|
-
mousing: {
|
|
56
|
-
mousemove: true,
|
|
57
|
-
mouseenter: true,
|
|
58
|
-
mouseleave: true,
|
|
59
|
-
mouseover: true,
|
|
60
|
-
mouseout: true
|
|
61
|
-
},
|
|
62
|
-
scrolling: {
|
|
63
|
-
scroll: true
|
|
64
|
-
},
|
|
65
|
-
touching: {
|
|
66
|
-
touchstart: true,
|
|
67
|
-
touchmove: true,
|
|
68
|
-
touchend: true,
|
|
69
|
-
touchcancel: true,
|
|
70
|
-
touchenter: true,
|
|
71
|
-
touchleave: true
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
49
|
this.trace = {};
|
|
75
50
|
this.nodeCount = 0;
|
|
76
51
|
this.sentTrace = null;
|
|
77
52
|
this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
78
53
|
this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
79
54
|
this.laststart = 0;
|
|
55
|
+
const handlerCache = new HandlerCache();
|
|
80
56
|
registerHandler('feat-stn', () => {
|
|
81
57
|
if (typeof PerformanceNavigationTiming !== 'undefined') {
|
|
82
|
-
this.storeTiming(window.performance
|
|
58
|
+
this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
|
|
83
59
|
} else {
|
|
84
|
-
this.storeTiming(window.performance
|
|
60
|
+
this.storeTiming(window.performance.timing);
|
|
85
61
|
}
|
|
86
|
-
|
|
62
|
+
const scheduler = new HarvestScheduler('resources', {
|
|
87
63
|
onFinished: onHarvestFinished.bind(this),
|
|
88
64
|
retryDelay: this.harvestTimeSeconds
|
|
89
65
|
}, this);
|
|
@@ -91,38 +67,37 @@ export class Aggregate extends FeatureBase {
|
|
|
91
67
|
scheduler.runHarvest({
|
|
92
68
|
needResponse: true
|
|
93
69
|
}); // sends first stn harvest immediately
|
|
94
|
-
|
|
70
|
+
handlerCache.decide(true);
|
|
95
71
|
function onHarvestFinished(result) {
|
|
96
|
-
// start timer only if ptid was returned by server
|
|
97
72
|
if (result.sent && result.responseText && !this.ptid) {
|
|
98
|
-
|
|
99
|
-
getRuntime(this.agentIdentifier).ptid = this.ptid;
|
|
73
|
+
// continue interval harvest only if ptid was returned by server on the first
|
|
74
|
+
getRuntime(this.agentIdentifier).ptid = this.ptid = result.responseText;
|
|
100
75
|
scheduler.startTimer(this.harvestTimeSeconds);
|
|
101
76
|
}
|
|
102
77
|
if (result.sent && result.retry && this.sentTrace) {
|
|
103
|
-
|
|
104
|
-
|
|
78
|
+
// merge previous trace back into buffer to retry for next harvest
|
|
79
|
+
Object.entries(this.sentTrace).forEach(_ref => {
|
|
80
|
+
let [name, listOfSTNodes] = _ref;
|
|
81
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) return;
|
|
82
|
+
this.nodeCount += listOfSTNodes.length;
|
|
83
|
+
this.trace[name] = this.trace[name] ? listOfSTNodes.concat(this.trace[name]) : listOfSTNodes;
|
|
105
84
|
});
|
|
106
85
|
this.sentTrace = null;
|
|
107
86
|
}
|
|
108
87
|
}
|
|
109
88
|
function prepareHarvest(options) {
|
|
110
|
-
if (now() >
|
|
89
|
+
if (now() > MAX_TRACE_DURATION) {
|
|
111
90
|
// been collecting for over 15 min, empty trace object and bail
|
|
112
91
|
scheduler.stopTimer();
|
|
113
92
|
this.trace = {};
|
|
114
93
|
return;
|
|
115
94
|
}
|
|
116
|
-
|
|
117
|
-
// only send when there are more than 30 nodes to send
|
|
95
|
+
// Only harvest when there are more than 30 nodes to send after the very first.
|
|
118
96
|
if (this.ptid && this.nodeCount <= 30) return;
|
|
119
97
|
return this.takeSTNs(options.retry);
|
|
120
98
|
}
|
|
121
|
-
handlerCache.decide(true);
|
|
122
|
-
}, this.featureName, this.ee);
|
|
123
|
-
registerHandler('block-stn', () => {
|
|
124
|
-
handlerCache.decide(false);
|
|
125
99
|
}, this.featureName, this.ee);
|
|
100
|
+
registerHandler('block-stn', () => handlerCache.decide(false), this.featureName, this.ee);
|
|
126
101
|
|
|
127
102
|
// register the handlers immediately... but let the handlerCache decide if the data should actually get stored...
|
|
128
103
|
registerHandler('bst', function () {
|
|
@@ -175,19 +150,28 @@ export class Aggregate extends FeatureBase {
|
|
|
175
150
|
}, this.featureName, this.ee);
|
|
176
151
|
drain(this.agentIdentifier, this.featureName);
|
|
177
152
|
}
|
|
153
|
+
|
|
154
|
+
// PageViewTiming (FEATURE) events and metrics, such as 'load', 'lcp', etc. pipes into ST here.
|
|
178
155
|
processPVT(name, value, attrs) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (
|
|
156
|
+
this.storeTiming({
|
|
157
|
+
[name]: value
|
|
158
|
+
});
|
|
159
|
+
if (hasFID(name, attrs)) this.storeEvent({
|
|
183
160
|
type: 'fid',
|
|
184
161
|
target: 'document'
|
|
185
162
|
}, 'document', value, value + attrs.fid);
|
|
163
|
+
function hasFID(name, attrs) {
|
|
164
|
+
return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
|
|
165
|
+
}
|
|
186
166
|
}
|
|
187
|
-
|
|
167
|
+
|
|
168
|
+
// This processes the aforementioned PVT and the first navigation entry of the page.
|
|
169
|
+
storeTiming(timingEntry) {
|
|
170
|
+
if (!timingEntry) return;
|
|
171
|
+
|
|
188
172
|
// loop iterates through prototype also (for FF)
|
|
189
|
-
for (let key in
|
|
190
|
-
|
|
173
|
+
for (let key in timingEntry) {
|
|
174
|
+
let val = timingEntry[key];
|
|
191
175
|
|
|
192
176
|
// ignore size and status type nodes that do not map to timestamp metrics
|
|
193
177
|
const lck = key.toLowerCase();
|
|
@@ -196,31 +180,33 @@ export class Aggregate extends FeatureBase {
|
|
|
196
180
|
// ignore inherited methods, meaningless 0 values, and bogus timestamps
|
|
197
181
|
// that are in the future (Microsoft Edge seems to sometimes produce these)
|
|
198
182
|
if (!(typeof val === 'number' && val >= 0)) continue;
|
|
199
|
-
|
|
183
|
+
val = Math.round(val);
|
|
200
184
|
this.storeSTN({
|
|
201
185
|
n: key,
|
|
202
|
-
s:
|
|
203
|
-
e:
|
|
186
|
+
s: val,
|
|
187
|
+
e: val,
|
|
204
188
|
o: 'document',
|
|
205
189
|
t: 'timing'
|
|
206
190
|
});
|
|
207
191
|
}
|
|
208
192
|
}
|
|
193
|
+
|
|
194
|
+
// Tracks duration of native APIs wrapped by wrap-timer & wrap-raf.
|
|
209
195
|
storeTimer(target, start, end, type) {
|
|
210
|
-
|
|
211
|
-
if (type === 'requestAnimationFrame') category = type;
|
|
212
|
-
var evt = {
|
|
196
|
+
const evt = {
|
|
213
197
|
n: type,
|
|
214
198
|
s: start,
|
|
215
199
|
e: end,
|
|
216
200
|
o: 'window',
|
|
217
|
-
t:
|
|
201
|
+
t: type === 'requestAnimationFrame' ? type : 'timer'
|
|
218
202
|
};
|
|
219
203
|
this.storeSTN(evt);
|
|
220
204
|
}
|
|
205
|
+
|
|
206
|
+
// Tracks the events and their listener's duration on objects wrapped by wrap-events.
|
|
221
207
|
storeEvent(currentEvent, target, start, end) {
|
|
222
|
-
if (this.shouldIgnoreEvent(currentEvent, target)) return
|
|
223
|
-
|
|
208
|
+
if (this.shouldIgnoreEvent(currentEvent, target)) return;
|
|
209
|
+
const evt = {
|
|
224
210
|
n: this.evtName(currentEvent.type),
|
|
225
211
|
s: start,
|
|
226
212
|
e: end,
|
|
@@ -235,31 +221,60 @@ export class Aggregate extends FeatureBase {
|
|
|
235
221
|
}
|
|
236
222
|
this.storeSTN(evt);
|
|
237
223
|
}
|
|
224
|
+
shouldIgnoreEvent(event, target) {
|
|
225
|
+
const origin = this.evtOrigin(event.target, target);
|
|
226
|
+
if (event.type in ignoredEvents.global) return true;
|
|
227
|
+
if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
|
|
228
|
+
if (!!ignoredEvents[origin] && event.type in ignoredEvents[origin]) return true;
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
238
231
|
evtName(type) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
232
|
+
switch (type) {
|
|
233
|
+
case 'keydown':
|
|
234
|
+
case 'keyup':
|
|
235
|
+
case 'keypress':
|
|
236
|
+
return 'typing';
|
|
237
|
+
case 'mousemove':
|
|
238
|
+
case 'mouseenter':
|
|
239
|
+
case 'mouseleave':
|
|
240
|
+
case 'mouseover':
|
|
241
|
+
case 'mouseout':
|
|
242
|
+
return 'mousing';
|
|
243
|
+
case 'scroll':
|
|
244
|
+
return 'scrolling';
|
|
245
|
+
case 'touchstart':
|
|
246
|
+
case 'touchmove':
|
|
247
|
+
case 'touchend':
|
|
248
|
+
case 'touchcancel':
|
|
249
|
+
case 'touchenter':
|
|
250
|
+
case 'touchleave':
|
|
251
|
+
return 'touching';
|
|
252
|
+
default:
|
|
253
|
+
return type;
|
|
254
|
+
}
|
|
244
255
|
}
|
|
245
256
|
evtOrigin(t, target) {
|
|
246
|
-
|
|
257
|
+
let origin = 'unknown';
|
|
247
258
|
if (t && t instanceof XMLHttpRequest) {
|
|
248
|
-
|
|
259
|
+
const params = this.ee.context(t).params;
|
|
249
260
|
if (!params || !params.status || !params.method || !params.host || !params.pathname) return 'xhrOriginMissing';
|
|
250
261
|
origin = params.status + ' ' + params.method + ': ' + params.host + params.pathname;
|
|
251
262
|
} else if (t && typeof t.tagName === 'string') {
|
|
252
263
|
origin = t.tagName.toLowerCase();
|
|
253
264
|
if (t.id) origin += '#' + t.id;
|
|
254
|
-
if (t.className)
|
|
265
|
+
if (t.className) {
|
|
266
|
+
for (let i = 0; i < t.classList.length; i++) origin += '.' + t.classList[i];
|
|
267
|
+
}
|
|
255
268
|
}
|
|
256
269
|
if (origin === 'unknown') {
|
|
257
270
|
if (typeof target === 'string') origin = target;else if (target === document) origin = 'document';else if (target === window) origin = 'window';else if (target instanceof FileReader) origin = 'FileReader';
|
|
258
271
|
}
|
|
259
272
|
return origin;
|
|
260
273
|
}
|
|
274
|
+
|
|
275
|
+
// Tracks when the window history API specified by wrap-history is used.
|
|
261
276
|
storeHist(path, old, time) {
|
|
262
|
-
|
|
277
|
+
const node = {
|
|
263
278
|
n: 'history.pushState',
|
|
264
279
|
s: time,
|
|
265
280
|
e: time,
|
|
@@ -268,11 +283,15 @@ export class Aggregate extends FeatureBase {
|
|
|
268
283
|
};
|
|
269
284
|
this.storeSTN(node);
|
|
270
285
|
}
|
|
286
|
+
|
|
287
|
+
// Processes all the PerformanceResourceTiming entries captured (by observer).
|
|
271
288
|
storeResources(resources) {
|
|
272
289
|
if (!resources || resources.length === 0) return;
|
|
273
290
|
resources.forEach(currentResource => {
|
|
274
|
-
|
|
275
|
-
|
|
291
|
+
if ((currentResource.fetchStart | 0) <= this.laststart) return; // don't recollect already-seen resources
|
|
292
|
+
|
|
293
|
+
const parsed = parseUrl(currentResource.name);
|
|
294
|
+
const res = {
|
|
276
295
|
n: currentResource.initiatorType,
|
|
277
296
|
s: currentResource.fetchStart | 0,
|
|
278
297
|
e: currentResource.responseEnd | 0,
|
|
@@ -280,16 +299,15 @@ export class Aggregate extends FeatureBase {
|
|
|
280
299
|
// resource.name is actually a URL so it's the source
|
|
281
300
|
t: currentResource.entryType
|
|
282
301
|
};
|
|
283
|
-
|
|
284
|
-
// don't recollect old resources
|
|
285
|
-
if (res.s <= this.laststart) return;
|
|
286
302
|
this.storeSTN(res);
|
|
287
303
|
});
|
|
288
304
|
this.laststart = resources[resources.length - 1].fetchStart | 0;
|
|
289
305
|
}
|
|
306
|
+
|
|
307
|
+
// JavascriptError (FEATURE) events pipes into ST here.
|
|
290
308
|
storeErrorAgg(type, name, params, metrics) {
|
|
291
|
-
if (type !== 'err') return;
|
|
292
|
-
|
|
309
|
+
if (type !== 'err') return; // internal errors are purposefully ignored
|
|
310
|
+
const node = {
|
|
293
311
|
n: 'error',
|
|
294
312
|
s: metrics.time,
|
|
295
313
|
e: metrics.time,
|
|
@@ -298,9 +316,11 @@ export class Aggregate extends FeatureBase {
|
|
|
298
316
|
};
|
|
299
317
|
this.storeSTN(node);
|
|
300
318
|
}
|
|
319
|
+
|
|
320
|
+
// Ajax (FEATURE) events--XML & fetches--pipes into ST here.
|
|
301
321
|
storeXhrAgg(type, name, params, metrics) {
|
|
302
322
|
if (type !== 'xhr') return;
|
|
303
|
-
|
|
323
|
+
const node = {
|
|
304
324
|
n: 'Ajax',
|
|
305
325
|
s: metrics.time,
|
|
306
326
|
e: metrics.time + metrics.duration,
|
|
@@ -309,46 +329,46 @@ export class Aggregate extends FeatureBase {
|
|
|
309
329
|
};
|
|
310
330
|
this.storeSTN(node);
|
|
311
331
|
}
|
|
332
|
+
|
|
333
|
+
// Central function called by all the other store__ & addToTrace API to append a trace node.
|
|
312
334
|
storeSTN(stn) {
|
|
313
|
-
// limit the
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (!traceArr) traceArr = this.trace[stn.n] = [];
|
|
317
|
-
traceArr.push(stn);
|
|
335
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) return; // limit the amount of data that is stored at once
|
|
336
|
+
|
|
337
|
+
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
318
338
|
this.nodeCount++;
|
|
319
339
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (this.nodeCount >= this.maxNodesPerHarvest) return;
|
|
323
|
-
var traceArr = this.trace[key];
|
|
324
|
-
if (!traceArr) traceArr = this.trace[key] = [];
|
|
325
|
-
this.trace[key] = nodes.concat(traceArr);
|
|
326
|
-
this.nodeCount += nodes.length;
|
|
327
|
-
}
|
|
340
|
+
|
|
341
|
+
// Used by session trace's harvester to create the payload body.
|
|
328
342
|
takeSTNs(retry) {
|
|
329
|
-
|
|
330
|
-
|
|
343
|
+
if (!this.resourceObserver) {
|
|
344
|
+
// if PO isn't supported, this checks resourcetiming buffer every harvest.
|
|
331
345
|
this.storeResources(window.performance.getEntriesByType('resource'));
|
|
332
346
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
347
|
+
const stns = Object.entries(this.trace).flatMap(_ref2 => {
|
|
348
|
+
let [name, listOfSTNodes] = _ref2;
|
|
349
|
+
// basically take the "this.trace" map-obj and concat all the list-type values
|
|
350
|
+
if (!(name in toAggregate)) return listOfSTNodes;
|
|
351
|
+
// Special processing for event nodes dealing with user inputs:
|
|
352
|
+
const reindexByOriginFn = this.smearEvtsByOrigin(name);
|
|
353
|
+
const partitionListByOriginMap = listOfSTNodes.sort((a, b) => a.s - b.s).reduce(reindexByOriginFn, {});
|
|
354
|
+
return Object.values(partitionListByOriginMap).flat(); // join the partitions back into 1-D, now ordered by origin then start time
|
|
355
|
+
}, this);
|
|
337
356
|
if (stns.length === 0) return {};
|
|
338
357
|
if (retry) {
|
|
339
358
|
this.sentTrace = this.trace;
|
|
340
359
|
}
|
|
341
360
|
this.trace = {};
|
|
342
361
|
this.nodeCount = 0;
|
|
343
|
-
|
|
362
|
+
const stnInfo = {
|
|
344
363
|
qs: {
|
|
345
|
-
st:
|
|
364
|
+
st: String(getRuntime(this.agentIdentifier).offset)
|
|
346
365
|
},
|
|
347
366
|
body: {
|
|
348
367
|
res: stns
|
|
349
368
|
}
|
|
350
369
|
};
|
|
351
370
|
if (!this.ptid) {
|
|
371
|
+
// send custom and user attributes on the very first ST harvest only
|
|
352
372
|
const {
|
|
353
373
|
userAttributes,
|
|
354
374
|
atts,
|
|
@@ -356,53 +376,34 @@ export class Aggregate extends FeatureBase {
|
|
|
356
376
|
} = getInfo(this.agentIdentifier);
|
|
357
377
|
stnInfo.qs.ua = userAttributes;
|
|
358
378
|
stnInfo.qs.at = atts;
|
|
359
|
-
|
|
379
|
+
const ja = stringify(jsAttributes);
|
|
360
380
|
stnInfo.qs.ja = ja === '{}' ? null : ja;
|
|
361
381
|
}
|
|
362
382
|
return stnInfo;
|
|
363
383
|
}
|
|
364
|
-
byStart(a, b) {
|
|
365
|
-
return a.s - b.s;
|
|
366
|
-
}
|
|
367
384
|
smearEvtsByOrigin(name) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return (byOrigin,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (name === 'scrolling' && !
|
|
376
|
-
lastO[
|
|
377
|
-
|
|
378
|
-
lastArr.push(
|
|
379
|
-
} else if (last &&
|
|
380
|
-
last.e =
|
|
385
|
+
const maxGap = toAggregate[name][0];
|
|
386
|
+
const maxLen = toAggregate[name][1];
|
|
387
|
+
const lastO = {};
|
|
388
|
+
return (byOrigin, evtNode) => {
|
|
389
|
+
let lastArr = byOrigin[evtNode.o];
|
|
390
|
+
if (!lastArr) lastArr = byOrigin[evtNode.o] = [];
|
|
391
|
+
const last = lastO[evtNode.o];
|
|
392
|
+
if (name === 'scrolling' && !trivial(evtNode)) {
|
|
393
|
+
lastO[evtNode.o] = null;
|
|
394
|
+
evtNode.n = 'scroll';
|
|
395
|
+
lastArr.push(evtNode);
|
|
396
|
+
} else if (last && evtNode.s - last.s < maxLen && last.e > evtNode.s - maxGap) {
|
|
397
|
+
last.e = evtNode.e;
|
|
381
398
|
} else {
|
|
382
|
-
lastO[
|
|
383
|
-
lastArr.push(
|
|
399
|
+
lastO[evtNode.o] = evtNode;
|
|
400
|
+
lastArr.push(evtNode);
|
|
384
401
|
}
|
|
385
402
|
return byOrigin;
|
|
386
403
|
};
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
flatten(a, b) {
|
|
392
|
-
return a.concat(b);
|
|
393
|
-
}
|
|
394
|
-
hasFID(name, attrs) {
|
|
395
|
-
return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
|
|
396
|
-
}
|
|
397
|
-
trivial(node) {
|
|
398
|
-
var limit = 4;
|
|
399
|
-
if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
|
|
400
|
-
}
|
|
401
|
-
shouldIgnoreEvent(event, target) {
|
|
402
|
-
var origin = this.evtOrigin(event.target, target);
|
|
403
|
-
if (event.type in this.ignoredEvents.global) return true;
|
|
404
|
-
if (!!this.ignoredEvents[origin] && this.ignoredEvents[origin].ignoreAll) return true;
|
|
405
|
-
if (!!this.ignoredEvents[origin] && event.type in this.ignoredEvents[origin]) return true;
|
|
406
|
-
return false;
|
|
404
|
+
function trivial(node) {
|
|
405
|
+
const limit = 4;
|
|
406
|
+
if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
|
|
407
|
+
}
|
|
407
408
|
}
|
|
408
409
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { originals } from '../../common/config/config';
|
|
2
1
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
3
2
|
export const FEATURE_NAME = FEATURE_NAMES.sessionTrace;
|
|
4
|
-
export const RESOURCE_TIMING_BUFFER_FULL = 'resourcetimingbufferfull';
|
|
5
3
|
export const BST_RESOURCE = 'bstResource';
|
|
6
4
|
export const RESOURCE = 'resource';
|
|
7
5
|
export const START = '-start';
|
|
@@ -9,6 +7,4 @@ export const END = '-end';
|
|
|
9
7
|
export const FN_START = 'fn' + START;
|
|
10
8
|
export const FN_END = 'fn' + END;
|
|
11
9
|
export const BST_TIMER = 'bstTimer';
|
|
12
|
-
export const PUSH_STATE = 'pushState';
|
|
13
|
-
export const ORIG_EVENT = originals.EV;
|
|
14
|
-
export const ADD_EVENT_LISTENER = 'addEventListener';
|
|
10
|
+
export const PUSH_STATE = 'pushState';
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { handle } from '../../../common/event-emitter/handle';
|
|
6
6
|
import { wrapHistory, wrapEvents, wrapTimer, wrapRaf } from '../../../common/wrap';
|
|
7
|
-
import { supportsPerformanceObserver } from '../../../common/window/supports-performance-observer';
|
|
8
|
-
import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts';
|
|
9
7
|
import { now } from '../../../common/timing/now';
|
|
10
8
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
11
9
|
import * as CONSTANTS from '../constants';
|
|
@@ -13,19 +11,15 @@ import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
|
13
11
|
import { isBrowserScope } from '../../../common/util/global-scope';
|
|
14
12
|
const {
|
|
15
13
|
BST_RESOURCE,
|
|
14
|
+
RESOURCE,
|
|
16
15
|
BST_TIMER,
|
|
16
|
+
START,
|
|
17
17
|
END,
|
|
18
18
|
FEATURE_NAME,
|
|
19
19
|
FN_END,
|
|
20
20
|
FN_START,
|
|
21
|
-
|
|
22
|
-
PUSH_STATE,
|
|
23
|
-
RESOURCE,
|
|
24
|
-
RESOURCE_TIMING_BUFFER_FULL,
|
|
25
|
-
START,
|
|
26
|
-
ORIG_EVENT: origEvent
|
|
21
|
+
PUSH_STATE
|
|
27
22
|
} = CONSTANTS;
|
|
28
|
-
const CRT = 'clearResourceTimings';
|
|
29
23
|
export class Instrument extends InstrumentBase {
|
|
30
24
|
static featureName = FEATURE_NAME;
|
|
31
25
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -37,20 +31,14 @@ export class Instrument extends InstrumentBase {
|
|
|
37
31
|
this.timerEE = wrapTimer(thisInstrumentEE);
|
|
38
32
|
this.rafEE = wrapRaf(thisInstrumentEE);
|
|
39
33
|
wrapHistory(thisInstrumentEE);
|
|
40
|
-
wrapEvents(thisInstrumentEE);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (evt instanceof origEvent) {
|
|
44
|
-
this.bstStart = now();
|
|
45
|
-
}
|
|
34
|
+
this.eventsEE = wrapEvents(thisInstrumentEE);
|
|
35
|
+
this.eventsEE.on(FN_START, function (args, target) {
|
|
36
|
+
this.bstStart = now();
|
|
46
37
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// When ajax is disabled, this may fail without making ajax a dependency of session_trace
|
|
52
|
-
handle('bst', [evt, target, this.bstStart, now()], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
53
|
-
}
|
|
38
|
+
this.eventsEE.on(FN_END, function (args, target) {
|
|
39
|
+
// ISSUE: when target is XMLHttpRequest, nr@context should have params so we can calculate event origin
|
|
40
|
+
// When ajax is disabled, this may fail without making ajax a dependency of session_trace
|
|
41
|
+
handle('bst', [args[0], target, this.bstStart, now()], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
54
42
|
});
|
|
55
43
|
this.timerEE.on(FN_START, function (args, obj, type) {
|
|
56
44
|
this.bstStart = now();
|
|
@@ -72,53 +60,23 @@ export class Instrument extends InstrumentBase {
|
|
|
72
60
|
thisInstrumentEE.on(PUSH_STATE + END, function (args) {
|
|
73
61
|
handle('bstHist', [location.pathname + location.hash, this.startPath, this.time], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
74
62
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
} else {
|
|
80
|
-
// collect resource timings once when buffer is full
|
|
81
|
-
if (window.performance[CRT] && window.performance[ADD_EVENT_LISTENER]) {
|
|
82
|
-
window.performance.addEventListener(RESOURCE_TIMING_BUFFER_FULL, this.onResourceTimingBufferFull, eventListenerOpts(false));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function observeResourceTimings() {
|
|
86
|
-
var observer = new PerformanceObserver((list, observer) => {
|
|
63
|
+
let observer;
|
|
64
|
+
try {
|
|
65
|
+
// Capture initial resources and watch for future ones. Don't defer this given there's a default cap on the number of buffered entries.
|
|
66
|
+
observer = new PerformanceObserver(list => {
|
|
87
67
|
// eslint-disable-line no-undef
|
|
88
|
-
|
|
68
|
+
const entries = list.getEntries();
|
|
89
69
|
handle(BST_RESOURCE, [entries], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
90
70
|
});
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
document.addEventListener('scroll', this.noOp, eventListenerOpts(false));
|
|
100
|
-
document.addEventListener('keypress', this.noOp, eventListenerOpts(false));
|
|
101
|
-
document.addEventListener('click', this.noOp, eventListenerOpts(false));
|
|
102
|
-
this.abortHandler = this.#abort;
|
|
103
|
-
this.importAggregator();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Restoration and resource release tasks to be done if Session trace loader is being aborted. Unwind changes to globals. */
|
|
107
|
-
#abort() {
|
|
108
|
-
window.performance.removeEventListener(RESOURCE_TIMING_BUFFER_FULL, this.onResourceTimingBufferFull, false);
|
|
109
|
-
// The doc interaction noOp listeners are harmless--cannot buffer data into EE.
|
|
110
|
-
this.abortHandler = undefined; // weakly allow this abort op to run only once
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
noOp(e) {/* no-op */}
|
|
114
|
-
onResourceTimingBufferFull(evt) {
|
|
115
|
-
handle(BST_RESOURCE, [window.performance.getEntriesByType(RESOURCE)], undefined, FEATURE_NAMES.sessionTrace, this.ee);
|
|
116
|
-
|
|
117
|
-
// stop recording once buffer is full
|
|
118
|
-
if (window.performance[CRT]) {
|
|
119
|
-
try {
|
|
120
|
-
window.performance.removeEventListener(RESOURCE_TIMING_BUFFER_FULL, this.onResourceTimingBufferFull, false);
|
|
121
|
-
} catch (e) {}
|
|
71
|
+
observer.observe({
|
|
72
|
+
type: RESOURCE,
|
|
73
|
+
buffered: true
|
|
74
|
+
});
|
|
75
|
+
} catch (e) {
|
|
76
|
+
// Per NEWRELIC-8525, we don't have a fallback for capturing resources for older versions that don't support PO at this time.
|
|
122
77
|
}
|
|
78
|
+
this.importAggregator({
|
|
79
|
+
resourceObserver: observer
|
|
80
|
+
});
|
|
123
81
|
}
|
|
124
82
|
}
|
|
@@ -19,7 +19,7 @@ import { ee } from '../../../common/event-emitter/contextual-ee';
|
|
|
19
19
|
import * as CONSTANTS from '../constants';
|
|
20
20
|
import { drain } from '../../../common/drain/drain';
|
|
21
21
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
22
|
-
import {
|
|
22
|
+
import { AggregateBase } from '../../utils/aggregate-base';
|
|
23
23
|
const {
|
|
24
24
|
FEATURE_NAME,
|
|
25
25
|
INTERACTION_EVENTS,
|
|
@@ -38,7 +38,7 @@ const {
|
|
|
38
38
|
JSONP_END,
|
|
39
39
|
originalSetTimeout
|
|
40
40
|
} = CONSTANTS;
|
|
41
|
-
export class Aggregate extends
|
|
41
|
+
export class Aggregate extends AggregateBase {
|
|
42
42
|
static featureName = FEATURE_NAME;
|
|
43
43
|
constructor(agentIdentifier, aggregator) {
|
|
44
44
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|