@newrelic/browser-agent 1.269.0 → 1.270.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/CHANGELOG.md +18 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/runtime.js +1 -2
- package/dist/cjs/common/harvest/harvest-scheduler.js +3 -4
- package/dist/cjs/common/unload/eol.js +2 -5
- package/dist/cjs/common/util/submit-data.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +8 -17
- package/dist/cjs/features/ajax/instrument/index.js +8 -10
- package/dist/cjs/features/generic_events/aggregate/index.js +15 -22
- package/dist/cjs/features/generic_events/instrument/index.js +5 -8
- package/dist/cjs/features/jserrors/aggregate/index.js +17 -22
- package/dist/cjs/features/jserrors/instrument/index.js +3 -3
- package/dist/cjs/features/logging/aggregate/index.js +16 -23
- package/dist/cjs/features/logging/instrument/index.js +3 -3
- package/dist/cjs/features/metrics/aggregate/index.js +13 -16
- package/dist/cjs/features/metrics/instrument/index.js +3 -3
- package/dist/cjs/features/page_view_event/aggregate/index.js +15 -29
- package/dist/cjs/features/page_view_event/instrument/index.js +3 -3
- package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -23
- package/dist/cjs/features/page_view_timing/instrument/index.js +3 -3
- package/dist/cjs/features/session_replay/aggregate/index.js +15 -29
- package/dist/cjs/features/session_replay/instrument/index.js +7 -5
- package/dist/cjs/features/session_trace/aggregate/index.js +25 -31
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +1 -1
- package/dist/cjs/features/session_trace/instrument/index.js +4 -5
- package/dist/cjs/features/soft_navigations/aggregate/index.js +6 -11
- package/dist/cjs/features/soft_navigations/instrument/index.js +3 -3
- package/dist/cjs/features/spa/aggregate/index.js +19 -30
- package/dist/cjs/features/spa/instrument/index.js +4 -4
- package/dist/cjs/features/utils/aggregate-base.js +11 -12
- package/dist/cjs/features/utils/feature-base.js +5 -3
- package/dist/cjs/features/utils/instrument-base.js +18 -10
- package/dist/cjs/loaders/agent.js +1 -5
- package/dist/cjs/loaders/micro-agent.js +6 -9
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +0 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +3 -4
- package/dist/esm/common/unload/eol.js +2 -5
- package/dist/esm/common/util/submit-data.js +2 -2
- package/dist/esm/features/ajax/aggregate/index.js +8 -17
- package/dist/esm/features/ajax/instrument/index.js +8 -10
- package/dist/esm/features/generic_events/aggregate/index.js +11 -18
- package/dist/esm/features/generic_events/instrument/index.js +5 -8
- package/dist/esm/features/jserrors/aggregate/index.js +15 -20
- package/dist/esm/features/jserrors/instrument/index.js +3 -3
- package/dist/esm/features/logging/aggregate/index.js +16 -23
- package/dist/esm/features/logging/instrument/index.js +3 -3
- package/dist/esm/features/metrics/aggregate/index.js +8 -11
- package/dist/esm/features/metrics/instrument/index.js +3 -3
- package/dist/esm/features/page_view_event/aggregate/index.js +16 -30
- package/dist/esm/features/page_view_event/instrument/index.js +3 -3
- package/dist/esm/features/page_view_timing/aggregate/index.js +6 -23
- package/dist/esm/features/page_view_timing/instrument/index.js +3 -3
- package/dist/esm/features/session_replay/aggregate/index.js +13 -27
- package/dist/esm/features/session_replay/instrument/index.js +7 -5
- package/dist/esm/features/session_trace/aggregate/index.js +22 -28
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +1 -1
- package/dist/esm/features/session_trace/instrument/index.js +4 -5
- package/dist/esm/features/soft_navigations/aggregate/index.js +6 -11
- package/dist/esm/features/soft_navigations/instrument/index.js +3 -3
- package/dist/esm/features/spa/aggregate/index.js +17 -28
- package/dist/esm/features/spa/instrument/index.js +4 -4
- package/dist/esm/features/utils/aggregate-base.js +13 -14
- package/dist/esm/features/utils/feature-base.js +5 -3
- package/dist/esm/features/utils/instrument-base.js +18 -10
- package/dist/esm/loaders/agent.js +1 -5
- package/dist/esm/loaders/micro-agent.js +6 -9
- package/dist/types/common/constants/runtime.d.ts +0 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts +1 -1
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +1 -2
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/instrument/index.d.ts +1 -1
- package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +1 -2
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/instrument/index.d.ts +1 -1
- package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_action/instrument/index.d.ts +1 -0
- package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -5
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/instrument/index.d.ts +1 -1
- package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +0 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +1 -3
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/instrument/index.d.ts +1 -1
- package/dist/types/features/soft_navigations/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/instrument/index.d.ts +1 -1
- package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +2 -2
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/feature-base.d.ts +2 -3
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +3 -3
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts +0 -2
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts +0 -2
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/constants/__mocks__/runtime.js +0 -1
- package/src/common/constants/runtime.js +0 -2
- package/src/common/harvest/harvest-scheduler.js +3 -4
- package/src/common/unload/eol.js +2 -5
- package/src/common/util/submit-data.js +2 -2
- package/src/features/ajax/aggregate/index.js +8 -18
- package/src/features/ajax/instrument/index.js +8 -10
- package/src/features/generic_events/aggregate/index.js +11 -20
- package/src/features/generic_events/instrument/index.js +7 -10
- package/src/features/jserrors/aggregate/index.js +15 -20
- package/src/features/jserrors/instrument/index.js +3 -4
- package/src/features/logging/aggregate/index.js +15 -23
- package/src/features/logging/instrument/index.js +3 -3
- package/src/features/metrics/aggregate/index.js +8 -11
- package/src/features/metrics/instrument/index.js +3 -3
- package/src/features/page_view_event/aggregate/index.js +16 -22
- package/src/features/page_view_event/instrument/index.js +3 -3
- package/src/features/page_view_timing/aggregate/index.js +6 -23
- package/src/features/page_view_timing/instrument/index.js +3 -3
- package/src/features/session_replay/aggregate/index.js +13 -21
- package/src/features/session_replay/instrument/index.js +7 -5
- package/src/features/session_trace/aggregate/index.js +22 -28
- package/src/features/session_trace/aggregate/trace/storage.js +1 -1
- package/src/features/session_trace/instrument/index.js +4 -5
- package/src/features/soft_navigations/aggregate/index.js +6 -8
- package/src/features/soft_navigations/instrument/index.js +3 -3
- package/src/features/spa/aggregate/index.js +17 -26
- package/src/features/spa/instrument/index.js +4 -4
- package/src/features/utils/__mocks__/feature-base.js +1 -2
- package/src/features/utils/aggregate-base.js +13 -14
- package/src/features/utils/feature-base.js +6 -3
- package/src/features/utils/instrument-base.js +16 -10
- package/src/loaders/agent.js +1 -3
- package/src/loaders/micro-agent.js +7 -9
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { getInfo } from '../../../common/config/info';
|
|
2
|
-
import { getConfigurationValue } from '../../../common/config/init';
|
|
3
|
-
import { getRuntime } from '../../../common/config/runtime';
|
|
4
1
|
import { handle } from '../../../common/event-emitter/handle';
|
|
5
2
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
6
3
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
@@ -16,16 +13,12 @@ import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
|
|
|
16
13
|
import { EventBuffer } from '../../utils/event-buffer';
|
|
17
14
|
export class Aggregate extends AggregateBase {
|
|
18
15
|
static featureName = FEATURE_NAME;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
constructor(agentIdentifier, aggregator) {
|
|
22
|
-
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
16
|
+
constructor(agentRef) {
|
|
17
|
+
super(agentRef, FEATURE_NAME);
|
|
23
18
|
|
|
24
19
|
/** held logs before sending */
|
|
25
20
|
this.bufferedLogs = new EventBuffer();
|
|
26
|
-
this
|
|
27
|
-
this.#agentInfo = getInfo(this.agentIdentifier);
|
|
28
|
-
this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'logging.harvestTimeSeconds');
|
|
21
|
+
this.harvestTimeSeconds = agentRef.init.logging.harvestTimeSeconds;
|
|
29
22
|
this.waitForFlags([]).then(() => {
|
|
30
23
|
this.scheduler = new HarvestScheduler('browser/logs', {
|
|
31
24
|
onFinished: this.onHarvestFinished.bind(this),
|
|
@@ -60,7 +53,7 @@ export class Aggregate extends AggregateBase {
|
|
|
60
53
|
return;
|
|
61
54
|
}
|
|
62
55
|
if (typeof message !== 'string' || !message) return warn(32);
|
|
63
|
-
const log = new Log(Math.floor(this
|
|
56
|
+
const log = new Log(Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(timestamp)), message, attributes, level);
|
|
64
57
|
const logBytes = log.message.length + stringify(log.attributes).length + log.level.length + 10; // timestamp == 10 chars
|
|
65
58
|
|
|
66
59
|
if (!this.bufferedLogs.canMerge(logBytes)) {
|
|
@@ -81,34 +74,34 @@ export class Aggregate extends AggregateBase {
|
|
|
81
74
|
/** These attributes are evaluated and dropped at ingest processing time and do not get stored on NRDB */
|
|
82
75
|
const unbilledAttributes = {
|
|
83
76
|
'instrumentation.provider': 'browser',
|
|
84
|
-
'instrumentation.version': this
|
|
85
|
-
'instrumentation.name': this
|
|
77
|
+
'instrumentation.version': this.agentRef.runtime.version,
|
|
78
|
+
'instrumentation.name': this.agentRef.runtime.loaderType
|
|
86
79
|
};
|
|
87
80
|
/** see https://source.datanerd.us/agents/rum-specs/blob/main/browser/Log for logging spec */
|
|
88
81
|
const payload = {
|
|
89
82
|
qs: {
|
|
90
|
-
browser_monitoring_key: this
|
|
83
|
+
browser_monitoring_key: this.agentRef.info.licenseKey
|
|
91
84
|
},
|
|
92
85
|
body: [{
|
|
93
86
|
common: {
|
|
94
87
|
/** Attributes in the `common` section are added to `all` logs generated in the payload */
|
|
95
88
|
attributes: {
|
|
96
|
-
'entity.guid': this
|
|
89
|
+
'entity.guid': this.agentRef.runtime.appMetadata?.agents?.[0]?.entityGuid,
|
|
97
90
|
// browser entity guid as provided from RUM response
|
|
98
|
-
session: this
|
|
91
|
+
session: this.agentRef.runtime.session?.state.value || '0',
|
|
99
92
|
// The session ID that we generate and keep across page loads
|
|
100
|
-
hasReplay: this
|
|
93
|
+
hasReplay: this.agentRef.runtime.session?.state.sessionReplayMode === 1,
|
|
101
94
|
// True if a session replay recording is running
|
|
102
|
-
hasTrace: this
|
|
95
|
+
hasTrace: this.agentRef.runtime.session?.state.sessionTraceMode === 1,
|
|
103
96
|
// True if a session trace recording is running
|
|
104
|
-
ptid: this
|
|
97
|
+
ptid: this.agentRef.runtime.ptid,
|
|
105
98
|
// page trace id
|
|
106
|
-
appId: this
|
|
99
|
+
appId: this.agentRef.info.applicationID,
|
|
107
100
|
// Application ID from info object,
|
|
108
|
-
standalone: Boolean(this
|
|
101
|
+
standalone: Boolean(this.agentRef.info.sa),
|
|
109
102
|
// copy paste (true) vs APM (false)
|
|
110
|
-
agentVersion: this
|
|
111
|
-
// browser agent version
|
|
103
|
+
agentVersion: this.agentRef.runtime.version,
|
|
104
|
+
// browser agent version
|
|
112
105
|
...unbilledAttributes
|
|
113
106
|
}
|
|
114
107
|
},
|
|
@@ -3,8 +3,8 @@ import { FEATURE_NAME } from '../constants';
|
|
|
3
3
|
import { bufferLog } from '../shared/utils';
|
|
4
4
|
export class Instrument extends InstrumentBase {
|
|
5
5
|
static featureName = FEATURE_NAME;
|
|
6
|
-
constructor(
|
|
7
|
-
super(
|
|
6
|
+
constructor(agentRef, auto = true) {
|
|
7
|
+
super(agentRef, FEATURE_NAME, auto);
|
|
8
8
|
const instanceEE = this.ee;
|
|
9
9
|
/** emitted by wrap-logger function */
|
|
10
10
|
this.ee.on('wrap-logger-end', function handleLog([message]) {
|
|
@@ -14,7 +14,7 @@ export class Instrument extends InstrumentBase {
|
|
|
14
14
|
} = this;
|
|
15
15
|
bufferLog(instanceEE, message, customAttributes, level);
|
|
16
16
|
});
|
|
17
|
-
this.importAggregator();
|
|
17
|
+
this.importAggregator(agentRef);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
export const Logging = Instrument;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getConfiguration } from '../../../common/config/init';
|
|
2
|
-
import { getRuntime } from '../../../common/config/runtime';
|
|
3
1
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
4
2
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
5
3
|
import { FEATURE_NAME, SUPPORTABILITY_METRIC, CUSTOM_METRIC, SUPPORTABILITY_METRIC_CHANNEL, CUSTOM_METRIC_CHANNEL /*, WATCHABLE_WEB_SOCKET_EVENTS */ } from '../constants';
|
|
@@ -9,15 +7,14 @@ import { onDOMContentLoaded } from '../../../common/window/load';
|
|
|
9
7
|
import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
|
|
10
8
|
import { isBrowserScope, isWorkerScope } from '../../../common/constants/runtime';
|
|
11
9
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
12
|
-
import { deregisterDrain } from '../../../common/drain/drain';
|
|
13
10
|
import { isIFrameWindow } from '../../../common/dom/iframe';
|
|
14
11
|
// import { WEBSOCKET_TAG } from '../../../common/wrap/wrap-websocket'
|
|
15
12
|
// import { handleWebsocketEvents } from './websocket-detection'
|
|
16
13
|
|
|
17
14
|
export class Aggregate extends AggregateBase {
|
|
18
15
|
static featureName = FEATURE_NAME;
|
|
19
|
-
constructor(
|
|
20
|
-
super(
|
|
16
|
+
constructor(agentRef) {
|
|
17
|
+
super(agentRef, FEATURE_NAME);
|
|
21
18
|
this.waitForFlags(['err']).then(([errFlag]) => {
|
|
22
19
|
if (errFlag) {
|
|
23
20
|
// *cli, Mar 23 - Per NR-94597, this feature should only harvest ONCE at the (potential) EoL time of the page.
|
|
@@ -26,12 +23,12 @@ export class Aggregate extends AggregateBase {
|
|
|
26
23
|
}, this);
|
|
27
24
|
// this is needed to ensure EoL is "on" and sent
|
|
28
25
|
scheduler.harvest.on('jserrors', () => ({
|
|
29
|
-
body: this.
|
|
26
|
+
body: this.agentRef.sharedAggregator.take(['cm', 'sm'])
|
|
30
27
|
}));
|
|
31
28
|
this.drain();
|
|
32
29
|
} else {
|
|
33
30
|
this.blocked = true; // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
|
|
34
|
-
deregisterDrain(
|
|
31
|
+
this.deregisterDrain();
|
|
35
32
|
}
|
|
36
33
|
});
|
|
37
34
|
|
|
@@ -47,7 +44,7 @@ export class Aggregate extends AggregateBase {
|
|
|
47
44
|
const params = {
|
|
48
45
|
name
|
|
49
46
|
};
|
|
50
|
-
this.
|
|
47
|
+
this.agentRef.sharedAggregator.storeMetric(type, name, params, value);
|
|
51
48
|
}
|
|
52
49
|
storeEventMetrics(name, metrics) {
|
|
53
50
|
if (this.blocked) return;
|
|
@@ -55,18 +52,18 @@ export class Aggregate extends AggregateBase {
|
|
|
55
52
|
const params = {
|
|
56
53
|
name
|
|
57
54
|
};
|
|
58
|
-
this.
|
|
55
|
+
this.agentRef.sharedAggregator.store(type, name, params, metrics);
|
|
59
56
|
}
|
|
60
57
|
singleChecks() {
|
|
61
58
|
// report loaderType
|
|
62
59
|
const {
|
|
63
60
|
distMethod,
|
|
64
61
|
loaderType
|
|
65
|
-
} =
|
|
62
|
+
} = this.agentRef.runtime;
|
|
66
63
|
const {
|
|
67
64
|
proxy,
|
|
68
65
|
privacy
|
|
69
|
-
} =
|
|
66
|
+
} = this.agentRef.init;
|
|
70
67
|
if (loaderType) this.storeSupportabilityMetrics("Generic/LoaderType/".concat(loaderType, "/Detected"));
|
|
71
68
|
if (distMethod) this.storeSupportabilityMetrics("Generic/DistMethod/".concat(distMethod, "/Detected"));
|
|
72
69
|
if (isBrowserScope) {
|
|
@@ -4,8 +4,8 @@ import { InstrumentBase } from '../../utils/instrument-base';
|
|
|
4
4
|
import { FEATURE_NAME /*, WATCHABLE_WEB_SOCKET_EVENTS */ } from '../constants';
|
|
5
5
|
export class Instrument extends InstrumentBase {
|
|
6
6
|
static featureName = FEATURE_NAME;
|
|
7
|
-
constructor(
|
|
8
|
-
super(
|
|
7
|
+
constructor(agentRef, auto = true) {
|
|
8
|
+
super(agentRef, FEATURE_NAME, auto);
|
|
9
9
|
// wrapWebSocket(this.ee)
|
|
10
10
|
|
|
11
11
|
// WATCHABLE_WEB_SOCKET_EVENTS.forEach((suffix) => {
|
|
@@ -14,7 +14,7 @@ export class Instrument extends InstrumentBase {
|
|
|
14
14
|
// })
|
|
15
15
|
// })
|
|
16
16
|
|
|
17
|
-
this.importAggregator();
|
|
17
|
+
this.importAggregator(agentRef);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
export const Metrics = Instrument;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { globalScope, isBrowserScope, originTime } from '../../../common/constants/runtime';
|
|
2
2
|
import { addPT, addPN } from '../../../common/timing/nav-timing';
|
|
3
3
|
import { stringify } from '../../../common/util/stringify';
|
|
4
|
-
import {
|
|
5
|
-
import { getRuntime } from '../../../common/config/runtime';
|
|
4
|
+
import { isValid } from '../../../common/config/info';
|
|
6
5
|
import { Harvest } from '../../../common/harvest/harvest';
|
|
7
6
|
import * as CONSTANTS from '../constants';
|
|
8
7
|
import { getActivatedFeaturesFlags } from './initialized-features';
|
|
@@ -17,13 +16,13 @@ import { TimeKeeper } from '../../../common/timing/time-keeper';
|
|
|
17
16
|
import { applyFnToProps } from '../../../common/util/traverse';
|
|
18
17
|
export class Aggregate extends AggregateBase {
|
|
19
18
|
static featureName = CONSTANTS.FEATURE_NAME;
|
|
20
|
-
constructor(
|
|
21
|
-
super(
|
|
19
|
+
constructor(agentRef) {
|
|
20
|
+
super(agentRef, CONSTANTS.FEATURE_NAME);
|
|
22
21
|
this.timeToFirstByte = 0;
|
|
23
22
|
this.firstByteToWindowLoad = 0; // our "frontend" duration
|
|
24
23
|
this.firstByteToDomContent = 0; // our "dom processing" duration
|
|
25
|
-
this.timeKeeper = new TimeKeeper(
|
|
26
|
-
if (!isValid(agentIdentifier)) {
|
|
24
|
+
this.timeKeeper = new TimeKeeper(agentRef.agentIdentifier);
|
|
25
|
+
if (!isValid(agentRef.agentIdentifier)) {
|
|
27
26
|
this.ee.abort();
|
|
28
27
|
return warn(43);
|
|
29
28
|
}
|
|
@@ -45,43 +44,30 @@ export class Aggregate extends AggregateBase {
|
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
sendRum() {
|
|
48
|
-
const info =
|
|
49
|
-
const agentRuntime = getRuntime(this.agentIdentifier);
|
|
47
|
+
const info = this.agentRef.info;
|
|
50
48
|
const harvester = new Harvest(this);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (info.applicationTime) this.aggregator.store('measures', 'ap', {
|
|
55
|
-
value: info.applicationTime
|
|
56
|
-
});
|
|
49
|
+
const measures = {};
|
|
50
|
+
if (info.queueTime) measures.qt = info.queueTime;
|
|
51
|
+
if (info.applicationTime) measures.ap = info.applicationTime;
|
|
57
52
|
|
|
58
53
|
// These 3 values should've been recorded after load and before this func runs. They are part of the minimum required for PageView events to be created.
|
|
59
54
|
// Following PR #428, which demands that all agents send RUM call, these need to be sent even outside of the main window context where PerformanceTiming
|
|
60
55
|
// or PerformanceNavigationTiming do not exists. Hence, they'll be filled in by 0s instead in, for example, worker threads that still init the PVE module.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.aggregator.store('measures', 'fe', {
|
|
65
|
-
value: this.firstByteToWindowLoad
|
|
66
|
-
});
|
|
67
|
-
this.aggregator.store('measures', 'dc', {
|
|
68
|
-
value: this.firstByteToDomContent
|
|
69
|
-
});
|
|
56
|
+
measures.be = this.timeToFirstByte;
|
|
57
|
+
measures.fe = this.firstByteToWindowLoad;
|
|
58
|
+
measures.dc = this.firstByteToDomContent;
|
|
70
59
|
const queryParameters = {
|
|
71
60
|
tt: info.ttGuid,
|
|
72
61
|
us: info.user,
|
|
73
62
|
ac: info.account,
|
|
74
63
|
pr: info.product,
|
|
75
64
|
af: getActivatedFeaturesFlags(this.agentIdentifier).join(','),
|
|
76
|
-
...
|
|
77
|
-
aggregator[metricName] = measure.params?.value;
|
|
78
|
-
return aggregator;
|
|
79
|
-
}, {}),
|
|
65
|
+
...measures,
|
|
80
66
|
xx: info.extra,
|
|
81
67
|
ua: info.userAttributes,
|
|
82
68
|
at: info.atts
|
|
83
69
|
};
|
|
84
|
-
if (
|
|
70
|
+
if (this.agentRef.runtime.session) queryParameters.fsh = Number(this.agentRef.runtime.session.isNew); // "first session harvest" aka RUM request or PageView event of a session
|
|
85
71
|
|
|
86
72
|
let body;
|
|
87
73
|
if (typeof info.jsAttributes === 'object' && Object.keys(info.jsAttributes).length > 0) {
|
|
@@ -142,13 +128,13 @@ export class Aggregate extends AggregateBase {
|
|
|
142
128
|
try {
|
|
143
129
|
this.timeKeeper.processRumRequest(xhr, rumStartTime, rumEndTime, app.nrServerTime);
|
|
144
130
|
if (!this.timeKeeper.ready) throw new Error('TimeKeeper not ready');
|
|
145
|
-
|
|
131
|
+
this.agentRef.runtime.timeKeeper = this.timeKeeper;
|
|
146
132
|
} catch (error) {
|
|
147
133
|
this.ee.abort();
|
|
148
134
|
warn(17, error);
|
|
149
135
|
return;
|
|
150
136
|
}
|
|
151
|
-
|
|
137
|
+
this.agentRef.runtime.appMetadata = app;
|
|
152
138
|
activateFeatures(flags, this.agentIdentifier);
|
|
153
139
|
this.drain();
|
|
154
140
|
} catch (err) {
|
|
@@ -2,9 +2,9 @@ import { InstrumentBase } from '../../utils/instrument-base';
|
|
|
2
2
|
import * as CONSTANTS from '../constants';
|
|
3
3
|
export class Instrument extends InstrumentBase {
|
|
4
4
|
static featureName = CONSTANTS.FEATURE_NAME;
|
|
5
|
-
constructor(
|
|
6
|
-
super(
|
|
7
|
-
this.importAggregator();
|
|
5
|
+
constructor(agentRef, auto = true) {
|
|
6
|
+
super(agentRef, CONSTANTS.FEATURE_NAME, auto);
|
|
7
|
+
this.importAggregator(agentRef);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
export const PageViewEvent = Instrument;
|
|
@@ -7,8 +7,6 @@ import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../
|
|
|
7
7
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
8
8
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
9
9
|
import { handle } from '../../../common/event-emitter/handle';
|
|
10
|
-
import { getInfo } from '../../../common/config/info';
|
|
11
|
-
import { getConfigurationValue } from '../../../common/config/init';
|
|
12
10
|
import { FEATURE_NAME } from '../constants';
|
|
13
11
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
14
12
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
@@ -31,13 +29,14 @@ export class Aggregate extends AggregateBase {
|
|
|
31
29
|
}) => {
|
|
32
30
|
this.addTiming(name, value, attrs);
|
|
33
31
|
};
|
|
34
|
-
constructor(
|
|
35
|
-
super(
|
|
32
|
+
constructor(agentRef) {
|
|
33
|
+
super(agentRef, FEATURE_NAME);
|
|
36
34
|
this.timings = new EventBuffer();
|
|
37
35
|
this.curSessEndRecorded = false;
|
|
38
36
|
registerHandler('docHidden', msTimestamp => this.endCurrentSession(msTimestamp), this.featureName, this.ee);
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
// Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr:
|
|
38
|
+
registerHandler('winPagehide', msTimestamp => this.addTiming('unload', msTimestamp, null), this.featureName, this.ee);
|
|
39
|
+
const harvestTimeSeconds = agentRef.init.page_view_timing.harvestTimeSeconds || 30;
|
|
41
40
|
this.waitForFlags([]).then(() => {
|
|
42
41
|
/* It's important that CWV api, like "onLCP", is called before the **scheduler** is initialized. The reason is because they listen to the same
|
|
43
42
|
on vis change or pagehide events, and we'd want ex. onLCP to record the timing (win the race) before we try to send "final harvest". */
|
|
@@ -84,21 +83,6 @@ export class Aggregate extends AggregateBase {
|
|
|
84
83
|
this.curSessEndRecorded = true;
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr.
|
|
90
|
-
*/
|
|
91
|
-
recordPageUnload(timestamp) {
|
|
92
|
-
this.addTiming('unload', timestamp, null);
|
|
93
|
-
/*
|
|
94
|
-
Issue: Because window's pageHide commonly fires BEFORE vis change and "final" harvest would happen at the former in this case, we also have to add our vis-change event now or it may not be sent.
|
|
95
|
-
Affected: Safari < v14.1/.5 ; versions that don't support 'visiilitychange' event
|
|
96
|
-
Impact: For affected w/o this, NR 'pageHide' attribute may not be sent. For other browsers w/o this, NR 'pageHide' gets fragmented into its own harvest call on page unloading because of dual EoL logic.
|
|
97
|
-
Mitigation: NR 'unload' and 'pageHide' are both recorded when window pageHide fires, rather than only recording 'unload'.
|
|
98
|
-
Future: When EoL can become the singular subscribeToVisibilityChange, it's likely endCurrentSession isn't needed here as 'unload'-'pageHide' can be untangled.
|
|
99
|
-
*/
|
|
100
|
-
this.endCurrentSession(timestamp);
|
|
101
|
-
}
|
|
102
86
|
addTiming(name, value, attrs) {
|
|
103
87
|
attrs = attrs || {};
|
|
104
88
|
addConnectionAttributes(attrs); // network conditions may differ from the actual for VitalMetrics when they were captured
|
|
@@ -126,9 +110,8 @@ export class Aggregate extends AggregateBase {
|
|
|
126
110
|
}
|
|
127
111
|
appendGlobalCustomAttributes(timing) {
|
|
128
112
|
var timingAttributes = timing.attrs || {};
|
|
129
|
-
var customAttributes = getInfo(this.agentIdentifier).jsAttributes || {};
|
|
130
113
|
var reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type', 'net-etype', 'net-rtt', 'net-dlink'];
|
|
131
|
-
Object.entries(
|
|
114
|
+
Object.entries(this.agentRef.info.jsAttributes || {}).forEach(([key, val]) => {
|
|
132
115
|
if (reservedAttributes.indexOf(key) < 0) {
|
|
133
116
|
timingAttributes[key] = val;
|
|
134
117
|
}
|
|
@@ -11,8 +11,8 @@ import { isBrowserScope } from '../../../common/constants/runtime';
|
|
|
11
11
|
import { now } from '../../../common/timing/now';
|
|
12
12
|
export class Instrument extends InstrumentBase {
|
|
13
13
|
static featureName = FEATURE_NAME;
|
|
14
|
-
constructor(
|
|
15
|
-
super(
|
|
14
|
+
constructor(agentRef, auto = true) {
|
|
15
|
+
super(agentRef, FEATURE_NAME, auto);
|
|
16
16
|
if (!isBrowserScope) return; // CWV is irrelevant outside web context
|
|
17
17
|
|
|
18
18
|
// While we try to replicate web-vital's visibilitywatcher logic in an effort to defer that library to post-pageload, this isn't perfect and doesn't consider prerendering.
|
|
@@ -20,7 +20,7 @@ export class Instrument extends InstrumentBase {
|
|
|
20
20
|
|
|
21
21
|
// Window fires its pagehide event (typically on navigation--this occurrence is a *subset* of vis change); don't defer this unless it's guarantee it cannot happen before load(?)
|
|
22
22
|
windowAddEventListener('pagehide', () => handle('winPagehide', [now()], undefined, FEATURE_NAME, this.ee));
|
|
23
|
-
this.importAggregator();
|
|
23
|
+
this.importAggregator(agentRef);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
export const PageViewTiming = Instrument;
|
|
@@ -9,9 +9,6 @@
|
|
|
9
9
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
10
10
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
11
11
|
import { ABORT_REASONS, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
|
|
12
|
-
import { getInfo } from '../../../common/config/info';
|
|
13
|
-
import { getConfigurationValue } from '../../../common/config/init';
|
|
14
|
-
import { getRuntime } from '../../../common/config/runtime';
|
|
15
12
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
16
13
|
import { sharedChannel } from '../../../common/constants/shared-channel';
|
|
17
14
|
import { obj as encodeObj } from '../../../common/url/encode';
|
|
@@ -24,7 +21,6 @@ import { RRWEB_VERSION } from "../../../common/constants/env.npm";
|
|
|
24
21
|
import { MODE, SESSION_EVENTS, SESSION_EVENT_TYPES } from '../../../common/session/constants';
|
|
25
22
|
import { stringify } from '../../../common/util/stringify';
|
|
26
23
|
import { stylesheetEvaluator } from '../shared/stylesheet-evaluator';
|
|
27
|
-
import { deregisterDrain } from '../../../common/drain/drain';
|
|
28
24
|
import { now } from '../../../common/timing/now';
|
|
29
25
|
import { buildNRMetaNode } from '../shared/utils';
|
|
30
26
|
import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
|
|
@@ -34,10 +30,10 @@ export class Aggregate extends AggregateBase {
|
|
|
34
30
|
mode = MODE.OFF;
|
|
35
31
|
|
|
36
32
|
// pass the recorder into the aggregator
|
|
37
|
-
constructor(
|
|
38
|
-
super(
|
|
33
|
+
constructor(agentRef, args) {
|
|
34
|
+
super(agentRef, FEATURE_NAME);
|
|
39
35
|
/** The interval to harvest at. This gets overridden if the size of the payload exceeds certain thresholds */
|
|
40
|
-
this.harvestTimeSeconds =
|
|
36
|
+
this.harvestTimeSeconds = agentRef.init.session_replay.harvestTimeSeconds || 60;
|
|
41
37
|
/** Set once the recorder has fully initialized after flag checks and sampling */
|
|
42
38
|
this.initialized = false;
|
|
43
39
|
/** Set once the feature has been "aborted" to prevent other side-effects from continuing */
|
|
@@ -71,10 +67,7 @@ export class Aggregate extends AggregateBase {
|
|
|
71
67
|
this.ee.on(SESSION_EVENTS.RESUME, () => {
|
|
72
68
|
if (!this.recorder) return;
|
|
73
69
|
// if the mode changed on a different tab, it needs to update this instance to match
|
|
74
|
-
|
|
75
|
-
session
|
|
76
|
-
} = getRuntime(this.agentIdentifier);
|
|
77
|
-
this.mode = session.state.sessionReplayMode;
|
|
70
|
+
this.mode = agentRef.runtime.session.state.sessionReplayMode;
|
|
78
71
|
if (!this.initialized || this.mode === MODE.OFF) return;
|
|
79
72
|
this.recorder?.startRecording();
|
|
80
73
|
});
|
|
@@ -106,11 +99,11 @@ export class Aggregate extends AggregateBase {
|
|
|
106
99
|
mask_all_inputs,
|
|
107
100
|
inline_images,
|
|
108
101
|
collect_fonts
|
|
109
|
-
} =
|
|
102
|
+
} = agentRef.init.session_replay;
|
|
110
103
|
this.waitForFlags(['srs', 'sr']).then(([srMode, entitled]) => {
|
|
111
104
|
this.entitled = !!entitled;
|
|
112
105
|
if (!this.entitled) {
|
|
113
|
-
deregisterDrain(
|
|
106
|
+
this.deregisterDrain();
|
|
114
107
|
if (this.recorder?.recording) {
|
|
115
108
|
this.abort(ABORT_REASONS.ENTITLEMENTS);
|
|
116
109
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['SessionReplay/EnabledNotEntitled/Detected'], undefined, FEATURE_NAMES.metrics, this.ee);
|
|
@@ -180,7 +173,7 @@ export class Aggregate extends AggregateBase {
|
|
|
180
173
|
const {
|
|
181
174
|
session,
|
|
182
175
|
timeKeeper
|
|
183
|
-
} =
|
|
176
|
+
} = this.agentRef.runtime;
|
|
184
177
|
this.timeKeeper = timeKeeper;
|
|
185
178
|
if (this.recorder?.parent.trigger === TRIGGERS.API && this.recorder?.recording) {
|
|
186
179
|
this.mode = MODE.FULL;
|
|
@@ -296,10 +289,7 @@ export class Aggregate extends AggregateBase {
|
|
|
296
289
|
return;
|
|
297
290
|
}
|
|
298
291
|
// TODO -- Gracefully handle the buffer for retries.
|
|
299
|
-
|
|
300
|
-
session
|
|
301
|
-
} = getRuntime(this.agentIdentifier);
|
|
302
|
-
if (!session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({
|
|
292
|
+
if (!this.agentRef.runtime.session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({
|
|
303
293
|
sessionReplaySentFirstChunk: true
|
|
304
294
|
});
|
|
305
295
|
this.recorder.clearBuffer();
|
|
@@ -314,9 +304,8 @@ export class Aggregate extends AggregateBase {
|
|
|
314
304
|
getHarvestContents(recorderEvents) {
|
|
315
305
|
recorderEvents ??= this.recorder.getEvents();
|
|
316
306
|
let events = recorderEvents.events;
|
|
317
|
-
const agentRuntime =
|
|
318
|
-
const
|
|
319
|
-
const endUserId = info.jsAttributes?.['enduser.id'];
|
|
307
|
+
const agentRuntime = this.agentRef.runtime;
|
|
308
|
+
const endUserId = this.agentRef.info.jsAttributes?.['enduser.id'];
|
|
320
309
|
|
|
321
310
|
// do not let the first node be a full snapshot node, since this NEEDS to be preceded by a meta node
|
|
322
311
|
// we will manually inject it if this happens
|
|
@@ -344,9 +333,9 @@ export class Aggregate extends AggregateBase {
|
|
|
344
333
|
const agentMetadata = agentRuntime.appMetadata?.agents?.[0] || {};
|
|
345
334
|
return {
|
|
346
335
|
qs: {
|
|
347
|
-
browser_monitoring_key: info.licenseKey,
|
|
336
|
+
browser_monitoring_key: this.agentRef.info.licenseKey,
|
|
348
337
|
type: 'SessionReplay',
|
|
349
|
-
app_id: info.applicationID,
|
|
338
|
+
app_id: this.agentRef.info.applicationID,
|
|
350
339
|
protocol_version: '0',
|
|
351
340
|
timestamp: firstTimestamp,
|
|
352
341
|
attributes: encodeObj({
|
|
@@ -423,9 +412,6 @@ export class Aggregate extends AggregateBase {
|
|
|
423
412
|
while (this.recorder?.getEvents().events.length) this.recorder?.clearBuffer?.();
|
|
424
413
|
}
|
|
425
414
|
syncWithSessionManager(state = {}) {
|
|
426
|
-
|
|
427
|
-
session
|
|
428
|
-
} = getRuntime(this.agentIdentifier);
|
|
429
|
-
session.write(state);
|
|
415
|
+
this.agentRef.runtime.session.write(state);
|
|
430
416
|
}
|
|
431
417
|
}
|
|
@@ -14,21 +14,23 @@ import { FEATURE_NAME, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
|
|
|
14
14
|
export class Instrument extends InstrumentBase {
|
|
15
15
|
static featureName = FEATURE_NAME;
|
|
16
16
|
#mode;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
#agentRef;
|
|
18
|
+
constructor(agentRef, auto = true) {
|
|
19
|
+
super(agentRef, FEATURE_NAME, auto);
|
|
19
20
|
let session;
|
|
20
21
|
this.replayRunning = false;
|
|
22
|
+
this.#agentRef = agentRef;
|
|
21
23
|
try {
|
|
22
24
|
session = JSON.parse(localStorage.getItem("".concat(PREFIX, "_").concat(DEFAULT_KEY)));
|
|
23
25
|
} catch (err) {}
|
|
24
|
-
if (hasReplayPrerequisite(agentIdentifier)) {
|
|
26
|
+
if (hasReplayPrerequisite(agentRef.agentIdentifier)) {
|
|
25
27
|
this.ee.on(SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay());
|
|
26
28
|
}
|
|
27
29
|
if (this.#canPreloadRecorder(session)) {
|
|
28
30
|
this.#mode = session?.sessionReplayMode;
|
|
29
31
|
this.#preloadStartRecording();
|
|
30
32
|
} else {
|
|
31
|
-
this.importAggregator();
|
|
33
|
+
this.importAggregator(agentRef);
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
/** If the recorder is running, we can pass error events on to the agg to help it switch to full mode later */
|
|
@@ -82,7 +84,7 @@ export class Instrument extends InstrumentBase {
|
|
|
82
84
|
this.recorder.startRecording();
|
|
83
85
|
this.abortHandler = this.recorder.stopRecording;
|
|
84
86
|
} catch (e) {}
|
|
85
|
-
this.importAggregator({
|
|
87
|
+
this.importAggregator(this.#agentRef, {
|
|
86
88
|
recorder: this.recorder,
|
|
87
89
|
errorNoticed: this.errorNoticed
|
|
88
90
|
});
|