@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
|
@@ -10,6 +10,7 @@ var _now = require("../timing/now");
|
|
|
10
10
|
var _cleanUrl = require("../url/clean-url");
|
|
11
11
|
var _nreum = require("../window/nreum");
|
|
12
12
|
var _pageVisibility = require("../window/page-visibility");
|
|
13
|
+
var _events = require("../constants/events");
|
|
13
14
|
/**
|
|
14
15
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
15
16
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -40,7 +41,7 @@ function wrapWebSocket(sharedEE) {
|
|
|
40
41
|
});
|
|
41
42
|
});
|
|
42
43
|
class WrappedWebSocket extends WebSocket {
|
|
43
|
-
static name =
|
|
44
|
+
static name = _events.EVENT_TYPES.WS;
|
|
44
45
|
static toString() {
|
|
45
46
|
// fake native WebSocket when static class is stringified
|
|
46
47
|
return 'function WebSocket() { [native code] }';
|
|
@@ -23,7 +23,7 @@ var _utils = require("../v2/utils");
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
const wrapped = {};
|
|
26
|
-
const XHR_PROPS = ['open', 'send']; // these are the specific funcs being wrapped on all XMLHttpRequests(.prototype)
|
|
26
|
+
const XHR_PROPS = ['open', 'send', 'setRequestHeader']; // these are the specific funcs being wrapped on all XMLHttpRequests(.prototype)
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Wraps the native XMLHttpRequest (XHR) object to emit custom events to its readystatechange event and an assortment
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.hasGQLErrors = hasGQLErrors;
|
|
6
7
|
exports.parseGQL = parseGQL;
|
|
7
8
|
var _typeCheck = require("../../../common/util/type-check");
|
|
8
9
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
10
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
11
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -95,4 +96,42 @@ function parseGQLQueryString(gqlQueryString) {
|
|
|
95
96
|
}
|
|
96
97
|
function validateGQLObject(obj) {
|
|
97
98
|
return !(typeof obj !== 'object' || !obj.query || typeof obj.query !== 'string');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Checks if a response object has valid GraphQL errors.
|
|
103
|
+
* @param {object} response - A single GraphQL response object
|
|
104
|
+
* @returns {boolean} True if the response has valid errors
|
|
105
|
+
*/
|
|
106
|
+
function hasValidGQLErrors(response) {
|
|
107
|
+
return Array.isArray(response?.errors) && response.errors.some(err => err && typeof err === 'object' && typeof err.message === 'string');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Checks if a response body contains GraphQL errors according to the GraphQL spec.
|
|
112
|
+
* A valid GraphQL error response contains an "errors" array with at least one error object.
|
|
113
|
+
* Supports both single and batched GraphQL responses.
|
|
114
|
+
* @param {string|object|array} [responseBody] The response body to check
|
|
115
|
+
* @returns {boolean} True if the response contains GraphQL errors
|
|
116
|
+
*/
|
|
117
|
+
function hasGQLErrors(responseBody) {
|
|
118
|
+
if (!responseBody) return false;
|
|
119
|
+
try {
|
|
120
|
+
let parsed = responseBody;
|
|
121
|
+
|
|
122
|
+
// Parse string to object if needed
|
|
123
|
+
if (typeof responseBody === 'string') {
|
|
124
|
+
parsed = JSON.parse(responseBody);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Handle batched GraphQL responses (array of response objects)
|
|
128
|
+
if (Array.isArray(parsed)) {
|
|
129
|
+
return parsed.some(hasValidGQLErrors);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Handle single GraphQL response
|
|
133
|
+
return hasValidGQLErrors(parsed);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
98
137
|
}
|
|
@@ -11,10 +11,13 @@ var _denyList = require("../../../common/deny-list/deny-list");
|
|
|
11
11
|
var _constants = require("../constants");
|
|
12
12
|
var _features = require("../../../loaders/features/features");
|
|
13
13
|
var _aggregateBase = require("../../utils/aggregate-base");
|
|
14
|
-
var _gql = require("./gql");
|
|
15
14
|
var _belSerializer = require("../../../common/serialize/bel-serializer");
|
|
16
15
|
var _nreum = require("../../../common/window/nreum");
|
|
16
|
+
var _gql = require("./gql");
|
|
17
|
+
var _payloads = require("../../../common/payloads/payloads");
|
|
18
|
+
var _obfuscate = require("../../../common/util/obfuscate");
|
|
17
19
|
var _utils = require("../../../common/v2/utils");
|
|
20
|
+
var _events = require("../../../common/constants/events");
|
|
18
21
|
var _uniqueId = require("../../../common/ids/unique-id");
|
|
19
22
|
/**
|
|
20
23
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
@@ -27,6 +30,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
27
30
|
super(agentRef, _constants.FEATURE_NAME);
|
|
28
31
|
(0, _denyList.setDenyList)(agentRef.runtime.denyList);
|
|
29
32
|
const classThis = this;
|
|
33
|
+
|
|
34
|
+
// Create obfuscator for AJAX requests
|
|
35
|
+
this.obfuscator = new _obfuscate.Obfuscator(agentRef, _events.EVENT_TYPES.AJAX);
|
|
30
36
|
if (!agentRef.init.ajax.block_internal) {
|
|
31
37
|
// if the agent is tracking ITSELF, it can spawn endless ajax requests early if they are large from custom attributes, so we just disable early harvest for ajax in this case.
|
|
32
38
|
super.canHarvestEarly = false;
|
|
@@ -91,17 +97,26 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
91
97
|
callbackDuration: metrics.cbTime,
|
|
92
98
|
[_constants.AJAX_ID]: (0, _uniqueId.generateUuid)() // all AjaxRequest events should have a unique identifier to allow for easier grouping and analysis in the UI
|
|
93
99
|
};
|
|
100
|
+
event.gql = params.gql = (0, _gql.parseGQL)({
|
|
101
|
+
body: ctx.requestBody,
|
|
102
|
+
query: ctx.parsedOrigin?.search
|
|
103
|
+
});
|
|
104
|
+
if (event.gql) event.gql.operationHasErrors = params.gql.operationHasErrors = (0, _gql.hasGQLErrors)(ctx.responseBody);
|
|
105
|
+
const capturePayloadSetting = this.agentRef.init.ajax.capture_payloads;
|
|
106
|
+
const shouldCapturePayload = (0, _payloads.canCapturePayload)(capturePayloadSetting, params.status, event.gql?.operationHasErrors);
|
|
107
|
+
if (shouldCapturePayload) {
|
|
108
|
+
// Store raw data; obfuscation and truncation will happen in the serializer
|
|
109
|
+
params.requestQuery = event.requestQuery = (0, _payloads.parseQueryString)(ctx.parsedOrigin?.search);
|
|
110
|
+
params.requestHeaders = event.requestHeaders = ctx.requestHeaders;
|
|
111
|
+
params.responseHeaders = event.responseHeaders = ctx.responseHeaders;
|
|
112
|
+
if ((0, _payloads.isLikelyHumanReadable)(ctx.requestHeaders, ctx.requestBody)) params.requestBody = event.requestBody = ctx.requestBody;
|
|
113
|
+
if ((0, _payloads.isLikelyHumanReadable)(ctx.responseHeaders, ctx.responseBody)) params.responseBody = event.responseBody = ctx.responseBody;
|
|
114
|
+
}
|
|
94
115
|
if (ctx.dt) {
|
|
95
116
|
event.spanId = ctx.dt.spanId;
|
|
96
117
|
event.traceId = ctx.dt.traceId;
|
|
97
118
|
event.spanTimestamp = Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp));
|
|
98
119
|
}
|
|
99
|
-
|
|
100
|
-
// parsed from the AJAX body, looking for operationName param & parsing query for operationType
|
|
101
|
-
event.gql = params.gql = (0, _gql.parseGQL)({
|
|
102
|
-
body: ctx.body,
|
|
103
|
-
query: ctx.parsedOrigin?.search
|
|
104
|
-
});
|
|
105
120
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', (0, _stringify.stringify)(event.gql).length);
|
|
106
121
|
|
|
107
122
|
/** make a copy of the event for the MFE target if it exists */
|
|
@@ -129,7 +144,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
129
144
|
}
|
|
130
145
|
serializer(eventBuffer) {
|
|
131
146
|
if (!eventBuffer.length) return;
|
|
132
|
-
const
|
|
147
|
+
const {
|
|
148
|
+
addString,
|
|
149
|
+
addStringWithTruncation
|
|
150
|
+
} = (0, _payloads.createStringAdders)(_belSerializer.getAddStringContext, this.obfuscator);
|
|
133
151
|
let payload = 'bel.7;';
|
|
134
152
|
let firstTimestamp = 0;
|
|
135
153
|
for (let i = 0; i < eventBuffer.length; i++) {
|
|
@@ -154,15 +172,35 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
154
172
|
// Since configuration objects (like info) are created new each time they are set, we have to grab the current pointer to the attr object here.
|
|
155
173
|
const jsAttributes = this.agentRef.info.jsAttributes;
|
|
156
174
|
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
const attrParts = (0, _belSerializer.addCustomAttributes)({
|
|
175
|
+
// Regular attributes: obfuscate only
|
|
176
|
+
const regularAttrs = (0, _belSerializer.addCustomAttributes)({
|
|
160
177
|
...(jsAttributes || {}),
|
|
161
|
-
|
|
178
|
+
[_constants.AJAX_ID]: event[_constants.AJAX_ID],
|
|
179
|
+
// all AjaxRequest events should have a unique identifier to allow for easier grouping and analysis in the UI
|
|
162
180
|
...(event.targetAttributes || {}),
|
|
163
181
|
// used to supply the version 2 attributes, either MFE target or duplication attributes for the main agent app
|
|
164
|
-
|
|
182
|
+
...(event.gql || {})
|
|
165
183
|
}, addString);
|
|
184
|
+
|
|
185
|
+
// Payload attributes: obfuscate then truncate
|
|
186
|
+
const payloadAttrs = (0, _belSerializer.addCustomAttributes)({
|
|
187
|
+
...(event.requestBody ? {
|
|
188
|
+
requestBody: event.requestBody
|
|
189
|
+
} : {}),
|
|
190
|
+
...(event.requestHeaders ? {
|
|
191
|
+
requestHeaders: event.requestHeaders
|
|
192
|
+
} : {}),
|
|
193
|
+
...(event.requestQuery ? {
|
|
194
|
+
requestQuery: event.requestQuery
|
|
195
|
+
} : {}),
|
|
196
|
+
...(event.responseBody ? {
|
|
197
|
+
responseBody: event.responseBody
|
|
198
|
+
} : {}),
|
|
199
|
+
...(event.responseHeaders ? {
|
|
200
|
+
responseHeaders: event.responseHeaders
|
|
201
|
+
} : {})
|
|
202
|
+
}, addStringWithTruncation);
|
|
203
|
+
const attrParts = [...regularAttrs, ...payloadAttrs];
|
|
166
204
|
fields.unshift((0, _belSerializer.numeric)(attrParts.length));
|
|
167
205
|
insert += fields.join(',');
|
|
168
206
|
if (attrParts && attrParts.length > 0) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.FEATURE_NAME = exports.AJAX_ID = void 0;
|
|
6
|
+
exports.FEATURE_NAME = exports.CAPTURE_PAYLOAD_SETTINGS = exports.AJAX_ID = void 0;
|
|
7
7
|
var _features = require("../../loaders/features/features");
|
|
8
8
|
/**
|
|
9
9
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
@@ -11,4 +11,9 @@ var _features = require("../../loaders/features/features");
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
const FEATURE_NAME = exports.FEATURE_NAME = _features.FEATURE_NAMES.ajax;
|
|
14
|
+
const CAPTURE_PAYLOAD_SETTINGS = exports.CAPTURE_PAYLOAD_SETTINGS = {
|
|
15
|
+
NONE: 'none',
|
|
16
|
+
FAILURES: 'failures',
|
|
17
|
+
ALL: 'all'
|
|
18
|
+
};
|
|
14
19
|
const AJAX_ID = exports.AJAX_ID = 'ajaxRequest.id';
|
|
@@ -31,6 +31,7 @@ var handlersLen = handlers.length;
|
|
|
31
31
|
var origRequest = (0, _nreum.gosNREUMOriginals)().o.REQ;
|
|
32
32
|
var origXHR = (0, _nreum.gosNREUMOriginals)().o.XHR;
|
|
33
33
|
const NR_CAT_HEADER = 'X-NewRelic-App-Data';
|
|
34
|
+
const INTERNAL_ERROR = 'internal-error';
|
|
34
35
|
class Instrument extends _instrumentBase.InstrumentBase {
|
|
35
36
|
static featureName = _constants.FEATURE_NAME;
|
|
36
37
|
constructor(agentRef) {
|
|
@@ -77,10 +78,12 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
77
78
|
}
|
|
78
79
|
exports.Instrument = Instrument;
|
|
79
80
|
function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
81
|
+
const shouldInterceptPayloads = [_constants.CAPTURE_PAYLOAD_SETTINGS.ALL, _constants.CAPTURE_PAYLOAD_SETTINGS.FAILURES].includes(agentRef.init.ajax?.capture_payloads);
|
|
80
82
|
ee.on('new-xhr', onNewXhr);
|
|
81
83
|
ee.on('open-xhr-start', onOpenXhrStart);
|
|
82
84
|
ee.on('open-xhr-end', onOpenXhrEnd);
|
|
83
85
|
ee.on('send-xhr-start', onSendXhrStart);
|
|
86
|
+
ee.on('setRequestHeader-xhr-start', onSetRequestHeader);
|
|
84
87
|
ee.on('xhr-cb-time', onXhrCbTime);
|
|
85
88
|
ee.on('xhr-load-added', onXhrLoadAdded);
|
|
86
89
|
ee.on('xhr-load-removed', onXhrLoadRemoved);
|
|
@@ -152,6 +155,13 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
152
155
|
}
|
|
153
156
|
}
|
|
154
157
|
}
|
|
158
|
+
function onSetRequestHeader(args, xhr) {
|
|
159
|
+
// args[0] = header name, args[1] = header value
|
|
160
|
+
if (shouldInterceptPayloads && args.length >= 2) {
|
|
161
|
+
this.requestHeaders ??= {};
|
|
162
|
+
this.requestHeaders[args[0].toLowerCase()] = args[1];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
155
165
|
function onSendXhrStart(args, xhr) {
|
|
156
166
|
var metrics = this.metrics;
|
|
157
167
|
var data = args[0];
|
|
@@ -161,7 +171,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
161
171
|
if (size) metrics.txSize = size;
|
|
162
172
|
}
|
|
163
173
|
this.startTime = (0, _now.now)();
|
|
164
|
-
this.
|
|
174
|
+
this.requestBody = data;
|
|
165
175
|
this.listener = function (evt) {
|
|
166
176
|
try {
|
|
167
177
|
if (evt.type === 'abort' && !context.loadCaptureCalled) {
|
|
@@ -170,7 +180,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
170
180
|
if (evt.type !== 'load' || context.called === context.totalCbs && (context.onloadCalled || typeof xhr.onload !== 'function') && typeof context.end === 'function') context.end(xhr);
|
|
171
181
|
} catch (e) {
|
|
172
182
|
try {
|
|
173
|
-
ee.emit(
|
|
183
|
+
ee.emit(INTERNAL_ERROR, [e]);
|
|
174
184
|
} catch (err) {
|
|
175
185
|
// do nothing
|
|
176
186
|
}
|
|
@@ -298,8 +308,27 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
298
308
|
addUrl(this, (0, _extractUrl.extractUrl)(target));
|
|
299
309
|
const method = ('' + (target && target instanceof origRequest && target.method || opts.method || 'GET')).toUpperCase();
|
|
300
310
|
this.params.method = method;
|
|
301
|
-
this.
|
|
302
|
-
|
|
311
|
+
this.txSize = (0, _dataSize.dataSize)(opts.body || target?.body) || 0;
|
|
312
|
+
|
|
313
|
+
// Capture request headers
|
|
314
|
+
try {
|
|
315
|
+
var headers = opts.headers || target?.headers;
|
|
316
|
+
if (shouldInterceptPayloads && headers) {
|
|
317
|
+
this.requestHeaders ??= {};
|
|
318
|
+
if (headers instanceof Headers) {
|
|
319
|
+
headers.forEach(function (value, key) {
|
|
320
|
+
this.requestHeaders[key.toLowerCase()] = value;
|
|
321
|
+
}.bind(this));
|
|
322
|
+
} else if (typeof headers === 'object') {
|
|
323
|
+
for (var key in headers) {
|
|
324
|
+
this.requestHeaders[key.toLowerCase()] = headers[key];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
} catch (e) {
|
|
329
|
+
// Silently fail if we can't access headers
|
|
330
|
+
}
|
|
331
|
+
this.requestBody = opts.body || target?.body;
|
|
303
332
|
}
|
|
304
333
|
|
|
305
334
|
// we capture failed call as status 0, the actual error is ignored
|
|
@@ -310,19 +339,45 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
310
339
|
if ((0, _denyList.hasUndefinedHostname)(this.params)) return; // don't bother with fetch to url with no hostname
|
|
311
340
|
|
|
312
341
|
this.params.status = res ? res.status : 0;
|
|
342
|
+
const finishAndReport = () => {
|
|
343
|
+
// convert rxSize to a number - handle both string (from content-length header) and number (from fallback)
|
|
344
|
+
const num = +this.rxSize;
|
|
345
|
+
const responseSize = this.rxSize != null && !isNaN(num) ? num : undefined;
|
|
346
|
+
const metrics = {
|
|
347
|
+
txSize: this.txSize,
|
|
348
|
+
rxSize: responseSize,
|
|
349
|
+
duration: this.endTime - this.startTime
|
|
350
|
+
};
|
|
351
|
+
const payload = [this.params, metrics, this.startTime, this.endTime, 'fetch'];
|
|
352
|
+
this.targets.forEach(target => reportToAgg(payload, this, target));
|
|
353
|
+
};
|
|
313
354
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
|
|
355
|
+
/** Since accessing fetch bodies is an async process, these are
|
|
356
|
+
* reasonable conditions to check to not do needless extra work */
|
|
357
|
+
if (!res || !shouldInterceptPayloads) {
|
|
358
|
+
finishAndReport();
|
|
359
|
+
return;
|
|
318
360
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
361
|
+
|
|
362
|
+
// Clone the response to read the body without consuming the original
|
|
363
|
+
res.clone().text().then(text => {
|
|
364
|
+
this.responseBody = text;
|
|
365
|
+
// Use captured payload size as fallback if content-length header was missing or is 0 with a body
|
|
366
|
+
// Only apply fallback for non-network-error responses (status !== 0)
|
|
367
|
+
if ((!this.rxSize || this.rxSize === '0' || this.rxSize === 0) && text !== undefined && this.params.status !== 0) {
|
|
368
|
+
this.rxSize = (0, _dataSize.dataSize)(text);
|
|
369
|
+
}
|
|
370
|
+
if (res?.headers) {
|
|
371
|
+
this.responseHeaders = {};
|
|
372
|
+
res.headers.forEach(function (value, key) {
|
|
373
|
+
this.responseHeaders[key.toLowerCase()] = value;
|
|
374
|
+
}.bind(this));
|
|
375
|
+
}
|
|
376
|
+
}).catch(err => {
|
|
377
|
+
ee.emit(INTERNAL_ERROR, [err]);
|
|
378
|
+
}).finally(() => {
|
|
379
|
+
finishAndReport();
|
|
380
|
+
});
|
|
326
381
|
}
|
|
327
382
|
|
|
328
383
|
// Create report for XHR request that has finished
|
|
@@ -337,7 +392,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
337
392
|
if (params.aborted) return;
|
|
338
393
|
if ((0, _denyList.hasUndefinedHostname)(params)) return; // don't bother with XHR of url with no hostname
|
|
339
394
|
|
|
340
|
-
metrics.duration =
|
|
395
|
+
metrics.duration = this.endTime - this.startTime;
|
|
341
396
|
if (!this.loadCaptureCalled && xhr.readyState === 4) {
|
|
342
397
|
captureXhrData(this, xhr);
|
|
343
398
|
} else if (params.status == null) {
|
|
@@ -346,6 +401,25 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
346
401
|
|
|
347
402
|
// Always send cbTime, even if no noticeable time was taken.
|
|
348
403
|
metrics.cbTime = this.cbTime;
|
|
404
|
+
if (shouldInterceptPayloads) {
|
|
405
|
+
try {
|
|
406
|
+
this.responseBody = xhr.responseText;
|
|
407
|
+
} catch (e) {
|
|
408
|
+
this.responseBody = xhr.response;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Use captured payload size as fallback if not already determined or is 0 with a body
|
|
412
|
+
// Only apply fallback for non-network-error responses (status !== 0)
|
|
413
|
+
if ((!metrics.rxSize || metrics.rxSize === 0) && this.responseBody !== undefined && params.status !== 0) {
|
|
414
|
+
const size = (0, _dataSize.dataSize)(this.responseBody);
|
|
415
|
+
if (size !== undefined) metrics.rxSize = size;
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
this.responseHeaders = parseResponseHeaders(xhr.getAllResponseHeaders());
|
|
419
|
+
} catch (err) {
|
|
420
|
+
ee.emit(INTERNAL_ERROR, [err]);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
349
423
|
const payload = [params, metrics, this.startTime, this.endTime, 'xhr'];
|
|
350
424
|
this.targets.forEach(target => reportToAgg(payload, this, target));
|
|
351
425
|
}
|
|
@@ -355,7 +429,8 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
355
429
|
function captureXhrData(ctx, xhr) {
|
|
356
430
|
ctx.params.status = xhr.status;
|
|
357
431
|
var size = (0, _responseSize.responseSizeFromXhr)(xhr, ctx.lastSize);
|
|
358
|
-
|
|
432
|
+
// Don't set rxSize for network errors (status 0)
|
|
433
|
+
if (size !== undefined && xhr.status !== 0) ctx.metrics.rxSize = size;
|
|
359
434
|
if (ctx.sameOrigin && xhr.getAllResponseHeaders().indexOf(NR_CAT_HEADER) >= 0) {
|
|
360
435
|
var header = xhr.getResponseHeader(NR_CAT_HEADER);
|
|
361
436
|
if (header) {
|
|
@@ -377,4 +452,17 @@ function addUrl(ctx, url) {
|
|
|
377
452
|
ctx.parsedOrigin = parsed;
|
|
378
453
|
ctx.sameOrigin = parsed.sameOrigin;
|
|
379
454
|
}
|
|
455
|
+
function parseResponseHeaders(headerStr) {
|
|
456
|
+
const headers = {};
|
|
457
|
+
if (!headerStr) return headers;
|
|
458
|
+
headerStr.split('\r\n').forEach(function (line) {
|
|
459
|
+
const separatorIndex = line.indexOf(': ');
|
|
460
|
+
if (separatorIndex > 0) {
|
|
461
|
+
const name = line.substring(0, separatorIndex);
|
|
462
|
+
const value = line.substring(separatorIndex + 2);
|
|
463
|
+
headers[name.toLowerCase()] = value;
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
return headers;
|
|
467
|
+
}
|
|
380
468
|
const Ajax = exports.Ajax = Instrument;
|
|
@@ -12,10 +12,11 @@ var _aggregateBase = require("../../utils/aggregate-base");
|
|
|
12
12
|
var _console = require("../../../common/util/console");
|
|
13
13
|
var _now = require("../../../common/timing/now");
|
|
14
14
|
var _registerHandler = require("../../../common/event-emitter/register-handler");
|
|
15
|
-
var
|
|
15
|
+
var _obfuscate = require("../../../common/util/obfuscate");
|
|
16
16
|
var _userActionsAggregator = require("./user-actions/user-actions-aggregator");
|
|
17
17
|
var _iframe = require("../../../common/dom/iframe");
|
|
18
18
|
var _typeCheck = require("../../../common/util/type-check");
|
|
19
|
+
var _events = require("../../../common/constants/events");
|
|
19
20
|
var _utils = require("../../../common/v2/utils");
|
|
20
21
|
/**
|
|
21
22
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
@@ -28,6 +29,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
28
29
|
constructor(agentRef) {
|
|
29
30
|
super(agentRef, _constants.FEATURE_NAME);
|
|
30
31
|
this.referrerUrl = _runtime.isBrowserScope && document.referrer ? (0, _cleanUrl.cleanURL)(document.referrer) : undefined;
|
|
32
|
+
|
|
33
|
+
// Create generic obfuscator (no specific event types) since this feature handles multiple event types
|
|
34
|
+
// Will check each event's eventType property at runtime against obfuscation rules
|
|
35
|
+
this.obfuscator = new _obfuscate.Obfuscator(agentRef);
|
|
31
36
|
this.waitForFlags(['ins']).then(([ins]) => {
|
|
32
37
|
if (!ins) {
|
|
33
38
|
this.blocked = true;
|
|
@@ -47,7 +52,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
47
52
|
(0, _registerHandler.registerHandler)('api-addPageAction', (timestamp, name, attributes, target) => {
|
|
48
53
|
this.addEvent({
|
|
49
54
|
...attributes,
|
|
50
|
-
eventType:
|
|
55
|
+
eventType: _events.EVENT_TYPES.PA,
|
|
51
56
|
timestamp: this.#toEpoch(timestamp),
|
|
52
57
|
timeSinceLoad: timestamp / 1000,
|
|
53
58
|
actionName: name,
|
|
@@ -75,7 +80,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
75
80
|
} = aggregatedUserAction.event;
|
|
76
81
|
aggregatedUserAction.targets.forEach(mfeTarget => {
|
|
77
82
|
const userActionEvent = {
|
|
78
|
-
eventType:
|
|
83
|
+
eventType: _events.EVENT_TYPES.UA,
|
|
79
84
|
timestamp: this.#toEpoch(timeStamp),
|
|
80
85
|
action: type,
|
|
81
86
|
actionCount: aggregatedUserAction.count,
|
|
@@ -162,7 +167,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
162
167
|
const detailObj = agentRef.init.performance.capture_detail ? createDetailAttrs(entry.detail) : {};
|
|
163
168
|
this.addEvent({
|
|
164
169
|
...detailObj,
|
|
165
|
-
eventType:
|
|
170
|
+
eventType: _events.EVENT_TYPES.BP,
|
|
166
171
|
timestamp: this.#toEpoch(entry.startTime),
|
|
167
172
|
entryName: entry.name,
|
|
168
173
|
entryDuration: entry.duration,
|
|
@@ -228,7 +233,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
228
233
|
this.reportSupportabilityMetric('Generic/Performance/Resource/Seen');
|
|
229
234
|
const event = {
|
|
230
235
|
...entryObject,
|
|
231
|
-
eventType:
|
|
236
|
+
eventType: _events.EVENT_TYPES.BP,
|
|
232
237
|
timestamp: this.#toEpoch(entryObject.startTime),
|
|
233
238
|
entryName: (0, _cleanUrl.cleanURL)(name),
|
|
234
239
|
entryDuration: duration,
|
|
@@ -248,7 +253,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
248
253
|
} = args;
|
|
249
254
|
const event = {
|
|
250
255
|
...customAttributes,
|
|
251
|
-
eventType:
|
|
256
|
+
eventType: _events.EVENT_TYPES.BP,
|
|
252
257
|
timestamp: this.#toEpoch(start),
|
|
253
258
|
entryName: n,
|
|
254
259
|
entryDuration: duration,
|
|
@@ -260,7 +265,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
260
265
|
(0, _registerHandler.registerHandler)('ws-complete', nrData => {
|
|
261
266
|
const event = {
|
|
262
267
|
...nrData,
|
|
263
|
-
eventType:
|
|
268
|
+
eventType: _events.EVENT_TYPES.WS,
|
|
264
269
|
timestamp: this.#toEpoch(nrData.timestamp),
|
|
265
270
|
openedAt: this.#toEpoch(nrData.openedAt),
|
|
266
271
|
closedAt: this.#toEpoch(nrData.closedAt)
|
|
@@ -275,7 +280,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
275
280
|
if (!agentRef.init.feature_flags.includes('no_spv')) {
|
|
276
281
|
(0, _registerHandler.registerHandler)('spv', evt => {
|
|
277
282
|
this.addEvent({
|
|
278
|
-
eventType:
|
|
283
|
+
eventType: _events.EVENT_TYPES.SPV,
|
|
279
284
|
timestamp: this.#toEpoch(evt.timeStamp),
|
|
280
285
|
blockedUri: evt.blockedURI,
|
|
281
286
|
documentUri: evt.documentURI,
|
|
@@ -344,9 +349,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
344
349
|
});
|
|
345
350
|
}
|
|
346
351
|
serializer(eventBuffer) {
|
|
347
|
-
return
|
|
352
|
+
return this.obfuscator.traverseAndObfuscateEvents({
|
|
348
353
|
ins: eventBuffer
|
|
349
|
-
}
|
|
354
|
+
});
|
|
350
355
|
}
|
|
351
356
|
queryStringsBuilder() {
|
|
352
357
|
return {
|
|
@@ -4,9 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.RESERVED_EVENT_TYPES = exports.RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_EVENTS = exports.OBSERVED_WINDOW_EVENTS = exports.OBSERVED_EVENTS = exports.FRUSTRATION_TIMEOUT_MS = exports.FEATURE_NAME = exports.FEATURE_FLAGS = void 0;
|
|
7
|
+
var _events = require("../../common/constants/events");
|
|
7
8
|
var _features = require("../../loaders/features/features");
|
|
8
9
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
10
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
11
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -16,7 +17,7 @@ const OBSERVED_WINDOW_EVENTS = exports.OBSERVED_WINDOW_EVENTS = ['focus', 'blur'
|
|
|
16
17
|
const RAGE_CLICK_THRESHOLD_EVENTS = exports.RAGE_CLICK_THRESHOLD_EVENTS = 4;
|
|
17
18
|
const RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_MS = 1000;
|
|
18
19
|
const FRUSTRATION_TIMEOUT_MS = exports.FRUSTRATION_TIMEOUT_MS = 2000;
|
|
19
|
-
const RESERVED_EVENT_TYPES = exports.RESERVED_EVENT_TYPES = [
|
|
20
|
+
const RESERVED_EVENT_TYPES = exports.RESERVED_EVENT_TYPES = [_events.EVENT_TYPES.PA, _events.EVENT_TYPES.UA, _events.EVENT_TYPES.BP];
|
|
20
21
|
const FEATURE_FLAGS = exports.FEATURE_FLAGS = {
|
|
21
22
|
RESOURCES: 'experimental.resources',
|
|
22
23
|
REGISTER: 'register'
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.formatStackTrace = formatStackTrace;
|
|
7
7
|
exports.truncateSize = truncateSize;
|
|
8
8
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ function formatStackTrace(stackLines) {
|
|
|
16
16
|
return truncateStackLines(stackLines).replace(stripNewlinesRegex, '');
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// takes array of stack lines and returns string with top 50 and
|
|
19
|
+
// takes array of stack lines and returns string with top 50 and bottom 50 lines
|
|
20
20
|
function truncateStackLines(stackLines) {
|
|
21
21
|
var stackString;
|
|
22
22
|
if (stackLines.length > 100) {
|
|
@@ -16,11 +16,12 @@ var _constants = require("../constants");
|
|
|
16
16
|
var _features = require("../../../loaders/features/features");
|
|
17
17
|
var _aggregateBase = require("../../utils/aggregate-base");
|
|
18
18
|
var _now = require("../../../common/timing/now");
|
|
19
|
-
var
|
|
19
|
+
var _obfuscate = require("../../../common/util/obfuscate");
|
|
20
20
|
var _internalErrors = require("./internal-errors");
|
|
21
21
|
var _utils = require("../../../common/v2/utils");
|
|
22
22
|
var _causeString = require("./cause-string");
|
|
23
23
|
var _shortCircuit = require("../../../common/util/short-circuit");
|
|
24
|
+
var _events = require("../../../common/constants/events");
|
|
24
25
|
/**
|
|
25
26
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
26
27
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -41,6 +42,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
41
42
|
this.observedAt = {};
|
|
42
43
|
this.pageviewReported = {};
|
|
43
44
|
this.errorOnPage = false;
|
|
45
|
+
|
|
46
|
+
// Create obfuscators for each event type this feature handles
|
|
47
|
+
this.errorObfuscator = new _obfuscate.Obfuscator(agentRef, _events.EVENT_TYPES.JSE);
|
|
48
|
+
this.xhrObfuscator = new _obfuscate.Obfuscator(agentRef, _events.EVENT_TYPES.AJAX);
|
|
44
49
|
(0, _registerHandler.registerHandler)('err', this.processError.bind(this), this.featureName, this.ee);
|
|
45
50
|
(0, _registerHandler.registerHandler)('ierr', this.processError.bind(this), this.featureName, this.ee);
|
|
46
51
|
(0, _registerHandler.registerHandler)('returnJserror', (jsErrorEvent, softNavAttrs) => this.#storeJserrorForHarvest(jsErrorEvent, softNavAttrs), this.featureName, this.ee);
|
|
@@ -56,7 +61,11 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
56
61
|
});
|
|
57
62
|
}
|
|
58
63
|
serializer(aggregatorTypeToBucketsMap) {
|
|
59
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
err: this.errorObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.err),
|
|
66
|
+
ierr: this.errorObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.ierr),
|
|
67
|
+
xhr: this.xhrObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.xhr)
|
|
68
|
+
};
|
|
60
69
|
}
|
|
61
70
|
queryStringsBuilder(aggregatorTakeReturnedData) {
|
|
62
71
|
const qs = {};
|
|
@@ -258,7 +267,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
258
267
|
params.stack_trace = (0, _formatStackTrace.truncateSize)(stackInfo.stackString);
|
|
259
268
|
this.observedAt[bucketHash] = Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(time));
|
|
260
269
|
} else {
|
|
261
|
-
params.browser_stack_hash = (0, _stringHashCode.stringHashCode)(stackInfo.stackString);
|
|
270
|
+
params.browser_stack_hash = (0, _stringHashCode.stringHashCode)((0, _formatStackTrace.truncateSize)(stackInfo.stackString));
|
|
262
271
|
}
|
|
263
272
|
params.releaseIds = (0, _stringify.stringify)(this.agentRef.runtime.releaseIds);
|
|
264
273
|
|