@newrelic/browser-agent 1.316.0 → 1.317.0-rc.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 +15 -0
- package/dist/cjs/common/config/configurable.js +1 -1
- package/dist/cjs/common/config/init-types.js +1 -0
- package/dist/cjs/common/config/init.js +6 -4
- package/dist/cjs/common/constants/env.cdn.js +2 -2
- package/dist/cjs/common/constants/env.npm.js +2 -2
- package/dist/cjs/common/constants/events.js +26 -0
- package/dist/cjs/common/harvest/harvester.js +9 -217
- package/dist/cjs/common/harvest/send.js +232 -0
- package/dist/cjs/common/harvest/types.js +9 -5
- package/dist/cjs/common/payloads/payloads.js +127 -0
- package/dist/cjs/common/serialize/bel-serializer.js +4 -3
- package/dist/cjs/common/session/session-entity.js +8 -8
- package/dist/cjs/common/util/data-size.js +2 -2
- package/dist/cjs/common/util/obfuscate.js +147 -3
- package/dist/cjs/common/v2/mfe-vitals.js +286 -0
- package/dist/cjs/common/wrap/wrap-websocket.js +2 -1
- package/dist/cjs/common/wrap/wrap-xhr.js +1 -1
- package/dist/cjs/features/ajax/aggregate/gql.js +40 -1
- package/dist/cjs/features/ajax/aggregate/index.js +51 -13
- package/dist/cjs/features/ajax/constants.js +6 -1
- package/dist/cjs/features/ajax/instrument/index.js +105 -17
- package/dist/cjs/features/generic_events/aggregate/index.js +15 -10
- package/dist/cjs/features/generic_events/constants.js +3 -2
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +12 -3
- package/dist/cjs/features/logging/aggregate/index.js +12 -8
- package/dist/cjs/features/metrics/aggregate/index.js +5 -1
- package/dist/cjs/features/page_view_event/aggregate/index.js +72 -33
- package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -1
- package/dist/cjs/features/session_replay/aggregate/index.js +39 -29
- package/dist/cjs/features/session_trace/aggregate/index.js +35 -29
- package/dist/cjs/features/session_trace/constants.js +17 -3
- package/dist/cjs/features/soft_navigations/aggregate/ajax-node.js +36 -5
- package/dist/cjs/features/soft_navigations/aggregate/index.js +7 -1
- package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
- package/dist/cjs/features/soft_navigations/aggregate/interaction.js +6 -4
- package/dist/cjs/features/utils/aggregate-base.js +4 -3
- package/dist/cjs/loaders/api/register.js +26 -4
- package/dist/esm/common/config/configurable.js +1 -1
- package/dist/esm/common/config/init-types.js +1 -0
- package/dist/esm/common/config/init.js +3 -1
- package/dist/esm/common/constants/env.cdn.js +2 -2
- package/dist/esm/common/constants/env.npm.js +2 -2
- package/dist/esm/common/constants/events.js +20 -0
- package/dist/esm/common/harvest/harvester.js +9 -217
- package/dist/esm/common/harvest/send.js +226 -0
- package/dist/esm/common/harvest/types.js +9 -5
- package/dist/esm/common/payloads/payloads.js +118 -0
- package/dist/esm/common/serialize/bel-serializer.js +4 -3
- package/dist/esm/common/session/session-entity.js +9 -9
- package/dist/esm/common/util/data-size.js +2 -2
- package/dist/esm/common/util/obfuscate.js +147 -3
- package/dist/esm/common/v2/mfe-vitals.js +281 -0
- package/dist/esm/common/wrap/wrap-websocket.js +2 -1
- package/dist/esm/common/wrap/wrap-xhr.js +1 -1
- package/dist/esm/features/ajax/aggregate/gql.js +39 -1
- package/dist/esm/features/ajax/aggregate/index.js +52 -14
- package/dist/esm/features/ajax/constants.js +5 -0
- package/dist/esm/features/ajax/instrument/index.js +106 -18
- package/dist/esm/features/generic_events/aggregate/index.js +15 -10
- package/dist/esm/features/generic_events/constants.js +3 -2
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.js +2 -2
- package/dist/esm/features/jserrors/aggregate/index.js +12 -3
- package/dist/esm/features/logging/aggregate/index.js +12 -8
- package/dist/esm/features/metrics/aggregate/index.js +5 -1
- package/dist/esm/features/page_view_event/aggregate/index.js +71 -32
- package/dist/esm/features/page_view_timing/aggregate/index.js +6 -1
- package/dist/esm/features/session_replay/aggregate/index.js +39 -29
- package/dist/esm/features/session_trace/aggregate/index.js +36 -30
- package/dist/esm/features/session_trace/constants.js +16 -2
- package/dist/esm/features/soft_navigations/aggregate/ajax-node.js +36 -5
- package/dist/esm/features/soft_navigations/aggregate/index.js +7 -1
- package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
- package/dist/esm/features/soft_navigations/aggregate/interaction.js +6 -4
- package/dist/esm/features/utils/aggregate-base.js +4 -3
- package/dist/esm/loaders/api/register.js +26 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/init-types.d.ts +4 -0
- package/dist/types/common/config/init-types.d.ts.map +1 -1
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/constants/events.d.ts +16 -0
- package/dist/types/common/constants/events.d.ts.map +1 -0
- package/dist/types/common/harvest/harvester.d.ts +2 -16
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/harvest/send.d.ts +9 -0
- package/dist/types/common/harvest/send.d.ts.map +1 -0
- package/dist/types/common/harvest/types.d.ts +39 -10
- package/dist/types/common/harvest/types.d.ts.map +1 -1
- package/dist/types/common/payloads/payloads.d.ts +42 -0
- package/dist/types/common/payloads/payloads.d.ts.map +1 -0
- package/dist/types/common/serialize/bel-serializer.d.ts +1 -1
- package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/util/obfuscate.d.ts +23 -2
- package/dist/types/common/util/obfuscate.d.ts.map +1 -1
- package/dist/types/common/v2/mfe-vitals.d.ts +14 -0
- package/dist/types/common/v2/mfe-vitals.d.ts.map +1 -0
- package/dist/types/common/wrap/wrap-websocket.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/gql.d.ts +8 -0
- package/dist/types/features/ajax/aggregate/gql.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +2 -0
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/constants.d.ts +5 -0
- package/dist/types/features/ajax/constants.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +3 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/constants.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +8 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +3 -1
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts +2 -0
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +3 -0
- 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 -0
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +4 -2
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +3 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts +17 -0
- package/dist/types/features/soft_navigations/aggregate/ajax-node.d.ts +6 -1
- package/dist/types/features/soft_navigations/aggregate/ajax-node.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts +3 -0
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/interaction.d.ts +3 -1
- package/dist/types/features/soft_navigations/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +0 -1
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/loaders/api/register.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/common/config/configurable.js +1 -1
- package/src/common/config/init-types.js +1 -0
- package/src/common/config/init.js +2 -1
- package/src/common/constants/events.js +20 -0
- package/src/common/harvest/harvester.js +9 -201
- package/src/common/harvest/send.js +209 -0
- package/src/common/harvest/types.js +9 -5
- package/src/common/payloads/payloads.js +135 -0
- package/src/common/serialize/bel-serializer.js +4 -3
- package/src/common/session/session-entity.js +8 -9
- package/src/common/util/data-size.js +2 -2
- package/src/common/util/obfuscate.js +154 -3
- package/src/common/v2/mfe-vitals.js +260 -0
- package/src/common/wrap/wrap-websocket.js +2 -1
- package/src/common/wrap/wrap-xhr.js +1 -1
- package/src/features/ajax/aggregate/gql.js +42 -1
- package/src/features/ajax/aggregate/index.js +43 -13
- package/src/features/ajax/constants.js +5 -1
- package/src/features/ajax/instrument/index.js +114 -18
- package/src/features/generic_events/aggregate/index.js +14 -9
- package/src/features/generic_events/constants.js +3 -2
- package/src/features/jserrors/aggregate/format-stack-trace.js +3 -3
- package/src/features/jserrors/aggregate/index.js +12 -3
- package/src/features/logging/aggregate/index.js +12 -11
- package/src/features/metrics/aggregate/index.js +5 -1
- package/src/features/page_view_event/aggregate/index.js +58 -29
- package/src/features/page_view_timing/aggregate/index.js +6 -1
- package/src/features/session_replay/aggregate/index.js +37 -28
- package/src/features/session_trace/aggregate/index.js +37 -30
- package/src/features/session_trace/constants.js +7 -1
- package/src/features/soft_navigations/aggregate/ajax-node.js +26 -5
- package/src/features/soft_navigations/aggregate/index.js +7 -1
- package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
- package/src/features/soft_navigations/aggregate/interaction.js +6 -4
- package/src/features/utils/aggregate-base.js +3 -3
- package/src/loaders/api/register.js +24 -4
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.AjaxNode = void 0;
|
|
7
7
|
var _belSerializer = require("../../../common/serialize/bel-serializer");
|
|
8
|
+
var _payloads = require("../../../common/payloads/payloads");
|
|
8
9
|
var _constants = require("../../ajax/constants");
|
|
9
10
|
var _constants2 = require("../constants");
|
|
10
11
|
var _belNode = require("./bel-node");
|
|
@@ -31,6 +32,12 @@ class AjaxNode extends _belNode.BelNode {
|
|
|
31
32
|
this.targetAttributes = ajaxEvent.targetAttributes;
|
|
32
33
|
this[_constants.AJAX_ID] = ajaxEvent[_constants.AJAX_ID]; // all AjaxRequest events should have a unique identifier to allow for easier grouping and analysis in the UI
|
|
33
34
|
|
|
35
|
+
// optional payload metadata attributes
|
|
36
|
+
this.requestBody = ajaxEvent.requestBody;
|
|
37
|
+
this.requestHeaders = ajaxEvent.requestHeaders;
|
|
38
|
+
this.requestQuery = ajaxEvent.requestQuery;
|
|
39
|
+
this.responseBody = ajaxEvent.responseBody;
|
|
40
|
+
this.responseHeaders = ajaxEvent.responseHeaders;
|
|
34
41
|
this.start = ajaxEvent.startTime;
|
|
35
42
|
this.end = ajaxEvent.endTime;
|
|
36
43
|
if (ajaxContext?.latestLongtaskEnd) {
|
|
@@ -38,8 +45,11 @@ class AjaxNode extends _belNode.BelNode {
|
|
|
38
45
|
this.callbackDuration = this.callbackEnd - this.end; // callbackDuration is the time from ajax loaded to last long task observed from it
|
|
39
46
|
} else this.callbackEnd = this.end; // if no long task was observed, callbackEnd is the same as end
|
|
40
47
|
}
|
|
41
|
-
serialize(parentStartTimestamp, agentRef) {
|
|
42
|
-
const
|
|
48
|
+
serialize(parentStartTimestamp, agentRef, ajaxObfuscator) {
|
|
49
|
+
const {
|
|
50
|
+
addString,
|
|
51
|
+
addStringWithTruncation
|
|
52
|
+
} = (0, _payloads.createStringAdders)(_belSerializer.getAddStringContext, ajaxObfuscator);
|
|
43
53
|
const nodeList = [];
|
|
44
54
|
|
|
45
55
|
// IMPORTANT: The order in which addString is called matters and correlates to the order in which string shows up in the harvest payload. Do not re-order the following code.
|
|
@@ -54,11 +64,32 @@ class AjaxNode extends _belNode.BelNode {
|
|
|
54
64
|
(0, _belSerializer.numeric)(this.callbackDuration),
|
|
55
65
|
// not relative
|
|
56
66
|
addString(this.method), (0, _belSerializer.numeric)(this.status), addString(this.domain), addString(this.path), (0, _belSerializer.numeric)(this.txSize), (0, _belSerializer.numeric)(this.rxSize), this.requestedWith, addString(this.nodeId), (0, _belSerializer.nullable)(this.spanId, addString, true) + (0, _belSerializer.nullable)(this.traceId, addString, true) + (0, _belSerializer.nullable)(this.spanTimestamp, _belSerializer.numeric)];
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
// Regular attributes: obfuscate only
|
|
68
|
+
const regularAttrs = (0, _belSerializer.addCustomAttributes)({
|
|
69
|
+
[_constants.AJAX_ID]: this[_constants.AJAX_ID],
|
|
59
70
|
...(this.targetAttributes || {}),
|
|
60
|
-
|
|
71
|
+
...(this.gql || {})
|
|
61
72
|
}, addString);
|
|
73
|
+
|
|
74
|
+
// Payload attributes: obfuscate then truncate
|
|
75
|
+
const payloadAttrs = (0, _belSerializer.addCustomAttributes)({
|
|
76
|
+
...(this.requestBody ? {
|
|
77
|
+
requestBody: this.requestBody
|
|
78
|
+
} : {}),
|
|
79
|
+
...(this.requestHeaders ? {
|
|
80
|
+
requestHeaders: this.requestHeaders
|
|
81
|
+
} : {}),
|
|
82
|
+
...(this.requestQuery ? {
|
|
83
|
+
requestQuery: this.requestQuery
|
|
84
|
+
} : {}),
|
|
85
|
+
...(this.responseBody ? {
|
|
86
|
+
responseBody: this.responseBody
|
|
87
|
+
} : {}),
|
|
88
|
+
...(this.responseHeaders ? {
|
|
89
|
+
responseHeaders: this.responseHeaders
|
|
90
|
+
} : {})
|
|
91
|
+
}, addStringWithTruncation);
|
|
92
|
+
let allAttachedNodes = [...regularAttrs, ...payloadAttrs];
|
|
62
93
|
this.children.forEach(node => allAttachedNodes.push(node.serialize())); // no children is expected under ajax nodes at this time
|
|
63
94
|
|
|
64
95
|
fields[1] = (0, _belSerializer.numeric)(allAttachedNodes.length);
|
|
@@ -10,10 +10,12 @@ var _webdriverDetection = require("../../../common/util/webdriver-detection");
|
|
|
10
10
|
var _loadTime = require("../../../common/vitals/load-time");
|
|
11
11
|
var _features = require("../../../loaders/features/features");
|
|
12
12
|
var _aggregateBase = require("../../utils/aggregate-base");
|
|
13
|
+
var _obfuscate = require("../../../common/util/obfuscate");
|
|
13
14
|
var _constants = require("../constants");
|
|
14
15
|
var _ajaxNode = require("./ajax-node");
|
|
15
16
|
var _initialPageLoadInteraction = require("./initial-page-load-interaction");
|
|
16
17
|
var _interaction = require("./interaction");
|
|
18
|
+
var _events = require("../../../common/constants/events");
|
|
17
19
|
/**
|
|
18
20
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
21
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -26,6 +28,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
26
28
|
}) {
|
|
27
29
|
super(agentRef, _constants.FEATURE_NAME);
|
|
28
30
|
super.customAttributesAreSeparate = true;
|
|
31
|
+
|
|
32
|
+
// Create obfuscators for browser interactions and nested AJAX requests
|
|
33
|
+
this.interactionObfuscator = new _obfuscate.Obfuscator(agentRef, _events.EVENT_TYPES.BI);
|
|
34
|
+
this.ajaxObfuscator = new _obfuscate.Obfuscator(agentRef, _events.EVENT_TYPES.AJAX);
|
|
29
35
|
this.interactionsToHarvest = this.events;
|
|
30
36
|
this.domObserver = domObserver;
|
|
31
37
|
this.initialPageLoadInteraction = new _initialPageLoadInteraction.InitialPageLoadInteraction(agentRef);
|
|
@@ -89,7 +95,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
89
95
|
let firstIxnStartTime;
|
|
90
96
|
const serializedIxnList = [];
|
|
91
97
|
for (const interaction of eventBuffer) {
|
|
92
|
-
serializedIxnList.push(interaction.serialize(firstIxnStartTime, this.agentRef));
|
|
98
|
+
serializedIxnList.push(interaction.serialize(firstIxnStartTime, this.agentRef, this.interactionObfuscator, this.ajaxObfuscator));
|
|
93
99
|
if (firstIxnStartTime === undefined) firstIxnStartTime = Math.floor(interaction.start); // careful not to match or overwrite on 0 value!
|
|
94
100
|
}
|
|
95
101
|
return "bel.7;".concat(serializedIxnList.join(';'));
|
|
@@ -11,7 +11,7 @@ var _firstPaint = require("../../../common/vitals/first-paint");
|
|
|
11
11
|
var _firstContentfulPaint = require("../../../common/vitals/first-contentful-paint");
|
|
12
12
|
var _constants = require("../constants");
|
|
13
13
|
/**
|
|
14
|
-
* Copyright 2020-
|
|
14
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
@@ -12,7 +12,7 @@ var _cleanUrl = require("../../../common/url/clean-url");
|
|
|
12
12
|
var _constants = require("../constants");
|
|
13
13
|
var _belNode = require("./bel-node");
|
|
14
14
|
/**
|
|
15
|
-
* Copyright 2020-
|
|
15
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
16
16
|
* SPDX-License-Identifier: Apache-2.0
|
|
17
17
|
*/
|
|
18
18
|
|
|
@@ -127,11 +127,13 @@ class Interaction extends _belNode.BelNode {
|
|
|
127
127
|
* Serializes (BEL) the interaction data for transmission.
|
|
128
128
|
* @param {Number} firstStartTimeOfPayload timestamp
|
|
129
129
|
* @param {Agent} agentRef Pass in the agent reference directly so that the event itself doesnt need to store the pointers and ruin the evaluation of the event size by including unused object references.
|
|
130
|
+
* @param {Obfuscator} interactionObfuscator Obfuscator for BrowserInteraction event type
|
|
131
|
+
* @param {Obfuscator} ajaxObfuscator Obfuscator for AjaxRequest event type (passed to child AjaxNodes)
|
|
130
132
|
* @returns {String} A string that is the serialized representation of this interaction.
|
|
131
133
|
*/
|
|
132
|
-
serialize(firstStartTimeOfPayload, agentRef) {
|
|
134
|
+
serialize(firstStartTimeOfPayload, agentRef, interactionObfuscator, ajaxObfuscator) {
|
|
133
135
|
const isFirstIxnOfPayload = firstStartTimeOfPayload === undefined;
|
|
134
|
-
const addString = (0, _belSerializer.getAddStringContext)(
|
|
136
|
+
const addString = (0, _belSerializer.getAddStringContext)(interactionObfuscator);
|
|
135
137
|
const nodeList = [];
|
|
136
138
|
let ixnType;
|
|
137
139
|
if (this.trigger === _constants.IPL_TRIGGER_NAME) ixnType = _constants.INTERACTION_TYPE.INITIAL_PAGE_LOAD;else if (this.newURL !== this.oldURL) ixnType = _constants.INTERACTION_TYPE.ROUTE_CHANGE;else ixnType = _constants.INTERACTION_TYPE.UNSPECIFIED;
|
|
@@ -157,7 +159,7 @@ class Interaction extends _belNode.BelNode {
|
|
|
157
159
|
/* Querypack encoder+decoder quirkiness:
|
|
158
160
|
- If first ixn node of payload is being processed, its children's start time must be offset by this node's start. (firstStartTime should be undefined.)
|
|
159
161
|
- Else for subsequent ixns in the same payload, we go back to using that first ixn node's start to offset their children's start. */
|
|
160
|
-
this.children.forEach(node => allAttachedNodes.push(node.serialize(isFirstIxnOfPayload ? this.start : firstStartTimeOfPayload, agentRef))); // recursively add the serialized string of every child of this (ixn) bel node
|
|
162
|
+
this.children.forEach(node => allAttachedNodes.push(node.serialize(isFirstIxnOfPayload ? this.start : firstStartTimeOfPayload, agentRef, ajaxObfuscator))); // recursively add the serialized string of every child of this (ixn) bel node
|
|
161
163
|
|
|
162
164
|
fields[1] = (0, _belSerializer.numeric)(allAttachedNodes.length);
|
|
163
165
|
nodeList.push(fields);
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.AggregateBase = void 0;
|
|
7
7
|
var _featureBase = require("./feature-base");
|
|
8
8
|
var _drain = require("../../common/drain/drain");
|
|
9
|
-
var _obfuscate = require("../../common/util/obfuscate");
|
|
10
9
|
var _features = require("../../loaders/features/features");
|
|
11
10
|
var _harvester = require("../../common/harvest/harvester");
|
|
12
11
|
var _eventBuffer = require("./event-buffer");
|
|
@@ -14,6 +13,7 @@ var _handle = require("../../common/event-emitter/handle");
|
|
|
14
13
|
var _constants = require("../metrics/constants");
|
|
15
14
|
var _eventAggregator = require("../../common/aggregate/event-aggregator");
|
|
16
15
|
var _agentConstants = require("../../common/constants/agent-constants");
|
|
16
|
+
var _console = require("../../common/util/console");
|
|
17
17
|
/**
|
|
18
18
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
19
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -118,6 +118,7 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
118
118
|
}
|
|
119
119
|
function buildOutput(ref) {
|
|
120
120
|
return flagNames.map(flag => {
|
|
121
|
+
if (ref[flag] === undefined || ref[flag] === null) (0, _console.warn)(71, flag);
|
|
121
122
|
if (!ref[flag]) return 0;
|
|
122
123
|
return ref[flag];
|
|
123
124
|
});
|
|
@@ -183,8 +184,8 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
183
184
|
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
184
185
|
*/
|
|
185
186
|
doOnceForAllAggregate(agentRef) {
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
// Note: obfuscator is now created per-feature for their specific event types
|
|
188
|
+
|
|
188
189
|
if (!agentRef.runtime.harvester) agentRef.runtime.harvester = new _harvester.Harvester(agentRef);
|
|
189
190
|
}
|
|
190
191
|
|
|
@@ -21,6 +21,7 @@ var _measure = require("./measure");
|
|
|
21
21
|
var _recordCustomEvent = require("./recordCustomEvent");
|
|
22
22
|
var _pageVisibility = require("../../common/window/page-visibility");
|
|
23
23
|
var _scriptTracker = require("../../common/v2/script-tracker");
|
|
24
|
+
var _mfeVitals = require("../../common/v2/mfe-vitals");
|
|
24
25
|
var _uniqueId = require("../../common/ids/unique-id");
|
|
25
26
|
/**
|
|
26
27
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
@@ -84,6 +85,9 @@ function register(agentRef, target) {
|
|
|
84
85
|
type: _utils.V2_TYPES.BA
|
|
85
86
|
};
|
|
86
87
|
const timings = (0, _scriptTracker.findScriptTimings)();
|
|
88
|
+
|
|
89
|
+
// Track MFE vitals for this entity
|
|
90
|
+
const vitals = (0, _mfeVitals.trackMFEVitals)(target.id);
|
|
87
91
|
const attrs = {};
|
|
88
92
|
|
|
89
93
|
// Only define attributes getter if it doesn't already exist
|
|
@@ -172,7 +176,8 @@ function register(agentRef, target) {
|
|
|
172
176
|
return attrs;
|
|
173
177
|
},
|
|
174
178
|
target,
|
|
175
|
-
timings
|
|
179
|
+
timings,
|
|
180
|
+
vitals
|
|
176
181
|
}
|
|
177
182
|
};
|
|
178
183
|
|
|
@@ -200,9 +205,17 @@ function register(agentRef, target) {
|
|
|
200
205
|
// only ever report the timings the first time this is called
|
|
201
206
|
if (timings.reportedAt) return;
|
|
202
207
|
timings.reportedAt = (0, _now.now)();
|
|
208
|
+
|
|
209
|
+
// Disconnect observers and capture current values, store in timings obj for visibility
|
|
210
|
+
vitals.disconnect();
|
|
211
|
+
timings.fcp = vitals.fcp;
|
|
212
|
+
timings.lcp = vitals.lcp;
|
|
213
|
+
timings.cls = vitals.cls;
|
|
214
|
+
timings.inp = vitals.inp;
|
|
203
215
|
const timeToFetch = timings.fetchEnd - timings.fetchStart; // fetchStart to fetchEnd
|
|
204
216
|
const timeToExecute = timings.scriptEnd - timings.scriptStart; // scriptStart to scriptEnd
|
|
205
|
-
|
|
217
|
+
|
|
218
|
+
const eventData = {
|
|
206
219
|
assetUrl: timings.asset,
|
|
207
220
|
// the url of the script that was registered, or undefined if it could not be determined (inline or no match)
|
|
208
221
|
assetType: timings.type,
|
|
@@ -217,8 +230,17 @@ function register(agentRef, target) {
|
|
|
217
230
|
// fetchStart to fetchEnd
|
|
218
231
|
timeToLoad: timeToFetch + timeToExecute,
|
|
219
232
|
// fetch time and script time together
|
|
220
|
-
timeToRegister: timings.registeredAt
|
|
221
|
-
|
|
233
|
+
timeToRegister: timings.registeredAt,
|
|
234
|
+
// timestamp when register() was called
|
|
235
|
+
'nr.vitals.fcp': vitals.fcp || null,
|
|
236
|
+
// FCP vital object with value and metadata
|
|
237
|
+
'nr.vitals.lcp': vitals.lcp || null,
|
|
238
|
+
// LCP vital object with value and metadata
|
|
239
|
+
'nr.vitals.cls': vitals.cls || null,
|
|
240
|
+
// CLS vital object with value and metadata
|
|
241
|
+
'nr.vitals.inp': vitals.inp || null // INP vital object with value and metadata
|
|
242
|
+
};
|
|
243
|
+
api.recordCustomEvent('MicroFrontEndTiming', eventData);
|
|
222
244
|
}
|
|
223
245
|
|
|
224
246
|
/**
|
|
@@ -17,7 +17,7 @@ export function getModeledObject(obj, model) {
|
|
|
17
17
|
output[key] = null;
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
|
-
if (Array.isArray(obj[key]) && Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]));else if (obj[key] instanceof Map || obj[key] instanceof Set || obj[key] instanceof Date || obj[key] instanceof RegExp) output[key] = obj[key];else if (typeof obj[key] === 'object' && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key]);else output[key] = obj[key];
|
|
20
|
+
if (Array.isArray(obj[key]) && Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]));else if (obj[key] instanceof Map || obj[key] instanceof Set || obj[key] instanceof Date || obj[key] instanceof RegExp) output[key] = obj[key];else if (typeof obj[key] === 'object' && model[key] !== null && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key]);else output[key] = obj[key];
|
|
21
21
|
} catch (e) {
|
|
22
22
|
if (!output[key]) warn(1, e);
|
|
23
23
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @property {boolean} [ajax.block_internal] - If true, agent requests going to harvest endpoint are treated as on deny list. In other words, agent will not self-report AJAX.
|
|
12
12
|
* @property {boolean} [ajax.enabled] - Turn on/off the ajax feature (on by default).
|
|
13
13
|
* @property {boolean} [ajax.autoStart] - If true, the agent will automatically start the ajax feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
14
|
+
* @property {('none'|'failures'|'all')} [ajax.capture_payloads] - Controls when AJAX request/response payloads are captured. 'none' = never capture, 'failures' = capture only on errors (4xx, 5xx, network errors, GraphQL errors), 'all' = always capture.
|
|
14
15
|
* @property {Object} [api]
|
|
15
16
|
* @property {Object} [api.register]
|
|
16
17
|
* @property {boolean} [api.register.enabled] - If true, the agent will allow registered children to be sent to the server.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { FEATURE_FLAGS } from '../../features/generic_events/constants';
|
|
6
|
+
import { CAPTURE_PAYLOAD_SETTINGS } from '../../features/ajax/constants';
|
|
6
7
|
import { isValidSelector } from '../dom/query-selector';
|
|
7
8
|
import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS } from '../session/constants';
|
|
8
9
|
import { warn } from '../util/console';
|
|
@@ -51,7 +52,8 @@ const InitModelFn = () => {
|
|
|
51
52
|
deny_list: undefined,
|
|
52
53
|
block_internal: true,
|
|
53
54
|
enabled: true,
|
|
54
|
-
autoStart: true
|
|
55
|
+
autoStart: true,
|
|
56
|
+
capture_payloads: CAPTURE_PAYLOAD_SETTINGS.NONE
|
|
55
57
|
},
|
|
56
58
|
api: {
|
|
57
59
|
register: {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
/**
|
|
12
12
|
* Exposes the version of the agent
|
|
13
13
|
*/
|
|
14
|
-
export const VERSION = "1.
|
|
14
|
+
export const VERSION = "1.317.0-rc.1";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Exposes the build type of the agent
|
|
@@ -25,4 +25,4 @@ export const BUILD_ENV = "CDN";
|
|
|
25
25
|
export const DIST_METHOD = 'CDN';
|
|
26
26
|
export const RRWEB_PACKAGE_NAME = '@newrelic/rrweb';
|
|
27
27
|
// Babel will inline this with the rrweb (fork) version on CDN builds.
|
|
28
|
-
export const RRWEB_VERSION = "1.1.
|
|
28
|
+
export const RRWEB_VERSION = "^1.1.2";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
/**
|
|
12
12
|
* Exposes the version of the agent
|
|
13
13
|
*/
|
|
14
|
-
export const VERSION = "1.
|
|
14
|
+
export const VERSION = "1.317.0-rc.1";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Exposes the build type of the agent
|
|
@@ -26,4 +26,4 @@ export const BUILD_ENV = 'NPM';
|
|
|
26
26
|
export const DIST_METHOD = 'NPM';
|
|
27
27
|
export const RRWEB_PACKAGE_NAME = '@newrelic/rrweb';
|
|
28
28
|
// Babel will inline this with the rrweb (fork) version on NPM dist esm/cjs builds.
|
|
29
|
-
export const RRWEB_VERSION = "1.1.
|
|
29
|
+
export const RRWEB_VERSION = "^1.1.2";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const EVENT_TYPES = {
|
|
7
|
+
AJAX: 'AjaxRequest',
|
|
8
|
+
PA: 'PageAction',
|
|
9
|
+
UA: 'UserAction',
|
|
10
|
+
BP: 'BrowserPerformance',
|
|
11
|
+
WS: 'WebSocket',
|
|
12
|
+
SPV: 'SecurityPolicyViolation',
|
|
13
|
+
JSE: 'JavaScriptError',
|
|
14
|
+
LOG: 'Log',
|
|
15
|
+
PVE: 'PageView',
|
|
16
|
+
PVT: 'PageViewTiming',
|
|
17
|
+
SR: 'SessionReplay',
|
|
18
|
+
ST: 'SessionTrace',
|
|
19
|
+
BI: 'BrowserInteraction'
|
|
20
|
+
};
|
|
@@ -3,19 +3,12 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants';
|
|
6
|
-
import { FEATURE_TO_ENDPOINT,
|
|
7
|
-
import { VERSION } from "../constants/env.npm";
|
|
8
|
-
import { globalScope, isWorkerScope } from '../constants/runtime';
|
|
6
|
+
import { FEATURE_TO_ENDPOINT, FEATURE_NAMES } from '../../loaders/features/features';
|
|
9
7
|
import { handle } from '../event-emitter/handle';
|
|
10
|
-
import { eventListenerOpts } from '../event-listener/event-listener-opts';
|
|
11
|
-
import { now } from '../timing/now';
|
|
12
8
|
import { subscribeToEOL } from '../unload/eol';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { stringify } from '../util/stringify';
|
|
17
|
-
import { getSubmitMethod, xhr as xhrMethod, xhrFetch as fetchMethod } from '../util/submit-data';
|
|
18
|
-
import { dispatchGlobalEvent } from '../dispatch/global-event';
|
|
9
|
+
import { getSubmitMethod, xhr as xhrMethod } from '../util/submit-data';
|
|
10
|
+
import { send } from './send';
|
|
11
|
+
import { Obfuscator } from '../util/obfuscate';
|
|
19
12
|
const RETRY = 'Harvester/Retry/';
|
|
20
13
|
const RETRY_ATTEMPTED = RETRY + 'Attempted/';
|
|
21
14
|
const RETRY_FAILED = RETRY + 'Failed/';
|
|
@@ -25,6 +18,10 @@ export class Harvester {
|
|
|
25
18
|
initializedAggregates = [];
|
|
26
19
|
constructor(agentRef) {
|
|
27
20
|
this.agentRef = agentRef;
|
|
21
|
+
|
|
22
|
+
// Create obfuscator for harvest metadata (referrer URL, etc.)
|
|
23
|
+
// No event type specified - applies to all harvests regardless of feature
|
|
24
|
+
this.obfuscator = new Obfuscator(agentRef);
|
|
28
25
|
subscribeToEOL(() => {
|
|
29
26
|
// do one last harvest round or check
|
|
30
27
|
this.initializedAggregates.forEach(aggregateInst => {
|
|
@@ -71,6 +68,7 @@ export class Harvester {
|
|
|
71
68
|
payload: output.payload,
|
|
72
69
|
localOpts,
|
|
73
70
|
submitMethod,
|
|
71
|
+
harvesterObfuscator: this.obfuscator,
|
|
74
72
|
cbFinished,
|
|
75
73
|
raw: aggregateInst.harvestOpts.raw,
|
|
76
74
|
featureName: aggregateInst.featureName,
|
|
@@ -99,210 +97,4 @@ export class Harvester {
|
|
|
99
97
|
aggregateInst.postHarvestCleanup(result);
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
|
|
106
|
-
*/
|
|
107
|
-
|
|
108
|
-
const warnings = {};
|
|
109
|
-
/**
|
|
110
|
-
* Initiate a harvest call.
|
|
111
|
-
* @param {NetworkSendSpec} param0 Specification for sending data
|
|
112
|
-
* @returns {boolean} True if a network call was made. Note that this does not mean or guarantee that it was successful.
|
|
113
|
-
*/
|
|
114
|
-
export function send(agentRef, {
|
|
115
|
-
endpoint,
|
|
116
|
-
payload,
|
|
117
|
-
localOpts = {},
|
|
118
|
-
submitMethod,
|
|
119
|
-
cbFinished,
|
|
120
|
-
raw,
|
|
121
|
-
featureName,
|
|
122
|
-
endpointVersion = 1
|
|
123
|
-
}) {
|
|
124
|
-
if (!agentRef.info.errorBeacon) return false;
|
|
125
|
-
let {
|
|
126
|
-
body,
|
|
127
|
-
qs
|
|
128
|
-
} = cleanPayload(payload);
|
|
129
|
-
if (Object.keys(body).length === 0 && !localOpts.sendEmptyBody) {
|
|
130
|
-
// if there's no body to send, just run onfinish stuff and return
|
|
131
|
-
if (cbFinished) cbFinished({
|
|
132
|
-
sent: false
|
|
133
|
-
});
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
const protocol = agentRef.init.ssl === false ? 'http' : 'https';
|
|
137
|
-
const perceivedBeacon = agentRef.init.proxy.beacon || agentRef.info.errorBeacon;
|
|
138
|
-
const url = raw ? "".concat(protocol, "://").concat(perceivedBeacon, "/").concat(endpoint) : "".concat(protocol, "://").concat(perceivedBeacon).concat(endpoint !== RUM ? '/' + endpoint : '', "/").concat(endpointVersion, "/").concat(agentRef.info.licenseKey);
|
|
139
|
-
const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint) : '';
|
|
140
|
-
let payloadParams = obj(qs, agentRef.runtime.maxBytes);
|
|
141
|
-
if (baseParams === '' && payloadParams.startsWith('&')) {
|
|
142
|
-
payloadParams = payloadParams.substring(1);
|
|
143
|
-
}
|
|
144
|
-
const fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
|
|
145
|
-
const gzip = !!qs?.attributes?.includes('gzip');
|
|
146
|
-
|
|
147
|
-
// all gzipped data is already in the correct format and needs no transformation
|
|
148
|
-
// all features going to 'events' endpoint should already be serialized & stringified
|
|
149
|
-
let stringBody = gzip || endpoint === EVENTS ? body : stringify(body);
|
|
150
|
-
|
|
151
|
-
// If body is null, undefined, or an empty object or array after stringifying, send an empty string instead.
|
|
152
|
-
if (!stringBody || stringBody.length === 0 || stringBody === '{}' || stringBody === '[]') stringBody = '';
|
|
153
|
-
|
|
154
|
-
// Warn--once per endpoint--if the agent tries to send large payloads
|
|
155
|
-
if (endpoint !== BLOBS && stringBody.length > 750000 && (warnings[endpoint] = (warnings[endpoint] || 0) + 1) === 1) warn(28, endpoint);
|
|
156
|
-
const headers = [{
|
|
157
|
-
key: 'content-type',
|
|
158
|
-
value: 'text/plain'
|
|
159
|
-
}];
|
|
160
|
-
|
|
161
|
-
/* Since workers don't support sendBeacon right now, they can only use XHR method.
|
|
162
|
-
Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
|
|
163
|
-
we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
|
|
164
|
-
Following the removal of img-element method. */
|
|
165
|
-
let result = submitMethod({
|
|
166
|
-
url: fullUrl,
|
|
167
|
-
body: stringBody,
|
|
168
|
-
sync: localOpts.isFinalHarvest && isWorkerScope,
|
|
169
|
-
headers
|
|
170
|
-
});
|
|
171
|
-
if (!localOpts.isFinalHarvest && cbFinished) {
|
|
172
|
-
// final harvests don't hold onto buffer data (shouldRetryOnFail is false), so cleanup isn't needed
|
|
173
|
-
if (submitMethod === xhrMethod) {
|
|
174
|
-
result.addEventListener('loadend', function () {
|
|
175
|
-
// `this` here in block refers to the XHR object in this scope, do not change the anon function to an arrow function
|
|
176
|
-
// status 0 refers to a local error, such as CORS or network failure, or a blocked request by the browser (e.g. adblocker)
|
|
177
|
-
const cbResult = {
|
|
178
|
-
sent: this.status !== 0,
|
|
179
|
-
status: this.status,
|
|
180
|
-
retry: shouldRetry(this.status),
|
|
181
|
-
fullUrl,
|
|
182
|
-
xhr: this,
|
|
183
|
-
responseText: this.responseText
|
|
184
|
-
};
|
|
185
|
-
cbFinished(cbResult);
|
|
186
|
-
|
|
187
|
-
/** temporary audit of consistency of harvest metadata flags */
|
|
188
|
-
if (!shouldRetry(this.status)) trackHarvestMetadata();
|
|
189
|
-
}, eventListenerOpts(false));
|
|
190
|
-
} else if (submitMethod === fetchMethod) {
|
|
191
|
-
result.then(async function (response) {
|
|
192
|
-
const status = response.status;
|
|
193
|
-
const cbResult = {
|
|
194
|
-
sent: true,
|
|
195
|
-
status,
|
|
196
|
-
retry: shouldRetry(status),
|
|
197
|
-
fullUrl,
|
|
198
|
-
fetchResponse: response,
|
|
199
|
-
responseText: await response.text()
|
|
200
|
-
};
|
|
201
|
-
cbFinished(cbResult);
|
|
202
|
-
/** temporary audit of consistency of harvest metadata flags */
|
|
203
|
-
if (!shouldRetry(status)) trackHarvestMetadata();
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
function trackHarvestMetadata() {
|
|
207
|
-
try {
|
|
208
|
-
if (featureName === FEATURE_NAMES.jserrors && !body?.err) return;
|
|
209
|
-
const hasReplay = baseParams.includes('hr=1');
|
|
210
|
-
const hasTrace = baseParams.includes('ht=1');
|
|
211
|
-
const hasError = qs?.attributes?.includes('hasError=true');
|
|
212
|
-
handle('harvest-metadata', [{
|
|
213
|
-
[featureName]: {
|
|
214
|
-
...(hasReplay && {
|
|
215
|
-
hasReplay
|
|
216
|
-
}),
|
|
217
|
-
...(hasTrace && {
|
|
218
|
-
hasTrace
|
|
219
|
-
}),
|
|
220
|
-
...(hasError && {
|
|
221
|
-
hasError
|
|
222
|
-
})
|
|
223
|
-
}
|
|
224
|
-
}], undefined, FEATURE_NAMES.metrics, agentRef.ee);
|
|
225
|
-
} catch (err) {
|
|
226
|
-
// do nothing
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
dispatchGlobalEvent({
|
|
231
|
-
drained: !!agentRef.runtime?.activatedFeatures,
|
|
232
|
-
type: 'data',
|
|
233
|
-
name: 'harvest',
|
|
234
|
-
feature: featureName,
|
|
235
|
-
data: {
|
|
236
|
-
endpoint,
|
|
237
|
-
headers,
|
|
238
|
-
payload,
|
|
239
|
-
submitMethod: getSubmitMethodName(),
|
|
240
|
-
raw,
|
|
241
|
-
synchronousXhr: !!(localOpts.isFinalHarvest && isWorkerScope)
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
return true;
|
|
245
|
-
function shouldRetry(status) {
|
|
246
|
-
switch (status) {
|
|
247
|
-
case 408:
|
|
248
|
-
case 429:
|
|
249
|
-
case 500:
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
return status >= 502 && status <= 504 || status >= 512 && status <= 530;
|
|
253
|
-
}
|
|
254
|
-
function getSubmitMethodName() {
|
|
255
|
-
if (submitMethod === xhrMethod) return 'xhr';
|
|
256
|
-
if (submitMethod === fetchMethod) return 'fetch';
|
|
257
|
-
return 'beacon';
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Cleans and returns a payload object containing a body and qs
|
|
263
|
-
* object with key/value pairs. KV pairs where the value is null,
|
|
264
|
-
* undefined, or an empty string are removed to save on transmission
|
|
265
|
-
* size.
|
|
266
|
-
* @param {HarvestPayload} payload Payload to be sent to the endpoint.
|
|
267
|
-
* @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
|
|
268
|
-
*/
|
|
269
|
-
function cleanPayload(payload = {}) {
|
|
270
|
-
const clean = input => {
|
|
271
|
-
if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array || Array.isArray(input)) return input;
|
|
272
|
-
if (typeof input === 'string') return input;
|
|
273
|
-
return Object.entries(input || {}).reduce((accumulator, [key, value]) => {
|
|
274
|
-
if (typeof value === 'number' || typeof value === 'string' && value.length > 0 || typeof value === 'object' && Object.keys(value || {}).length > 0) {
|
|
275
|
-
accumulator[key] = value;
|
|
276
|
-
}
|
|
277
|
-
return accumulator;
|
|
278
|
-
}, {});
|
|
279
|
-
};
|
|
280
|
-
return {
|
|
281
|
-
body: clean(payload.body),
|
|
282
|
-
qs: clean(payload.qs)
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// The stuff that gets sent every time.
|
|
287
|
-
function baseQueryString(agentRef, qs, endpoint) {
|
|
288
|
-
const ref = agentRef.runtime.obfuscator.obfuscateString(cleanURL('' + globalScope.location));
|
|
289
|
-
const session = agentRef.runtime.session;
|
|
290
|
-
const hr = !!session?.state.sessionReplaySentFirstChunk && session?.state.sessionReplayMode === 1 && endpoint !== JSERRORS;
|
|
291
|
-
const ht = !!session?.state.traceHarvestStarted && session?.state.sessionTraceMode === 1 && ![LOGS, BLOBS].includes(endpoint);
|
|
292
|
-
const qps = ['a=' + agentRef.info.applicationID, param('sa', agentRef.info.sa ? '' + agentRef.info.sa : ''), param('v', VERSION), transactionNameParam(), param('ct', agentRef.runtime.customTransaction), '&rst=' + now(), '&ck=0',
|
|
293
|
-
// ck param DEPRECATED - still expected by backend
|
|
294
|
-
'&s=' + (session?.state.value || '0'),
|
|
295
|
-
// the 0 id encaps all untrackable and default traffic
|
|
296
|
-
param('ref', ref), param('ptid', agentRef.runtime.ptid ? '' + agentRef.runtime.ptid : '')];
|
|
297
|
-
if (hr) qps.push(param('hr', '1', qs));
|
|
298
|
-
if (ht) qps.push(param('ht', '1', qs));
|
|
299
|
-
return qps.join('');
|
|
300
|
-
|
|
301
|
-
// Constructs the transaction name param for the beacon URL.
|
|
302
|
-
// Prefers the obfuscated transaction name over the plain text.
|
|
303
|
-
// Falls back to making up a name.
|
|
304
|
-
function transactionNameParam() {
|
|
305
|
-
if (agentRef.info.transactionName) return param('to', agentRef.info.transactionName);
|
|
306
|
-
return param('t', agentRef.info.tNamePlain || 'Unnamed Transaction');
|
|
307
|
-
}
|
|
308
100
|
}
|