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