@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
|
@@ -14,7 +14,7 @@ import { parseUrl } from '../../../common/url/parse-url';
|
|
|
14
14
|
import { DT } from './distributed-tracing';
|
|
15
15
|
import { responseSizeFromXhr } from './response-size';
|
|
16
16
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
17
|
-
import { FEATURE_NAME } from '../constants';
|
|
17
|
+
import { CAPTURE_PAYLOAD_SETTINGS, FEATURE_NAME } from '../constants';
|
|
18
18
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
19
19
|
import { SUPPORTABILITY_METRIC } from '../../metrics/constants';
|
|
20
20
|
import { now } from '../../../common/timing/now';
|
|
@@ -25,6 +25,7 @@ var handlersLen = handlers.length;
|
|
|
25
25
|
var origRequest = gosNREUMOriginals().o.REQ;
|
|
26
26
|
var origXHR = gosNREUMOriginals().o.XHR;
|
|
27
27
|
const NR_CAT_HEADER = 'X-NewRelic-App-Data';
|
|
28
|
+
const INTERNAL_ERROR = 'internal-error';
|
|
28
29
|
export class Instrument extends InstrumentBase {
|
|
29
30
|
static featureName = FEATURE_NAME;
|
|
30
31
|
constructor(agentRef) {
|
|
@@ -70,10 +71,12 @@ export class Instrument extends InstrumentBase {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
74
|
+
const shouldInterceptPayloads = [CAPTURE_PAYLOAD_SETTINGS.ALL, CAPTURE_PAYLOAD_SETTINGS.FAILURES].includes(agentRef.init.ajax?.capture_payloads);
|
|
73
75
|
ee.on('new-xhr', onNewXhr);
|
|
74
76
|
ee.on('open-xhr-start', onOpenXhrStart);
|
|
75
77
|
ee.on('open-xhr-end', onOpenXhrEnd);
|
|
76
78
|
ee.on('send-xhr-start', onSendXhrStart);
|
|
79
|
+
ee.on('setRequestHeader-xhr-start', onSetRequestHeader);
|
|
77
80
|
ee.on('xhr-cb-time', onXhrCbTime);
|
|
78
81
|
ee.on('xhr-load-added', onXhrLoadAdded);
|
|
79
82
|
ee.on('xhr-load-removed', onXhrLoadRemoved);
|
|
@@ -145,6 +148,13 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
}
|
|
151
|
+
function onSetRequestHeader(args, xhr) {
|
|
152
|
+
// args[0] = header name, args[1] = header value
|
|
153
|
+
if (shouldInterceptPayloads && args.length >= 2) {
|
|
154
|
+
this.requestHeaders ??= {};
|
|
155
|
+
this.requestHeaders[args[0].toLowerCase()] = args[1];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
148
158
|
function onSendXhrStart(args, xhr) {
|
|
149
159
|
var metrics = this.metrics;
|
|
150
160
|
var data = args[0];
|
|
@@ -154,7 +164,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
154
164
|
if (size) metrics.txSize = size;
|
|
155
165
|
}
|
|
156
166
|
this.startTime = now();
|
|
157
|
-
this.
|
|
167
|
+
this.requestBody = data;
|
|
158
168
|
this.listener = function (evt) {
|
|
159
169
|
try {
|
|
160
170
|
if (evt.type === 'abort' && !context.loadCaptureCalled) {
|
|
@@ -163,7 +173,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
163
173
|
if (evt.type !== 'load' || context.called === context.totalCbs && (context.onloadCalled || typeof xhr.onload !== 'function') && typeof context.end === 'function') context.end(xhr);
|
|
164
174
|
} catch (e) {
|
|
165
175
|
try {
|
|
166
|
-
ee.emit(
|
|
176
|
+
ee.emit(INTERNAL_ERROR, [e]);
|
|
167
177
|
} catch (err) {
|
|
168
178
|
// do nothing
|
|
169
179
|
}
|
|
@@ -291,8 +301,27 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
291
301
|
addUrl(this, extractUrl(target));
|
|
292
302
|
const method = ('' + (target && target instanceof origRequest && target.method || opts.method || 'GET')).toUpperCase();
|
|
293
303
|
this.params.method = method;
|
|
294
|
-
this.
|
|
295
|
-
|
|
304
|
+
this.txSize = dataSize(opts.body || target?.body) || 0;
|
|
305
|
+
|
|
306
|
+
// Capture request headers
|
|
307
|
+
try {
|
|
308
|
+
var headers = opts.headers || target?.headers;
|
|
309
|
+
if (shouldInterceptPayloads && headers) {
|
|
310
|
+
this.requestHeaders ??= {};
|
|
311
|
+
if (headers instanceof Headers) {
|
|
312
|
+
headers.forEach(function (value, key) {
|
|
313
|
+
this.requestHeaders[key.toLowerCase()] = value;
|
|
314
|
+
}.bind(this));
|
|
315
|
+
} else if (typeof headers === 'object') {
|
|
316
|
+
for (var key in headers) {
|
|
317
|
+
this.requestHeaders[key.toLowerCase()] = headers[key];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
} catch (e) {
|
|
322
|
+
// Silently fail if we can't access headers
|
|
323
|
+
}
|
|
324
|
+
this.requestBody = opts.body || target?.body;
|
|
296
325
|
}
|
|
297
326
|
|
|
298
327
|
// we capture failed call as status 0, the actual error is ignored
|
|
@@ -303,19 +332,45 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
303
332
|
if (hasUndefinedHostname(this.params)) return; // don't bother with fetch to url with no hostname
|
|
304
333
|
|
|
305
334
|
this.params.status = res ? res.status : 0;
|
|
335
|
+
const finishAndReport = () => {
|
|
336
|
+
// convert rxSize to a number - handle both string (from content-length header) and number (from fallback)
|
|
337
|
+
const num = +this.rxSize;
|
|
338
|
+
const responseSize = this.rxSize != null && !isNaN(num) ? num : undefined;
|
|
339
|
+
const metrics = {
|
|
340
|
+
txSize: this.txSize,
|
|
341
|
+
rxSize: responseSize,
|
|
342
|
+
duration: this.endTime - this.startTime
|
|
343
|
+
};
|
|
344
|
+
const payload = [this.params, metrics, this.startTime, this.endTime, 'fetch'];
|
|
345
|
+
this.targets.forEach(target => reportToAgg(payload, this, target));
|
|
346
|
+
};
|
|
306
347
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (
|
|
310
|
-
|
|
348
|
+
/** Since accessing fetch bodies is an async process, these are
|
|
349
|
+
* reasonable conditions to check to not do needless extra work */
|
|
350
|
+
if (!res || !shouldInterceptPayloads) {
|
|
351
|
+
finishAndReport();
|
|
352
|
+
return;
|
|
311
353
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
354
|
+
|
|
355
|
+
// Clone the response to read the body without consuming the original
|
|
356
|
+
res.clone().text().then(text => {
|
|
357
|
+
this.responseBody = text;
|
|
358
|
+
// Use captured payload size as fallback if content-length header was missing or is 0 with a body
|
|
359
|
+
// Only apply fallback for non-network-error responses (status !== 0)
|
|
360
|
+
if ((!this.rxSize || this.rxSize === '0' || this.rxSize === 0) && text !== undefined && this.params.status !== 0) {
|
|
361
|
+
this.rxSize = dataSize(text);
|
|
362
|
+
}
|
|
363
|
+
if (res?.headers) {
|
|
364
|
+
this.responseHeaders = {};
|
|
365
|
+
res.headers.forEach(function (value, key) {
|
|
366
|
+
this.responseHeaders[key.toLowerCase()] = value;
|
|
367
|
+
}.bind(this));
|
|
368
|
+
}
|
|
369
|
+
}).catch(err => {
|
|
370
|
+
ee.emit(INTERNAL_ERROR, [err]);
|
|
371
|
+
}).finally(() => {
|
|
372
|
+
finishAndReport();
|
|
373
|
+
});
|
|
319
374
|
}
|
|
320
375
|
|
|
321
376
|
// Create report for XHR request that has finished
|
|
@@ -330,7 +385,7 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
330
385
|
if (params.aborted) return;
|
|
331
386
|
if (hasUndefinedHostname(params)) return; // don't bother with XHR of url with no hostname
|
|
332
387
|
|
|
333
|
-
metrics.duration =
|
|
388
|
+
metrics.duration = this.endTime - this.startTime;
|
|
334
389
|
if (!this.loadCaptureCalled && xhr.readyState === 4) {
|
|
335
390
|
captureXhrData(this, xhr);
|
|
336
391
|
} else if (params.status == null) {
|
|
@@ -339,6 +394,25 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
339
394
|
|
|
340
395
|
// Always send cbTime, even if no noticeable time was taken.
|
|
341
396
|
metrics.cbTime = this.cbTime;
|
|
397
|
+
if (shouldInterceptPayloads) {
|
|
398
|
+
try {
|
|
399
|
+
this.responseBody = xhr.responseText;
|
|
400
|
+
} catch (e) {
|
|
401
|
+
this.responseBody = xhr.response;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Use captured payload size as fallback if not already determined or is 0 with a body
|
|
405
|
+
// Only apply fallback for non-network-error responses (status !== 0)
|
|
406
|
+
if ((!metrics.rxSize || metrics.rxSize === 0) && this.responseBody !== undefined && params.status !== 0) {
|
|
407
|
+
const size = dataSize(this.responseBody);
|
|
408
|
+
if (size !== undefined) metrics.rxSize = size;
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
this.responseHeaders = parseResponseHeaders(xhr.getAllResponseHeaders());
|
|
412
|
+
} catch (err) {
|
|
413
|
+
ee.emit(INTERNAL_ERROR, [err]);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
342
416
|
const payload = [params, metrics, this.startTime, this.endTime, 'xhr'];
|
|
343
417
|
this.targets.forEach(target => reportToAgg(payload, this, target));
|
|
344
418
|
}
|
|
@@ -348,7 +422,8 @@ function subscribeToEvents(agentRef, ee, handler, dt) {
|
|
|
348
422
|
function captureXhrData(ctx, xhr) {
|
|
349
423
|
ctx.params.status = xhr.status;
|
|
350
424
|
var size = responseSizeFromXhr(xhr, ctx.lastSize);
|
|
351
|
-
|
|
425
|
+
// Don't set rxSize for network errors (status 0)
|
|
426
|
+
if (size !== undefined && xhr.status !== 0) ctx.metrics.rxSize = size;
|
|
352
427
|
if (ctx.sameOrigin && xhr.getAllResponseHeaders().indexOf(NR_CAT_HEADER) >= 0) {
|
|
353
428
|
var header = xhr.getResponseHeader(NR_CAT_HEADER);
|
|
354
429
|
if (header) {
|
|
@@ -370,4 +445,17 @@ function addUrl(ctx, url) {
|
|
|
370
445
|
ctx.parsedOrigin = parsed;
|
|
371
446
|
ctx.sameOrigin = parsed.sameOrigin;
|
|
372
447
|
}
|
|
448
|
+
function parseResponseHeaders(headerStr) {
|
|
449
|
+
const headers = {};
|
|
450
|
+
if (!headerStr) return headers;
|
|
451
|
+
headerStr.split('\r\n').forEach(function (line) {
|
|
452
|
+
const separatorIndex = line.indexOf(': ');
|
|
453
|
+
if (separatorIndex > 0) {
|
|
454
|
+
const name = line.substring(0, separatorIndex);
|
|
455
|
+
const value = line.substring(separatorIndex + 2);
|
|
456
|
+
headers[name.toLowerCase()] = value;
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
return headers;
|
|
460
|
+
}
|
|
373
461
|
export const Ajax = Instrument;
|
|
@@ -10,10 +10,11 @@ import { AggregateBase } from '../../utils/aggregate-base';
|
|
|
10
10
|
import { warn } from '../../../common/util/console';
|
|
11
11
|
import { now } from '../../../common/timing/now';
|
|
12
12
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
13
|
-
import {
|
|
13
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
14
14
|
import { UserActionsAggregator } from './user-actions/user-actions-aggregator';
|
|
15
15
|
import { isIFrameWindow } from '../../../common/dom/iframe';
|
|
16
16
|
import { isPureObject } from '../../../common/util/type-check';
|
|
17
|
+
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
17
18
|
import { getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate } from '../../../common/v2/utils';
|
|
18
19
|
export class Aggregate extends AggregateBase {
|
|
19
20
|
static featureName = FEATURE_NAME;
|
|
@@ -21,6 +22,10 @@ export class Aggregate extends AggregateBase {
|
|
|
21
22
|
constructor(agentRef) {
|
|
22
23
|
super(agentRef, FEATURE_NAME);
|
|
23
24
|
this.referrerUrl = isBrowserScope && document.referrer ? cleanURL(document.referrer) : undefined;
|
|
25
|
+
|
|
26
|
+
// Create generic obfuscator (no specific event types) since this feature handles multiple event types
|
|
27
|
+
// Will check each event's eventType property at runtime against obfuscation rules
|
|
28
|
+
this.obfuscator = new Obfuscator(agentRef);
|
|
24
29
|
this.waitForFlags(['ins']).then(([ins]) => {
|
|
25
30
|
if (!ins) {
|
|
26
31
|
this.blocked = true;
|
|
@@ -40,7 +45,7 @@ export class Aggregate extends AggregateBase {
|
|
|
40
45
|
registerHandler('api-addPageAction', (timestamp, name, attributes, target) => {
|
|
41
46
|
this.addEvent({
|
|
42
47
|
...attributes,
|
|
43
|
-
eventType:
|
|
48
|
+
eventType: EVENT_TYPES.PA,
|
|
44
49
|
timestamp: this.#toEpoch(timestamp),
|
|
45
50
|
timeSinceLoad: timestamp / 1000,
|
|
46
51
|
actionName: name,
|
|
@@ -68,7 +73,7 @@ export class Aggregate extends AggregateBase {
|
|
|
68
73
|
} = aggregatedUserAction.event;
|
|
69
74
|
aggregatedUserAction.targets.forEach(mfeTarget => {
|
|
70
75
|
const userActionEvent = {
|
|
71
|
-
eventType:
|
|
76
|
+
eventType: EVENT_TYPES.UA,
|
|
72
77
|
timestamp: this.#toEpoch(timeStamp),
|
|
73
78
|
action: type,
|
|
74
79
|
actionCount: aggregatedUserAction.count,
|
|
@@ -155,7 +160,7 @@ export class Aggregate extends AggregateBase {
|
|
|
155
160
|
const detailObj = agentRef.init.performance.capture_detail ? createDetailAttrs(entry.detail) : {};
|
|
156
161
|
this.addEvent({
|
|
157
162
|
...detailObj,
|
|
158
|
-
eventType:
|
|
163
|
+
eventType: EVENT_TYPES.BP,
|
|
159
164
|
timestamp: this.#toEpoch(entry.startTime),
|
|
160
165
|
entryName: entry.name,
|
|
161
166
|
entryDuration: entry.duration,
|
|
@@ -221,7 +226,7 @@ export class Aggregate extends AggregateBase {
|
|
|
221
226
|
this.reportSupportabilityMetric('Generic/Performance/Resource/Seen');
|
|
222
227
|
const event = {
|
|
223
228
|
...entryObject,
|
|
224
|
-
eventType:
|
|
229
|
+
eventType: EVENT_TYPES.BP,
|
|
225
230
|
timestamp: this.#toEpoch(entryObject.startTime),
|
|
226
231
|
entryName: cleanURL(name),
|
|
227
232
|
entryDuration: duration,
|
|
@@ -241,7 +246,7 @@ export class Aggregate extends AggregateBase {
|
|
|
241
246
|
} = args;
|
|
242
247
|
const event = {
|
|
243
248
|
...customAttributes,
|
|
244
|
-
eventType:
|
|
249
|
+
eventType: EVENT_TYPES.BP,
|
|
245
250
|
timestamp: this.#toEpoch(start),
|
|
246
251
|
entryName: n,
|
|
247
252
|
entryDuration: duration,
|
|
@@ -253,7 +258,7 @@ export class Aggregate extends AggregateBase {
|
|
|
253
258
|
registerHandler('ws-complete', nrData => {
|
|
254
259
|
const event = {
|
|
255
260
|
...nrData,
|
|
256
|
-
eventType:
|
|
261
|
+
eventType: EVENT_TYPES.WS,
|
|
257
262
|
timestamp: this.#toEpoch(nrData.timestamp),
|
|
258
263
|
openedAt: this.#toEpoch(nrData.openedAt),
|
|
259
264
|
closedAt: this.#toEpoch(nrData.closedAt)
|
|
@@ -268,7 +273,7 @@ export class Aggregate extends AggregateBase {
|
|
|
268
273
|
if (!agentRef.init.feature_flags.includes('no_spv')) {
|
|
269
274
|
registerHandler('spv', evt => {
|
|
270
275
|
this.addEvent({
|
|
271
|
-
eventType:
|
|
276
|
+
eventType: EVENT_TYPES.SPV,
|
|
272
277
|
timestamp: this.#toEpoch(evt.timeStamp),
|
|
273
278
|
blockedUri: evt.blockedURI,
|
|
274
279
|
documentUri: evt.documentURI,
|
|
@@ -337,9 +342,9 @@ export class Aggregate extends AggregateBase {
|
|
|
337
342
|
});
|
|
338
343
|
}
|
|
339
344
|
serializer(eventBuffer) {
|
|
340
|
-
return
|
|
345
|
+
return this.obfuscator.traverseAndObfuscateEvents({
|
|
341
346
|
ins: eventBuffer
|
|
342
|
-
}
|
|
347
|
+
});
|
|
343
348
|
}
|
|
344
349
|
queryStringsBuilder() {
|
|
345
350
|
return {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
+
import { EVENT_TYPES } from '../../common/constants/events';
|
|
5
6
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
6
7
|
export const FEATURE_NAME = FEATURE_NAMES.genericEvents;
|
|
7
8
|
export const OBSERVED_EVENTS = ['auxclick', 'click', 'copy', 'keydown', 'paste', 'scrollend'];
|
|
@@ -9,7 +10,7 @@ export const OBSERVED_WINDOW_EVENTS = ['focus', 'blur'];
|
|
|
9
10
|
export const RAGE_CLICK_THRESHOLD_EVENTS = 4;
|
|
10
11
|
export const RAGE_CLICK_THRESHOLD_MS = 1000;
|
|
11
12
|
export const FRUSTRATION_TIMEOUT_MS = 2000;
|
|
12
|
-
export const RESERVED_EVENT_TYPES = [
|
|
13
|
+
export const RESERVED_EVENT_TYPES = [EVENT_TYPES.PA, EVENT_TYPES.UA, EVENT_TYPES.BP];
|
|
13
14
|
export const FEATURE_FLAGS = {
|
|
14
15
|
RESOURCES: 'experimental.resources',
|
|
15
16
|
REGISTER: 'register'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ export function formatStackTrace(stackLines) {
|
|
|
9
9
|
return truncateStackLines(stackLines).replace(stripNewlinesRegex, '');
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
// takes array of stack lines and returns string with top 50 and
|
|
12
|
+
// takes array of stack lines and returns string with top 50 and bottom 50 lines
|
|
13
13
|
function truncateStackLines(stackLines) {
|
|
14
14
|
var stackString;
|
|
15
15
|
if (stackLines.length > 100) {
|
|
@@ -15,11 +15,12 @@ import { FEATURE_NAME } from '../constants';
|
|
|
15
15
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
16
16
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
17
17
|
import { now } from '../../../common/timing/now';
|
|
18
|
-
import {
|
|
18
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
19
19
|
import { evaluateInternalError } from './internal-errors';
|
|
20
20
|
import { getRegisteredTargetsFromFilename, getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate } from '../../../common/v2/utils';
|
|
21
21
|
import { buildCauseString } from './cause-string';
|
|
22
22
|
import { ShortCircuit } from '../../../common/util/short-circuit';
|
|
23
|
+
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* @typedef {import('./compute-stack-trace.js').StackInfo} StackInfo
|
|
@@ -36,6 +37,10 @@ export class Aggregate extends AggregateBase {
|
|
|
36
37
|
this.observedAt = {};
|
|
37
38
|
this.pageviewReported = {};
|
|
38
39
|
this.errorOnPage = false;
|
|
40
|
+
|
|
41
|
+
// Create obfuscators for each event type this feature handles
|
|
42
|
+
this.errorObfuscator = new Obfuscator(agentRef, EVENT_TYPES.JSE);
|
|
43
|
+
this.xhrObfuscator = new Obfuscator(agentRef, EVENT_TYPES.AJAX);
|
|
39
44
|
register('err', this.processError.bind(this), this.featureName, this.ee);
|
|
40
45
|
register('ierr', this.processError.bind(this), this.featureName, this.ee);
|
|
41
46
|
register('returnJserror', (jsErrorEvent, softNavAttrs) => this.#storeJserrorForHarvest(jsErrorEvent, softNavAttrs), this.featureName, this.ee);
|
|
@@ -51,7 +56,11 @@ export class Aggregate extends AggregateBase {
|
|
|
51
56
|
});
|
|
52
57
|
}
|
|
53
58
|
serializer(aggregatorTypeToBucketsMap) {
|
|
54
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
err: this.errorObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.err),
|
|
61
|
+
ierr: this.errorObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.ierr),
|
|
62
|
+
xhr: this.xhrObfuscator.traverseAndObfuscateEvents(aggregatorTypeToBucketsMap.xhr)
|
|
63
|
+
};
|
|
55
64
|
}
|
|
56
65
|
queryStringsBuilder(aggregatorTakeReturnedData) {
|
|
57
66
|
const qs = {};
|
|
@@ -253,7 +262,7 @@ export class Aggregate extends AggregateBase {
|
|
|
253
262
|
params.stack_trace = truncateSize(stackInfo.stackString);
|
|
254
263
|
this.observedAt[bucketHash] = Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(time));
|
|
255
264
|
} else {
|
|
256
|
-
params.browser_stack_hash = stringHashCode(stackInfo.stackString);
|
|
265
|
+
params.browser_stack_hash = stringHashCode(truncateSize(stackInfo.stackString));
|
|
257
266
|
}
|
|
258
267
|
params.releaseIds = stringify(this.agentRef.runtime.releaseIds);
|
|
259
268
|
|
|
@@ -9,11 +9,12 @@ import { AggregateBase } from '../../utils/aggregate-base';
|
|
|
9
9
|
import { FEATURE_NAME, LOGGING_EVENT_EMITTER_CHANNEL, LOG_LEVELS, LOGGING_MODE } from '../constants';
|
|
10
10
|
import { Log } from '../shared/log';
|
|
11
11
|
import { isValidLogLevel } from '../shared/utils';
|
|
12
|
-
import {
|
|
12
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
13
13
|
import { SESSION_EVENT_TYPES, SESSION_EVENTS } from '../../../common/session/constants';
|
|
14
14
|
import { ABORT_REASONS } from '../../session_replay/constants';
|
|
15
15
|
import { canEnableSessionTracking } from '../../utils/feature-gates';
|
|
16
16
|
import { getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate } from '../../../common/v2/utils';
|
|
17
|
+
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
17
18
|
const LOGGING_EVENT = 'Logging/Event/';
|
|
18
19
|
export class Aggregate extends AggregateBase {
|
|
19
20
|
static featureName = FEATURE_NAME;
|
|
@@ -32,6 +33,9 @@ export class Aggregate extends AggregateBase {
|
|
|
32
33
|
this.harvestOpts.raw = true;
|
|
33
34
|
super.customAttributesAreSeparate = true;
|
|
34
35
|
|
|
36
|
+
// Create obfuscator for log entries
|
|
37
|
+
this.obfuscator = new Obfuscator(agentRef, EVENT_TYPES.LOG);
|
|
38
|
+
|
|
35
39
|
// The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
|
|
36
40
|
this.ee.on(SESSION_EVENTS.RESET, () => {
|
|
37
41
|
this.abort(ABORT_REASONS.RESET);
|
|
@@ -50,7 +54,7 @@ export class Aggregate extends AggregateBase {
|
|
|
50
54
|
}; // likewise, don't want to overwrite the mode if it was set already
|
|
51
55
|
const session = this.agentRef.runtime.session;
|
|
52
56
|
if (canEnableSessionTracking(agentRef.init) && session) {
|
|
53
|
-
if (session.
|
|
57
|
+
if (session.state.loggingMode === null || session.state.logApiMode === null) this.#writeToStorage(this.loggingMode);else updateLocalLoggingMode(session.state.loggingMode, session.state.logApiMode);
|
|
54
58
|
}
|
|
55
59
|
if (this.loggingMode.auto === LOGGING_MODE.OFF && this.loggingMode.api === LOGGING_MODE.OFF) {
|
|
56
60
|
this.blocked = true;
|
|
@@ -112,7 +116,7 @@ export class Aggregate extends AggregateBase {
|
|
|
112
116
|
common: {
|
|
113
117
|
/** Attributes in the `common` section are added to `all` logs generated in the payload */
|
|
114
118
|
attributes: {
|
|
115
|
-
...
|
|
119
|
+
...this.obfuscator.traverseAndObfuscateEvents(this.agentRef.info.jsAttributes),
|
|
116
120
|
...(this.harvestEndpointVersion === 1 && {
|
|
117
121
|
'entity.guid': this.agentRef.runtime.appMetadata.agents[0].entityGuid,
|
|
118
122
|
appId: this.agentRef.info.applicationID
|
|
@@ -137,7 +141,7 @@ export class Aggregate extends AggregateBase {
|
|
|
137
141
|
}
|
|
138
142
|
},
|
|
139
143
|
/** logs section contains individual unique log entries */
|
|
140
|
-
logs:
|
|
144
|
+
logs: this.obfuscator.traverseAndObfuscateEvents(eventBuffer)
|
|
141
145
|
}];
|
|
142
146
|
}
|
|
143
147
|
queryStringsBuilder() {
|
|
@@ -158,13 +162,13 @@ export class Aggregate extends AggregateBase {
|
|
|
158
162
|
auto: LOGGING_MODE.OFF,
|
|
159
163
|
api: LOGGING_MODE.OFF
|
|
160
164
|
};
|
|
161
|
-
this.#
|
|
165
|
+
this.#writeToStorage(this.loggingMode);
|
|
162
166
|
this.deregisterDrain();
|
|
163
167
|
}
|
|
164
|
-
#
|
|
168
|
+
#writeToStorage(logModes) {
|
|
165
169
|
this.agentRef.runtime.session?.write({
|
|
166
|
-
loggingMode:
|
|
167
|
-
logApiMode:
|
|
170
|
+
loggingMode: logModes.auto,
|
|
171
|
+
logApiMode: logModes.api
|
|
168
172
|
});
|
|
169
173
|
}
|
|
170
174
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
@@ -12,6 +12,7 @@ import { isBrowserScope, isWorkerScope } from '../../../common/constants/runtime
|
|
|
12
12
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
13
13
|
import { isIFrameWindow } from '../../../common/dom/iframe';
|
|
14
14
|
import { evaluateHarvestMetadata } from './harvest-metadata';
|
|
15
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
15
16
|
// import { WEBSOCKET_TAG } from '../../../common/wrap/wrap-websocket'
|
|
16
17
|
// import { handleWebsocketEvents } from './websocket-detection'
|
|
17
18
|
|
|
@@ -21,6 +22,9 @@ export class Aggregate extends AggregateBase {
|
|
|
21
22
|
super(agentRef, FEATURE_NAME);
|
|
22
23
|
this.harvestOpts.aggregatorTypes = ['cm', 'sm']; // the types in EventAggregator this feature cares about
|
|
23
24
|
|
|
25
|
+
// Create a generic obfuscator for checking if rules are configured
|
|
26
|
+
this.obfuscator = new Obfuscator(agentRef);
|
|
27
|
+
|
|
24
28
|
/** all the harvest metadata metrics need to be evaluated simulataneously at unload time so just temporarily buffer them and dont make SMs immediately from the data */
|
|
25
29
|
this.harvestMetadata = {};
|
|
26
30
|
this.harvestOpts.beforeUnload = () => {
|
|
@@ -15,23 +15,42 @@ import { firstPaint } from '../../../common/vitals/first-paint';
|
|
|
15
15
|
import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte';
|
|
16
16
|
import { now } from '../../../common/timing/now';
|
|
17
17
|
import { TimeKeeper } from '../../../common/timing/time-keeper';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { send } from '../../../common/harvest/send';
|
|
19
|
+
import { canEnableSessionTracking } from '../../utils/feature-gates';
|
|
20
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
20
21
|
import { FEATURE_NAMES, FEATURE_TO_ENDPOINT } from '../../../loaders/features/features';
|
|
21
22
|
import { getSubmitMethod } from '../../../common/util/submit-data';
|
|
22
23
|
import { webdriverDetected } from '../../../common/util/webdriver-detection';
|
|
24
|
+
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
23
25
|
export class Aggregate extends AggregateBase {
|
|
24
26
|
static featureName = CONSTANTS.FEATURE_NAME;
|
|
25
27
|
constructor(agentRef) {
|
|
26
28
|
super(agentRef, CONSTANTS.FEATURE_NAME);
|
|
29
|
+
this.isSessionTrackingEnabled = canEnableSessionTracking(agentRef.init) && !!agentRef.runtime.session;
|
|
27
30
|
this.sentRum = false; // flag to facilitate calling sendRum() once externally (by the consent API in agent-session.js)
|
|
28
31
|
|
|
29
32
|
this.timeToFirstByte = 0;
|
|
30
33
|
this.firstByteToWindowLoad = 0; // our "frontend" duration
|
|
31
34
|
this.firstByteToDomContent = 0; // our "dom processing" duration
|
|
32
35
|
this.retries = 0;
|
|
36
|
+
|
|
37
|
+
// Create obfuscator for page view events
|
|
38
|
+
this.obfuscator = new Obfuscator(agentRef, EVENT_TYPES.PVE);
|
|
33
39
|
agentRef.runtime.timeKeeper = new TimeKeeper(agentRef.runtime.session);
|
|
34
40
|
if (isBrowserScope) {
|
|
41
|
+
const cached = this.isSessionTrackingEnabled && agentRef.runtime.session?.state.cachedRumResponse;
|
|
42
|
+
if (cached) {
|
|
43
|
+
const {
|
|
44
|
+
app: cachedApp,
|
|
45
|
+
...cachedFlags
|
|
46
|
+
} = cached;
|
|
47
|
+
|
|
48
|
+
// set the agent runtime objects that require the rum response or entity guid
|
|
49
|
+
if (!Object.keys(this.agentRef.runtime.appMetadata).length) agentRef.runtime.appMetadata = cachedApp;
|
|
50
|
+
this.drain();
|
|
51
|
+
agentRef.runtime.harvester.startTimer();
|
|
52
|
+
activateFeatures(cachedFlags, agentRef);
|
|
53
|
+
}
|
|
35
54
|
timeToFirstByte.subscribe(({
|
|
36
55
|
value,
|
|
37
56
|
attrs
|
|
@@ -76,14 +95,13 @@ export class Aggregate extends AggregateBase {
|
|
|
76
95
|
ua: info.userAttributes,
|
|
77
96
|
at: info.atts
|
|
78
97
|
};
|
|
79
|
-
if (this.agentRef.runtime.session) queryParameters.fsh = Number(this.agentRef.runtime.session.
|
|
80
|
-
|
|
81
|
-
let body = applyFnToProps({
|
|
98
|
+
if (this.agentRef.runtime.session) queryParameters.fsh = Number(!this.agentRef.runtime.session.state.cachedRumResponse);
|
|
99
|
+
let body = this.obfuscator.traverseAndObfuscateEvents({
|
|
82
100
|
ja: {
|
|
83
101
|
...customAttributes,
|
|
84
102
|
webdriverDetected
|
|
85
103
|
}
|
|
86
|
-
}
|
|
104
|
+
});
|
|
87
105
|
if (globalScope.performance) {
|
|
88
106
|
const navTimingEntry = getNavigationEntry();
|
|
89
107
|
if (navTimingEntry) {
|
|
@@ -131,6 +149,7 @@ export class Aggregate extends AggregateBase {
|
|
|
131
149
|
}) {
|
|
132
150
|
const rumEndTime = now();
|
|
133
151
|
let app, flags;
|
|
152
|
+
const hasCachedRumResponse = !!this.agentRef.runtime.session?.state.cachedRumResponse;
|
|
134
153
|
try {
|
|
135
154
|
({
|
|
136
155
|
app,
|
|
@@ -140,10 +159,20 @@ export class Aggregate extends AggregateBase {
|
|
|
140
159
|
// wont set entity stuff here, if main agent will later abort, if registered agent, nothing will happen
|
|
141
160
|
warn(53, error);
|
|
142
161
|
}
|
|
162
|
+
const shouldCacheResponse = this.isSessionTrackingEnabled && !hasCachedRumResponse && !!app;
|
|
163
|
+
if (hasCachedRumResponse) {
|
|
164
|
+
let {
|
|
165
|
+
app: cachedApp,
|
|
166
|
+
...cachedFlags
|
|
167
|
+
} = this.agentRef.runtime.session.state.cachedRumResponse;
|
|
168
|
+
app ??= cachedApp;
|
|
169
|
+
flags = cachedFlags;
|
|
170
|
+
}
|
|
143
171
|
super.postHarvestCleanup({
|
|
144
172
|
sent,
|
|
145
|
-
retry
|
|
173
|
+
retry: retry && !hasCachedRumResponse
|
|
146
174
|
}); // this will set isRetrying & re-buffer the body if request is to be retried
|
|
175
|
+
|
|
147
176
|
if (this.isRetrying && this.retries++ < 1) {
|
|
148
177
|
// Only retry once
|
|
149
178
|
setTimeout(() => this.agentRef.runtime.harvester.triggerHarvestFor(this, {
|
|
@@ -153,7 +182,6 @@ export class Aggregate extends AggregateBase {
|
|
|
153
182
|
}
|
|
154
183
|
if (status >= 400 || status === 0) {
|
|
155
184
|
warn(18, status);
|
|
156
|
-
this.blocked = true;
|
|
157
185
|
|
|
158
186
|
// Get estimated payload size of our backlog
|
|
159
187
|
const textEncoder = new TextEncoder();
|
|
@@ -164,15 +192,24 @@ export class Aggregate extends AggregateBase {
|
|
|
164
192
|
}, 0);
|
|
165
193
|
const BCSError = 'BCS/Error/';
|
|
166
194
|
// Send SMs about failed RUM request
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
195
|
+
const sm = [{
|
|
196
|
+
params: {
|
|
197
|
+
name: BCSError + status
|
|
198
|
+
},
|
|
199
|
+
stats: {
|
|
200
|
+
c: 1
|
|
201
|
+
}
|
|
202
|
+
}, {
|
|
203
|
+
params: {
|
|
204
|
+
name: BCSError + 'Duration/Ms'
|
|
205
|
+
},
|
|
206
|
+
stats: {
|
|
207
|
+
c: 1,
|
|
208
|
+
t: rumEndTime - this.rumStartTime
|
|
209
|
+
}
|
|
210
|
+
}];
|
|
211
|
+
if (!hasCachedRumResponse) {
|
|
212
|
+
sm.push({
|
|
176
213
|
params: {
|
|
177
214
|
name: BCSError + 'Dropped/Bytes'
|
|
178
215
|
},
|
|
@@ -180,28 +217,30 @@ export class Aggregate extends AggregateBase {
|
|
|
180
217
|
c: 1,
|
|
181
218
|
t: payloadSize
|
|
182
219
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
name: BCSError + 'Duration/Ms'
|
|
186
|
-
},
|
|
187
|
-
stats: {
|
|
188
|
-
c: 1,
|
|
189
|
-
t: rumEndTime - this.rumStartTime
|
|
190
|
-
}
|
|
191
|
-
}]
|
|
192
|
-
};
|
|
220
|
+
});
|
|
221
|
+
}
|
|
193
222
|
send(this.agentRef, {
|
|
194
223
|
endpoint: FEATURE_TO_ENDPOINT[FEATURE_NAMES.metrics],
|
|
195
224
|
payload: {
|
|
196
|
-
body
|
|
225
|
+
body: {
|
|
226
|
+
sm
|
|
227
|
+
}
|
|
197
228
|
},
|
|
198
229
|
submitMethod: getSubmitMethod(),
|
|
199
230
|
featureName: FEATURE_NAMES.metrics
|
|
200
231
|
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
232
|
+
if (!hasCachedRumResponse) {
|
|
233
|
+
this.blocked = true;
|
|
234
|
+
this.ee.abort();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
} else if (shouldCacheResponse) {
|
|
238
|
+
this.agentRef.runtime.session.write({
|
|
239
|
+
cachedRumResponse: {
|
|
240
|
+
app,
|
|
241
|
+
...flags
|
|
242
|
+
}
|
|
243
|
+
});
|
|
205
244
|
}
|
|
206
245
|
try {
|
|
207
246
|
const wasReady = this.agentRef.runtime.timeKeeper.ready;
|