@newrelic/browser-agent 1.285.0 → 1.287.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +6 -0
- package/dist/cjs/common/config/init-types.js +96 -0
- package/dist/cjs/common/config/init.js +9 -79
- package/dist/cjs/common/config/runtime.js +7 -6
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/dom/selector-path.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +3 -3
- package/dist/cjs/common/util/feature-flags.js +6 -6
- package/dist/cjs/common/util/target.js +34 -0
- package/dist/cjs/features/ajax/aggregate/index.js +2 -1
- package/dist/cjs/features/generic_events/aggregate/index.js +10 -6
- package/dist/cjs/features/jserrors/aggregate/index.js +44 -22
- package/dist/cjs/features/logging/aggregate/index.js +17 -11
- package/dist/cjs/features/logging/shared/utils.js +3 -2
- package/dist/cjs/features/metrics/aggregate/index.js +6 -4
- package/dist/cjs/features/page_view_event/aggregate/index.js +60 -11
- package/dist/cjs/features/page_view_event/instrument/index.js +4 -0
- package/dist/cjs/features/session_replay/aggregate/index.js +8 -6
- package/dist/cjs/features/session_replay/instrument/index.js +1 -1
- package/dist/cjs/features/session_replay/shared/recorder-events.js +4 -2
- package/dist/cjs/features/session_replay/shared/recorder.js +17 -11
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +4 -3
- package/dist/cjs/features/soft_navigations/aggregate/index.js +12 -2
- package/dist/cjs/features/spa/aggregate/index.js +3 -3
- package/dist/cjs/features/spa/aggregate/interaction.js +6 -9
- package/dist/cjs/features/utils/aggregate-base.js +51 -24
- package/dist/cjs/features/utils/entity-manager.js +47 -0
- package/dist/cjs/features/utils/event-store-manager.js +79 -54
- package/dist/cjs/features/utils/nr1-debugger.js +1 -1
- package/dist/cjs/interfaces/registered-entity.js +114 -0
- package/dist/cjs/loaders/agent-base.js +1 -1
- package/dist/cjs/loaders/agent.js +3 -1
- package/dist/cjs/loaders/api/api-methods.js +1 -1
- package/dist/cjs/loaders/api/api.js +97 -69
- package/dist/cjs/loaders/api/apiAsync.js +19 -22
- package/dist/cjs/loaders/api/register-api-types.js +35 -0
- package/dist/cjs/loaders/api/register-api.js +165 -0
- package/dist/cjs/loaders/configure/configure.js +12 -15
- package/dist/cjs/loaders/micro-agent-base.js +17 -1
- package/dist/cjs/loaders/micro-agent.js +4 -1
- package/dist/esm/common/config/init-types.js +92 -0
- package/dist/esm/common/config/init.js +9 -79
- package/dist/esm/common/config/runtime.js +7 -6
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/dom/selector-path.js +1 -1
- package/dist/esm/common/harvest/harvester.js +3 -3
- package/dist/esm/common/util/feature-flags.js +6 -6
- package/dist/esm/common/util/target.js +27 -0
- package/dist/esm/features/ajax/aggregate/index.js +2 -1
- package/dist/esm/features/generic_events/aggregate/index.js +10 -6
- package/dist/esm/features/jserrors/aggregate/index.js +44 -22
- package/dist/esm/features/logging/aggregate/index.js +17 -11
- package/dist/esm/features/logging/shared/utils.js +3 -2
- package/dist/esm/features/metrics/aggregate/index.js +6 -4
- package/dist/esm/features/page_view_event/aggregate/index.js +60 -11
- package/dist/esm/features/page_view_event/instrument/index.js +4 -0
- package/dist/esm/features/session_replay/aggregate/index.js +8 -6
- package/dist/esm/features/session_replay/instrument/index.js +1 -1
- package/dist/esm/features/session_replay/shared/recorder-events.js +4 -2
- package/dist/esm/features/session_replay/shared/recorder.js +17 -11
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +4 -3
- package/dist/esm/features/soft_navigations/aggregate/index.js +12 -2
- package/dist/esm/features/spa/aggregate/index.js +3 -3
- package/dist/esm/features/spa/aggregate/interaction.js +6 -9
- package/dist/esm/features/utils/aggregate-base.js +51 -24
- package/dist/esm/features/utils/entity-manager.js +40 -0
- package/dist/esm/features/utils/event-store-manager.js +79 -54
- package/dist/esm/features/utils/nr1-debugger.js +1 -1
- package/dist/esm/interfaces/registered-entity.js +107 -0
- package/dist/esm/loaders/agent-base.js +1 -1
- package/dist/esm/loaders/agent.js +3 -1
- package/dist/esm/loaders/api/api-methods.js +1 -1
- package/dist/esm/loaders/api/api.js +95 -67
- package/dist/esm/loaders/api/apiAsync.js +14 -17
- package/dist/esm/loaders/api/register-api-types.js +33 -0
- package/dist/esm/loaders/api/register-api.js +159 -0
- package/dist/esm/loaders/configure/configure.js +13 -16
- package/dist/esm/loaders/micro-agent-base.js +17 -1
- package/dist/esm/loaders/micro-agent.js +4 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/init-types.d.ts +275 -0
- package/dist/types/common/config/init-types.d.ts.map +1 -0
- package/dist/types/common/config/init.d.ts +1 -262
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/dom/selector-path.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/target.d.ts +18 -0
- package/dist/types/common/util/target.d.ts.map +1 -0
- package/dist/types/features/ajax/aggregate/index.d.ts +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +2 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +9 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +3 -3
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/shared/utils.d.ts +2 -1
- package/dist/types/features/logging/shared/utils.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts +1 -0
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +10 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +2 -11
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder-events.d.ts +1 -0
- package/dist/types/features/session_replay/shared/recorder-events.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts +4 -4
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/interaction.d.ts +3 -4
- package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +22 -5
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/entity-manager.d.ts +15 -0
- package/dist/types/features/utils/entity-manager.d.ts.map +1 -0
- package/dist/types/features/utils/event-store-manager.d.ts +48 -24
- package/dist/types/features/utils/event-store-manager.d.ts.map +1 -1
- package/dist/types/interfaces/registered-entity.d.ts +72 -0
- package/dist/types/interfaces/registered-entity.d.ts.map +1 -0
- package/dist/types/loaders/agent.d.ts +2 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +1 -20
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +56 -0
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -0
- package/dist/types/loaders/api/register-api.d.ts +14 -0
- package/dist/types/loaders/api/register-api.d.ts.map +1 -0
- package/dist/types/loaders/configure/configure.d.ts +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent-base.d.ts +17 -0
- package/dist/types/loaders/micro-agent-base.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts +2 -0
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +10 -1
- package/src/common/config/init-types.js +92 -0
- package/src/common/config/init.js +9 -79
- package/src/common/config/runtime.js +7 -6
- package/src/common/dom/selector-path.js +1 -3
- package/src/common/harvest/harvester.js +3 -3
- package/src/common/util/feature-flags.js +6 -6
- package/src/common/util/target.js +27 -0
- package/src/features/ajax/aggregate/index.js +2 -1
- package/src/features/generic_events/aggregate/index.js +8 -6
- package/src/features/jserrors/aggregate/index.js +42 -20
- package/src/features/logging/aggregate/index.js +14 -10
- package/src/features/logging/shared/utils.js +3 -2
- package/src/features/metrics/aggregate/index.js +7 -5
- package/src/features/page_view_event/aggregate/index.js +50 -8
- package/src/features/page_view_event/instrument/index.js +4 -0
- package/src/features/session_replay/aggregate/index.js +6 -3
- package/src/features/session_replay/instrument/index.js +1 -1
- package/src/features/session_replay/shared/recorder-events.js +5 -2
- package/src/features/session_replay/shared/recorder.js +17 -11
- package/src/features/session_trace/aggregate/trace/storage.js +3 -3
- package/src/features/soft_navigations/aggregate/index.js +11 -2
- package/src/features/spa/aggregate/index.js +3 -3
- package/src/features/spa/aggregate/interaction.js +6 -9
- package/src/features/utils/aggregate-base.js +56 -24
- package/src/features/utils/entity-manager.js +45 -0
- package/src/features/utils/event-store-manager.js +72 -49
- package/src/features/utils/nr1-debugger.js +1 -1
- package/src/interfaces/registered-entity.js +107 -0
- package/src/loaders/agent-base.js +2 -2
- package/src/loaders/agent.js +4 -1
- package/src/loaders/api/api-methods.js +1 -1
- package/src/loaders/api/api.js +94 -62
- package/src/loaders/api/apiAsync.js +14 -18
- package/src/loaders/api/register-api-types.js +33 -0
- package/src/loaders/api/register-api.js +152 -0
- package/src/loaders/configure/configure.js +12 -12
- package/src/loaders/micro-agent-base.js +18 -2
- package/src/loaders/micro-agent.js +5 -1
|
@@ -23,7 +23,7 @@ class MicroAgentBase {
|
|
|
23
23
|
* @param {...any} args
|
|
24
24
|
*/
|
|
25
25
|
#callMethod(methodName, ...args) {
|
|
26
|
-
if (
|
|
26
|
+
if (this[methodName] === MicroAgentBase.prototype[methodName]) (0, _console.warn)(35, methodName);else return this[methodName](...args);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// MicroAgent class custom defines its own start
|
|
@@ -38,6 +38,22 @@ class MicroAgentBase {
|
|
|
38
38
|
return this.#callMethod('addPageAction', name, attributes);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @experimental
|
|
43
|
+
* IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state.
|
|
44
|
+
* It is not recommended for use in production environments and will not receive support for issues.
|
|
45
|
+
*
|
|
46
|
+
* Registers an external caller to report through the base agent to a different target than the base agent.
|
|
47
|
+
* @param {object} target the target object to report data to
|
|
48
|
+
* @param {string} target.licenseKey The licenseKey to report data to
|
|
49
|
+
* @param {string} target.applicationID The applicationID to report data to
|
|
50
|
+
* @param {string=} target.entityGuid The entityGuid to report data to
|
|
51
|
+
* @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
|
|
52
|
+
*/
|
|
53
|
+
register(target) {
|
|
54
|
+
return this.#callMethod('register', target);
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
/**
|
|
42
58
|
* Records a custom event with a specified eventType and attributes.
|
|
43
59
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
|
|
@@ -20,6 +20,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
20
20
|
const nonAutoFeatures = [_features.FEATURE_NAMES.jserrors, _features.FEATURE_NAMES.genericEvents, _features.FEATURE_NAMES.metrics, _features.FEATURE_NAMES.logging];
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
+
* @deprecated This feature has been deprecated and will be removed in a future release. A future product centralizing around a single agent instance will be released as a replacement, at which time this loader will be removed.
|
|
23
24
|
* A minimal agent class designed to only respond to manual user input. As such, this class does not
|
|
24
25
|
* automatically instrument. Instead, each MicroAgent instance will lazy load the required features and can support loading multiple instances on one page.
|
|
25
26
|
* Out of the box, it can manually handle and report Page View, Page Action, and Error events.
|
|
@@ -38,7 +39,6 @@ class MicroAgent extends _microAgentBase.MicroAgentBase {
|
|
|
38
39
|
isolatedBacklog: true
|
|
39
40
|
}
|
|
40
41
|
}, options.loaderType || 'micro-agent');
|
|
41
|
-
Object.assign(this, this.api); // the APIs should be available at the class level for micro-agent
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Starts a set of agent features if not running in "autoStart" mode
|
|
@@ -91,5 +91,8 @@ class MicroAgent extends _microAgentBase.MicroAgentBase {
|
|
|
91
91
|
runtime: this.runtime
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
|
+
get api() {
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
94
97
|
}
|
|
95
98
|
exports.MicroAgent = MicroAgent;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} Init
|
|
9
|
+
* @property {Object} [ajax]
|
|
10
|
+
* @property {Array<string>} [ajax.deny_list] - List of domain URLs to be excluded from AjaxRequest collection.
|
|
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
|
+
* @property {boolean} [ajax.enabled] - Turn on/off the ajax feature (on by default).
|
|
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 {Object} [api]
|
|
15
|
+
* @property {boolean} [api.allow_registered_children] - If true, the agent will allow registered children to be sent to the server.
|
|
16
|
+
* @property {boolean} [api.duplicate_registered_data] - If true, the agent will capture registered child data to the main agent as well as the registered child.
|
|
17
|
+
* @property {Object} [distributed_tracing]
|
|
18
|
+
* @property {boolean} [distributed_tracing.enabled] - If true, distributed tracing headers will be added to outgoing requests. Requires ajax feature to be running.
|
|
19
|
+
* @property {boolean} [distributed_tracing.exclude_newrelic_header]
|
|
20
|
+
* @property {boolean} [distributed_tracing.cors_use_newrelic_header]
|
|
21
|
+
* @property {boolean} [distributed_tracing.cors_use_tracecontext_headers]
|
|
22
|
+
* @property {Array<string>} [distributed_tracing.allowed_origins]
|
|
23
|
+
* @property {Array<string>} [feature_flags] - An array of feature flags to enable experimental features.
|
|
24
|
+
* @property {Object} [generic_events]
|
|
25
|
+
* @property {boolean} [generic_events.enabled] - Turn on/off the generic events feature (on by default). This is required for `PageAction`, `UserAction`, and `BrowserPerformance` events.
|
|
26
|
+
* @property {boolean} [generic_events.autoStart] - If true, the agent will automatically start the generic events feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
27
|
+
* @property {Object} [harvest]
|
|
28
|
+
* @property {number} [harvest.interval] - The interval in seconds at which the agent will send out data. It's not recommended to change this value.
|
|
29
|
+
* @property {Object} [jserrors]
|
|
30
|
+
* @property {boolean} [jserrors.enabled] - Turn on/off the jserrors feature (on by default).
|
|
31
|
+
* @property {boolean} [jserrors.autoStart] - If true, the agent will automatically start the jserrors feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
32
|
+
* @property {Object} [logging]
|
|
33
|
+
* @property {boolean} [logging.enabled] - Turn on/off the logging feature (on by default).
|
|
34
|
+
* @property {boolean} [logging.autoStart] - If true, the agent will automatically start the logging feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
35
|
+
* @property {Object} [metrics]
|
|
36
|
+
* @property {boolean} [metrics.enabled] - Turn on/off the metrics feature (on by default).
|
|
37
|
+
* @property {boolean} [metrics.autoStart] - If true, the agent will automatically start the metrics feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
38
|
+
* @property {Array<Object>} [obfuscate] - Array of regexp and corresponding replacement patterns for obfuscating data.
|
|
39
|
+
* @property {Object} [page_action]
|
|
40
|
+
* @property {boolean} [page_action.enabled] - Must be true to allow PageAction events to be captured.
|
|
41
|
+
* @property {Object} [page_view_event]
|
|
42
|
+
* @property {boolean} [page_view_event.enabled] - This setting is ignored! PageViewEvent is always enabled by force.
|
|
43
|
+
* @property {boolean} [page_view_event.autoStart] - If true, the agent will automatically send the RUM request. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
44
|
+
* @property {Object} [page_view_timing]
|
|
45
|
+
* @property {boolean} [page_view_timing.enabled] - Turn on/off the page view timing feature (on by default).
|
|
46
|
+
* @property {boolean} [page_view_timing.autoStart] - If true, the agent will automatically start the page view timing feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
47
|
+
* @property {Object} [performance]
|
|
48
|
+
* @property {boolean} [performance.capture_marks] - If true, the agent will capture PerformanceMark events.
|
|
49
|
+
* @property {boolean} [performance.capture_measures] - If true, the agent will capture PerformanceMeasure events.
|
|
50
|
+
* @property {boolean} [performance.capture_detail] - If true, `BrowserPerformance` events from marks and measures will include, as attribute(s), the `detail` metadata provided to `markOptions` and `measureOptions`.
|
|
51
|
+
* @property {Object} [performance.resources]
|
|
52
|
+
* @property {boolean} [performance.resources.enabled] - If true, the agent will capture PerformanceResourceTiming entries.
|
|
53
|
+
* @property {Array<string>} [performance.resources.asset_types] - Array of `initiatorType` strings to filter the desired ResourceTiming entries. By default, all resource types are captured.
|
|
54
|
+
* @property {Array<string>} [performance.resources.first_party_domains] - Each resource URL will be checked against this list to determine if it should be labeled "first party" in the resulting `BrowserPerformance` event.
|
|
55
|
+
* @property {boolean} [performance.resources.ignore_newrelic] - When true (default), resource entries associated with New Relic domains will be ignored.
|
|
56
|
+
* @property {Object} [privacy]
|
|
57
|
+
* @property {boolean} [privacy.cookies_enabled] - If true (default), session tracking of users across page loads is enabled in the agent. This is required for session trace, replay, and session-related features.
|
|
58
|
+
* @property {Object} [proxy]
|
|
59
|
+
* @property {string} [proxy.assets] - Set value will be used to overwrite the webpack asset path used to fetch agent assets.
|
|
60
|
+
* @property {string} [proxy.beacon] - Set value will be used to overwrite the endpoint URL to which we send analytics.
|
|
61
|
+
* @property {Object} [session]
|
|
62
|
+
* @property {number} [session.expiresMs] - When session tracking is on, this determines how long a session will last before expiring. Modifying this value is not recommended.
|
|
63
|
+
* @property {number} [session.inactiveMs] - When session tracking is on, this determines how long a session will last without user activity before expiring. Modifying this value is not recommended.
|
|
64
|
+
* @property {Object} [session_replay]
|
|
65
|
+
* @property {boolean} [session_replay.autoStart] - If true, the agent will automatically start the session replay feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
66
|
+
* @property {boolean} [session_replay.enabled] - Turn on/off the session replay feature (off by default).
|
|
67
|
+
* @property {boolean} [session_replay.preload] - If true, allow the agent to run rrweb recorder immediately instead of waiting until after the window.load event, for new sessions. Existing sessions ignore this setting.
|
|
68
|
+
* @property {number} [session_replay.sampling_rate] - This setting is deprecated and ineffective. Sampling is controlled in New Relic by server-side configuration.
|
|
69
|
+
* @property {number} [session_replay.error_sampling_rate] - This setting is deprecated and ineffective.
|
|
70
|
+
* @property {boolean} [session_replay.collect_fonts] - When true, serialize fonts for collection without public asset url. This is currently broken -- https://github.com/rrweb-io/rrweb/issues/1304.
|
|
71
|
+
* @property {boolean} [session_replay.inline_images] - When true, serialize images for collection without public asset url. Not recommended for use. This is currently for TESTING as it easily generates payloads too large to be harvested.
|
|
72
|
+
* @property {boolean} [session_replay.fix_stylesheets] - When true, tries to fetch any missing stylesheets again to inline in replayer.
|
|
73
|
+
* @property {boolean} [session_replay.mask_all_inputs] - If true, all input content will be masked with asterisks.
|
|
74
|
+
* @property {string} [session_replay.mask_text_selector] - Set value should be in CSS selector syntax and is used to identify matching elements to mask.
|
|
75
|
+
* @property {string} [session_replay.block_selector] - Set value should be in CSS selector syntax and is used to identify matching elements to block.
|
|
76
|
+
* @property {Object} [session_replay.mask_input_options] - If mask_all_inputs is not true, this object will be used to select what input to mask. Passwords are forcibly always masked.
|
|
77
|
+
* @property {Object} [session_trace]
|
|
78
|
+
* @property {boolean} [session_trace.enabled] - Turn on/off the session trace feature (on by default).
|
|
79
|
+
* @property {boolean} [session_trace.autoStart] - If true, the agent will automatically start the session trace feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
80
|
+
* @property {Object} [soft_navigations]
|
|
81
|
+
* @property {boolean} [soft_navigations.enabled] - Turn on/off the soft navigations feature (on by default).
|
|
82
|
+
* @property {boolean} [soft_navigations.autoStart] - If true, the agent will automatically start the soft navigations feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
83
|
+
* @property {Object} [spa]
|
|
84
|
+
* @property {boolean} [spa.enabled] - Turn on/off the single page application feature (on by default). NOTE: the SPA feature is deprecated and under removal procedure.
|
|
85
|
+
* @property {boolean} [spa.autoStart] - If true, the agent will automatically start the single page application feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
86
|
+
* @property {boolean} [ssl] - If explicitly false, the agent will use HTTP instead of HTTPS. This setting should NOT be used.
|
|
87
|
+
* @property {Object} [user_actions]
|
|
88
|
+
* @property {boolean} [user_actions.enabled] - Must be true to allow UserAction events to be captured.
|
|
89
|
+
* @property {Array<string>} [user_actions.elementAttributes] - List of HTML Element properties to be captured with UserAction events' target elements. This may help to identify the source element being interacted with in the UI.
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
export default {};
|
|
@@ -10,88 +10,14 @@ import { getNREUMInitializedAgent } from '../window/nreum';
|
|
|
10
10
|
import { getModeledObject } from './configurable';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @typedef {
|
|
14
|
-
* @property {Object} [ajax]
|
|
15
|
-
* @property {Array<string>} [ajax.deny_list] - List of domain URLs to be excluded from AjaxRequest collection.
|
|
16
|
-
* @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.
|
|
17
|
-
* @property {boolean} [ajax.enabled] - Turn on/off the ajax feature (on by default).
|
|
18
|
-
* @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.
|
|
19
|
-
* @property {Object} [distributed_tracing]
|
|
20
|
-
* @property {boolean} [distributed_tracing.enabled] - If true, distributed tracing headers will be added to outgoing requests. Requires ajax feature to be running.
|
|
21
|
-
* @property {boolean} [distributed_tracing.exclude_newrelic_header]
|
|
22
|
-
* @property {boolean} [distributed_tracing.cors_use_newrelic_header]
|
|
23
|
-
* @property {boolean} [distributed_tracing.cors_use_tracecontext_headers]
|
|
24
|
-
* @property {Array<string>} [distributed_tracing.allowed_origins]
|
|
25
|
-
* @property {Array<string>} [feature_flags] - An array of feature flags to enable experimental features.
|
|
26
|
-
* @property {Object} [generic_events]
|
|
27
|
-
* @property {boolean} [generic_events.enabled] - Turn on/off the generic events feature (on by default). This is required for `PageAction`, `UserAction`, and `BrowserPerformance` events.
|
|
28
|
-
* @property {boolean} [generic_events.autoStart] - If true, the agent will automatically start the generic events feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
29
|
-
* @property {Object} [harvest]
|
|
30
|
-
* @property {number} [harvest.interval] - The interval in seconds at which the agent will send out data. It's not recommended to change this value.
|
|
31
|
-
* @property {Object} [jserrors]
|
|
32
|
-
* @property {boolean} [jserrors.enabled] - Turn on/off the jserrors feature (on by default).
|
|
33
|
-
* @property {boolean} [jserrors.autoStart] - If true, the agent will automatically start the jserrors feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
34
|
-
* @property {Object} [logging]
|
|
35
|
-
* @property {boolean} [logging.enabled] - Turn on/off the logging feature (on by default).
|
|
36
|
-
* @property {boolean} [logging.autoStart] - If true, the agent will automatically start the logging feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
37
|
-
* @property {Object} [metrics]
|
|
38
|
-
* @property {boolean} [metrics.enabled] - Turn on/off the metrics feature (on by default).
|
|
39
|
-
* @property {boolean} [metrics.autoStart] - If true, the agent will automatically start the metrics feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
40
|
-
* @property {Array<Object>} [obfuscate] - Array of regexp and corresponding replacement patterns for obfuscating data.
|
|
41
|
-
* @property {Object} [page_action]
|
|
42
|
-
* @property {boolean} [page_action.enabled] - Must be true to allow PageAction events to be captured.
|
|
43
|
-
* @property {Object} [page_view_event]
|
|
44
|
-
* @property {boolean} [page_view_event.enabled] - This setting is ignored! PageViewEvent is always enabled by force.
|
|
45
|
-
* @property {boolean} [page_view_event.autoStart] - If true, the agent will automatically send the RUM request. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
46
|
-
* @property {Object} [page_view_timing]
|
|
47
|
-
* @property {boolean} [page_view_timing.enabled] - Turn on/off the page view timing feature (on by default).
|
|
48
|
-
* @property {boolean} [page_view_timing.autoStart] - If true, the agent will automatically start the page view timing feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
49
|
-
* @property {Object} [performance]
|
|
50
|
-
* @property {boolean} [performance.capture_marks] - If true, the agent will capture PerformanceMark events.
|
|
51
|
-
* @property {boolean} [performance.capture_measures] - If true, the agent will capture PerformanceMeasure events.
|
|
52
|
-
* @property {boolean} [performance.capture_detail] - If true, `BrowserPerformance` events from marks and measures will include, as attribute(s), the `detail` metadata provided to `markOptions` and `measureOptions`.
|
|
53
|
-
* @property {Object} [performance.resources]
|
|
54
|
-
* @property {boolean} [performance.resources.enabled] - If true, the agent will capture PerformanceResourceTiming entries.
|
|
55
|
-
* @property {Array<string>} [performance.resources.asset_types] - Array of `initiatorType` strings to filter the desired ResourceTiming entries. By default, all resource types are captured.
|
|
56
|
-
* @property {Array<string>} [performance.resources.first_party_domains] - Each resource URL will be checked against this list to determine if it should be labeled "first party" in the resulting `BrowserPerformance` event.
|
|
57
|
-
* @property {boolean} [performance.resources.ignore_newrelic] - When true (default), resource entries associated with New Relic domains will be ignored.
|
|
58
|
-
* @property {Object} [privacy]
|
|
59
|
-
* @property {boolean} [privacy.cookies_enabled] - If true (default), session tracking of users across page loads is enabled in the agent. This is required for session trace, replay, and session-related features.
|
|
60
|
-
* @property {Object} [proxy]
|
|
61
|
-
* @property {string} [proxy.assets] - Set value will be used to overwrite the webpack asset path used to fetch agent assets.
|
|
62
|
-
* @property {string} [proxy.beacon] - Set value will be used to overwrite the endpoint URL to which we send analytics.
|
|
63
|
-
* @property {Object} [session]
|
|
64
|
-
* @property {number} [session.expiresMs] - When session tracking is on, this determines how long a session will last before expiring. Modifying this value is not recommended.
|
|
65
|
-
* @property {number} [session.inactiveMs] - When session tracking is on, this determines how long a session will last without user activity before expiring. Modifying this value is not recommended.
|
|
66
|
-
* @property {Object} [session_replay]
|
|
67
|
-
* @property {boolean} [session_replay.autoStart] - If true, the agent will automatically start the session replay feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
68
|
-
* @property {boolean} [session_replay.enabled] - Turn on/off the session replay feature (off by default).
|
|
69
|
-
* @property {boolean} [session_replay.preload] - If true, allow the agent to run rrweb recorder immediately instead of waiting until after the window.load event, for new sessions. Existing sessions ignore this setting.
|
|
70
|
-
* @property {number} [session_replay.sampling_rate] - This setting is deprecated and ineffective. Sampling is controlled in New Relic by server-side configuration.
|
|
71
|
-
* @property {number} [session_replay.error_sampling_rate] - This setting is deprecated and ineffective.
|
|
72
|
-
* @property {boolean} [session_replay.collect_fonts] - When true, serialize fonts for collection without public asset url. This is currently broken -- https://github.com/rrweb-io/rrweb/issues/1304.
|
|
73
|
-
* @property {boolean} [session_replay.inline_images] - When true, serialize images for collection without public asset url. Not recommended for use. This is currently for TESTING as it easily generates payloads too large to be harvested.
|
|
74
|
-
* @property {boolean} [session_replay.fix_stylesheets] - When true, tries to fetch any missing stylesheets again to inline in replayer.
|
|
75
|
-
* @property {boolean} [session_replay.mask_all_inputs] - If true, all input content will be masked with asterisks.
|
|
76
|
-
* @property {string} [session_replay.mask_text_selector] - Set value should be in CSS selector syntax and is used to identify matching elements to mask.
|
|
77
|
-
* @property {string} [session_replay.block_selector] - Set value should be in CSS selector syntax and is used to identify matching elements to block.
|
|
78
|
-
* @property {Object} [session_replay.mask_input_options] - If mask_all_inputs is not true, this object will be used to select what input to mask. Passwords are forcibly always masked.
|
|
79
|
-
* @property {Object} [session_trace]
|
|
80
|
-
* @property {boolean} [session_trace.enabled] - Turn on/off the session trace feature (on by default).
|
|
81
|
-
* @property {boolean} [session_trace.autoStart] - If true, the agent will automatically start the session trace feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
82
|
-
* @property {Object} [soft_navigations]
|
|
83
|
-
* @property {boolean} [soft_navigations.enabled] - Turn on/off the soft navigations feature (on by default).
|
|
84
|
-
* @property {boolean} [soft_navigations.autoStart] - If true, the agent will automatically start the soft navigations feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
85
|
-
* @property {Object} [spa]
|
|
86
|
-
* @property {boolean} [spa.enabled] - Turn on/off the single page application feature (on by default). NOTE: the SPA feature is deprecated and under removal procedure.
|
|
87
|
-
* @property {boolean} [spa.autoStart] - If true, the agent will automatically start the single page application feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
88
|
-
* @property {boolean} [ssl] - If explicitly false, the agent will use HTTP instead of HTTPS. This setting should NOT be used.
|
|
89
|
-
* @property {Object} [user_actions]
|
|
90
|
-
* @property {boolean} [user_actions.enabled] - Must be true to allow UserAction events to be captured.
|
|
91
|
-
* @property {Array<string>} [user_actions.elementAttributes] - List of HTML Element properties to be captured with UserAction events' target elements. This may help to identify the source element being interacted with in the UI.
|
|
13
|
+
* @typedef {import('./init-types').Init} Init
|
|
92
14
|
*/
|
|
93
15
|
|
|
94
16
|
const nrMask = '[data-nr-mask]';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @returns {Init} the default configuration object
|
|
20
|
+
*/
|
|
95
21
|
const model = () => {
|
|
96
22
|
const hiddenState = {
|
|
97
23
|
feature_flags: [],
|
|
@@ -129,6 +55,10 @@ const model = () => {
|
|
|
129
55
|
enabled: true,
|
|
130
56
|
autoStart: true
|
|
131
57
|
},
|
|
58
|
+
api: {
|
|
59
|
+
allow_registered_children: true,
|
|
60
|
+
duplicate_registered_data: false
|
|
61
|
+
},
|
|
132
62
|
distributed_tracing: {
|
|
133
63
|
enabled: undefined,
|
|
134
64
|
exclude_newrelic_header: undefined,
|
|
@@ -19,21 +19,22 @@ const readonly = {
|
|
|
19
19
|
originTime
|
|
20
20
|
};
|
|
21
21
|
const model = {
|
|
22
|
+
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
23
|
+
appMetadata: {},
|
|
22
24
|
customTransaction: undefined,
|
|
25
|
+
denyList: undefined,
|
|
23
26
|
disabled: false,
|
|
27
|
+
entityManager: undefined,
|
|
28
|
+
harvester: undefined,
|
|
24
29
|
isolatedBacklog: false,
|
|
25
30
|
loaderType: undefined,
|
|
26
31
|
maxBytes: 30000,
|
|
32
|
+
obfuscator: undefined,
|
|
27
33
|
onerror: undefined,
|
|
28
34
|
ptid: undefined,
|
|
29
35
|
releaseIds: {},
|
|
30
|
-
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
31
|
-
appMetadata: {},
|
|
32
36
|
session: undefined,
|
|
33
|
-
|
|
34
|
-
timeKeeper: undefined,
|
|
35
|
-
obfuscator: undefined,
|
|
36
|
-
harvester: undefined
|
|
37
|
+
timeKeeper: undefined
|
|
37
38
|
};
|
|
38
39
|
const _cache = {};
|
|
39
40
|
export function getRuntime(id) {
|
|
@@ -40,7 +40,7 @@ export const generateSelectorPath = (elem, targetFields = []) => {
|
|
|
40
40
|
localName
|
|
41
41
|
} = elem;
|
|
42
42
|
targetFields.forEach(field => {
|
|
43
|
-
nearestFields[nearestAttrName(field)] ||= elem[field];
|
|
43
|
+
nearestFields[nearestAttrName(field)] ||= elem[field]?.baseVal || elem[field];
|
|
44
44
|
});
|
|
45
45
|
const selector = [localName, id ? "#".concat(id) : '', pathSelector ? ">".concat(pathSelector) : ''].join('');
|
|
46
46
|
pathSelector = selector;
|
|
@@ -145,7 +145,7 @@ function send(agentRef, {
|
|
|
145
145
|
const protocol = agentRef.init.ssl === false ? 'http' : 'https';
|
|
146
146
|
const perceivedBeacon = agentRef.init.proxy.beacon || agentRef.info.errorBeacon;
|
|
147
147
|
const url = raw ? "".concat(protocol, "://").concat(perceivedBeacon, "/").concat(endpoint) : "".concat(protocol, "://").concat(perceivedBeacon).concat(endpoint !== RUM ? '/' + endpoint : '', "/1/").concat(targetApp.licenseKey);
|
|
148
|
-
const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint, targetApp.
|
|
148
|
+
const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint, targetApp.applicationID) : '';
|
|
149
149
|
let payloadParams = obj(qs, agentRef.runtime.maxBytes);
|
|
150
150
|
if (baseParams === '' && payloadParams.startsWith('&')) {
|
|
151
151
|
payloadParams = payloadParams.substring(1);
|
|
@@ -185,8 +185,8 @@ function send(agentRef, {
|
|
|
185
185
|
sent: this.status !== 0,
|
|
186
186
|
status: this.status,
|
|
187
187
|
retry: shouldRetry(this.status),
|
|
188
|
-
xhr: this,
|
|
189
188
|
fullUrl,
|
|
189
|
+
xhr: this,
|
|
190
190
|
targetApp
|
|
191
191
|
};
|
|
192
192
|
if (localOpts.needResponse) cbResult.responseText = this.responseText;
|
|
@@ -210,7 +210,7 @@ function send(agentRef, {
|
|
|
210
210
|
}
|
|
211
211
|
dispatchGlobalEvent({
|
|
212
212
|
agentIdentifier: agentRef.agentIdentifier,
|
|
213
|
-
|
|
213
|
+
drained: !!activatedFeatures?.[agentRef.agentIdentifier],
|
|
214
214
|
type: 'data',
|
|
215
215
|
name: 'harvest',
|
|
216
216
|
feature: featureName,
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
-
import { ee } from '../event-emitter/contextual-ee';
|
|
6
5
|
import { dispatchGlobalEvent } from '../dispatch/global-event';
|
|
7
6
|
const sentIds = new Set();
|
|
8
7
|
|
|
@@ -16,19 +15,20 @@ export const activatedFeatures = {};
|
|
|
16
15
|
* @param {string} agentIdentifier agent instance identifier
|
|
17
16
|
* @returns {void}
|
|
18
17
|
*/
|
|
19
|
-
export function activateFeatures(flags,
|
|
20
|
-
const
|
|
18
|
+
export function activateFeatures(flags, agentRef) {
|
|
19
|
+
const agentIdentifier = agentRef.agentIdentifier;
|
|
21
20
|
activatedFeatures[agentIdentifier] ??= {};
|
|
22
|
-
if (!
|
|
21
|
+
if (!flags || typeof flags !== 'object') return;
|
|
23
22
|
if (sentIds.has(agentIdentifier)) return;
|
|
24
|
-
|
|
23
|
+
agentRef.ee.emit('rumresp', [flags]);
|
|
25
24
|
activatedFeatures[agentIdentifier] = flags;
|
|
26
25
|
sentIds.add(agentIdentifier);
|
|
27
26
|
|
|
28
|
-
// let any window level subscribers know that the agent is running
|
|
27
|
+
// let any window level subscribers know that the agent is running, per install docs
|
|
29
28
|
dispatchGlobalEvent({
|
|
30
29
|
agentIdentifier,
|
|
31
30
|
loaded: true,
|
|
31
|
+
drained: true,
|
|
32
32
|
type: 'lifecycle',
|
|
33
33
|
name: 'load',
|
|
34
34
|
feature: undefined,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {Object} [target] - the target to be validated
|
|
8
|
+
* @param {boolean} [allowUndefined=true]
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
export function isValidTarget(target) {
|
|
12
|
+
/** target can be undefined to support legacy/default behaviors - main agent does not supply a target */
|
|
13
|
+
if (!target) return true;
|
|
14
|
+
/** if not undefined, we require specific values */
|
|
15
|
+
return !!(target.licenseKey && target.applicationID);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Checks if the target matches the container agent target
|
|
20
|
+
* @param {*} target the target to be validated
|
|
21
|
+
* @param {*} agentRef the agent reference to be validated
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
export function isContainerAgentTarget(target, agentRef) {
|
|
25
|
+
if (!target) return true;
|
|
26
|
+
return target.licenseKey === agentRef.info.licenseKey && target.applicationID === agentRef.info.applicationID;
|
|
27
|
+
}
|
|
@@ -54,7 +54,7 @@ export class Aggregate extends AggregateBase {
|
|
|
54
54
|
|
|
55
55
|
// Report ajax timeslice metric (to be harvested by jserrors feature, but only if it's running).
|
|
56
56
|
if (jserrorsInUse && (shouldCollect || !shouldOmitAjaxMetrics)) {
|
|
57
|
-
this.agentRef.sharedAggregator
|
|
57
|
+
this.agentRef.sharedAggregator?.add(['xhr', hash, params, metrics]);
|
|
58
58
|
}
|
|
59
59
|
if (!shouldCollect) {
|
|
60
60
|
if (params.hostname === this.agentRef.info.errorBeacon || this.agentRef.init.proxy?.beacon && params.hostname === this.agentRef.init.proxy.beacon) {
|
|
@@ -107,6 +107,7 @@ export class Aggregate extends AggregateBase {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
serializer(eventBuffer) {
|
|
110
|
+
if (!eventBuffer.length) return;
|
|
110
111
|
const addString = getAddStringContext(this.agentIdentifier);
|
|
111
112
|
let payload = 'bel.7;';
|
|
112
113
|
for (let i = 0; i < eventBuffer.length; i++) {
|
|
@@ -37,7 +37,8 @@ export class Aggregate extends AggregateBase {
|
|
|
37
37
|
});
|
|
38
38
|
}, this.featureName, this.ee);
|
|
39
39
|
if (agentRef.init.page_action.enabled) {
|
|
40
|
-
registerHandler('api-addPageAction', (timestamp, name, attributes) => {
|
|
40
|
+
registerHandler('api-addPageAction', (timestamp, name, attributes, targetEntityGuid) => {
|
|
41
|
+
if (!this.agentRef.runtime.entityManager.get(targetEntityGuid)) return warn(56, this.featureName);
|
|
41
42
|
this.addEvent({
|
|
42
43
|
...attributes,
|
|
43
44
|
eventType: 'PageAction',
|
|
@@ -49,7 +50,7 @@ export class Aggregate extends AggregateBase {
|
|
|
49
50
|
browserWidth: window.document.documentElement?.clientWidth,
|
|
50
51
|
browserHeight: window.document.documentElement?.clientHeight
|
|
51
52
|
})
|
|
52
|
-
});
|
|
53
|
+
}, targetEntityGuid);
|
|
53
54
|
}, this.featureName, this.ee);
|
|
54
55
|
}
|
|
55
56
|
let addUserAction = () => {/** no-op */};
|
|
@@ -231,9 +232,10 @@ export class Aggregate extends AggregateBase {
|
|
|
231
232
|
* * sessionTraceId: set by the `ptid=` query param
|
|
232
233
|
* * userAgent*: set by the userAgent header
|
|
233
234
|
* @param {object=} obj the event object for storing in the event buffer
|
|
235
|
+
* @param {string=} targetEntityGuid the target entity guid for the event to scope buffering and harvesting. Defaults to agent config if undefined
|
|
234
236
|
* @returns void
|
|
235
237
|
*/
|
|
236
|
-
addEvent(obj = {}) {
|
|
238
|
+
addEvent(obj = {}, targetEntityGuid) {
|
|
237
239
|
if (!obj || !Object.keys(obj).length) return;
|
|
238
240
|
if (!obj.eventType) {
|
|
239
241
|
warn(44);
|
|
@@ -258,14 +260,16 @@ export class Aggregate extends AggregateBase {
|
|
|
258
260
|
/** Event-specific attributes take precedence over agent-level custom attributes and fallbacks */
|
|
259
261
|
...obj
|
|
260
262
|
};
|
|
261
|
-
const addedEvent = this.events.add(eventAttributes);
|
|
262
|
-
if (!addedEvent && !this.events.isEmpty()) {
|
|
263
|
+
const addedEvent = this.events.add(eventAttributes, targetEntityGuid);
|
|
264
|
+
if (!addedEvent && !this.events.isEmpty(undefined, targetEntityGuid)) {
|
|
263
265
|
/** could not add the event because it pushed the buffer over the limit
|
|
264
266
|
* so we harvest early, and try to add it again now that the buffer is cleared
|
|
265
267
|
* if it fails again, we do nothing
|
|
266
268
|
*/
|
|
267
269
|
this.ee.emit(SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen']);
|
|
268
|
-
this.agentRef.runtime.harvester.triggerHarvestFor(this
|
|
270
|
+
this.agentRef.runtime.harvester.triggerHarvestFor(this, {
|
|
271
|
+
targetEntityGuid
|
|
272
|
+
});
|
|
269
273
|
this.events.add(eventAttributes);
|
|
270
274
|
}
|
|
271
275
|
}
|
|
@@ -17,6 +17,8 @@ import { AggregateBase } from '../../utils/aggregate-base';
|
|
|
17
17
|
import { now } from '../../../common/timing/now';
|
|
18
18
|
import { applyFnToProps } from '../../../common/util/traverse';
|
|
19
19
|
import { evaluateInternalError } from './internal-errors';
|
|
20
|
+
import { isContainerAgentTarget } from '../../../common/util/target';
|
|
21
|
+
import { warn } from '../../../common/util/console';
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* @typedef {import('./compute-stack-trace.js').StackInfo} StackInfo
|
|
@@ -96,10 +98,13 @@ export class Aggregate extends AggregateBase {
|
|
|
96
98
|
* @param {object=} customAttributes any custom attributes to be included in the error payload
|
|
97
99
|
* @param {boolean=} hasReplay a flag indicating if the error occurred during a replay session
|
|
98
100
|
* @param {string=} swallowReason a string indicating pre-defined reason if swallowing the error. Mainly used by the internal error SMs.
|
|
101
|
+
* @param {object=} target the target to buffer and harvest to, if undefined the default configuration target is used
|
|
99
102
|
* @returns
|
|
100
103
|
*/
|
|
101
|
-
storeError(err, time, internal, customAttributes, hasReplay, swallowReason) {
|
|
104
|
+
storeError(err, time, internal, customAttributes, hasReplay, swallowReason, targetEntityGuid) {
|
|
102
105
|
if (!err) return;
|
|
106
|
+
const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
|
|
107
|
+
if (!target) return warn(56, this.featureName);
|
|
103
108
|
// are we in an interaction
|
|
104
109
|
time = time || now();
|
|
105
110
|
let filterOutput;
|
|
@@ -131,7 +136,9 @@ export class Aggregate extends AggregateBase {
|
|
|
131
136
|
// Notice if filterOutput isn't false|undefined OR our specified object, this func would've returned already (so it's unnecessary to req-check group).
|
|
132
137
|
// Do not modify the name ('errorGroup') of params without DEM approval!
|
|
133
138
|
if (filterOutput?.group) params.errorGroup = filterOutput.group;
|
|
134
|
-
|
|
139
|
+
|
|
140
|
+
// Should only decorate "hasReplay" for the container agent, so check if the target matches the config
|
|
141
|
+
if (hasReplay && isContainerAgentTarget(target, this.agentRef)) params.hasReplay = hasReplay;
|
|
135
142
|
/**
|
|
136
143
|
* The bucketHash is different from the params.stackHash because the params.stackHash is based on the canonicalized
|
|
137
144
|
* stack trace and is used downstream in NR1 to attempt to group the same errors across different browsers. However,
|
|
@@ -166,33 +173,38 @@ export class Aggregate extends AggregateBase {
|
|
|
166
173
|
|
|
167
174
|
// Trace sends the error in its payload, and both trace & replay simply listens for any error to occur.
|
|
168
175
|
const jsErrorEvent = [type, bucketHash, params, newMetrics, customAttributes];
|
|
169
|
-
handle('trace-jserror', jsErrorEvent, undefined, FEATURE_NAMES.sessionTrace, this.ee);
|
|
176
|
+
if (this.shouldAllowMainAgentToCapture(targetEntityGuid)) handle('trace-jserror', jsErrorEvent, undefined, FEATURE_NAMES.sessionTrace, this.ee);
|
|
170
177
|
// still send EE events for other features such as above, but stop this one from aggregating internal data
|
|
171
178
|
if (this.blocked) return;
|
|
172
179
|
if (err?.__newrelic?.[this.agentIdentifier]) {
|
|
173
180
|
params._interactionId = err.__newrelic[this.agentIdentifier].interactionId;
|
|
174
181
|
params._interactionNodeId = err.__newrelic[this.agentIdentifier].interactionNodeId;
|
|
175
182
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
if (this.shouldAllowMainAgentToCapture(targetEntityGuid)) {
|
|
184
|
+
const softNavInUse = Boolean(this.agentRef.features?.[FEATURE_NAMES.softNav]);
|
|
185
|
+
// Note: the following are subject to potential race cond wherein if the other feature aren't fully initialized, it'll be treated as there being no associated interaction.
|
|
186
|
+
// They each will also tack on their respective properties to the params object as part of the decision flow.
|
|
187
|
+
if (softNavInUse) handle('jserror', [params, time], undefined, FEATURE_NAMES.softNav, this.ee);else handle('spa-jserror', jsErrorEvent, undefined, FEATURE_NAMES.spa, this.ee);
|
|
188
|
+
if (params.browserInteractionId && !params._softNavFinished) {
|
|
189
|
+
// hold onto the error until the in-progress interaction is done, eithered saved or discarded
|
|
190
|
+
this.bufferedErrorsUnderSpa[params.browserInteractionId] ??= [];
|
|
191
|
+
this.bufferedErrorsUnderSpa[params.browserInteractionId].push(jsErrorEvent);
|
|
192
|
+
} else if (params._interactionId != null) {
|
|
193
|
+
// same as above, except tailored for the way old spa does it
|
|
194
|
+
this.bufferedErrorsUnderSpa[params._interactionId] = this.bufferedErrorsUnderSpa[params._interactionId] || [];
|
|
195
|
+
this.bufferedErrorsUnderSpa[params._interactionId].push(jsErrorEvent);
|
|
196
|
+
} else {
|
|
197
|
+
// Either there is no interaction (then all these params properties will be undefined) OR there's a related soft navigation that's already completed.
|
|
198
|
+
// The old spa does not look up completed interactions at all, so there's no need to consider it.
|
|
199
|
+
this.#storeJserrorForHarvest(jsErrorEvent, params.browserInteractionId !== undefined, params._softNavAttributes);
|
|
200
|
+
}
|
|
192
201
|
}
|
|
202
|
+
|
|
203
|
+
// always add directly if scoped to a sub-entity, the other pathways above will be deterministic if the main agent should procede
|
|
204
|
+
if (targetEntityGuid) this.#storeJserrorForHarvest([...jsErrorEvent, targetEntityGuid], false, params._softNavAttributes);
|
|
193
205
|
}
|
|
194
206
|
#storeJserrorForHarvest(errorInfoArr, softNavOccurredFinished, softNavCustomAttrs = {}) {
|
|
195
|
-
let [type, bucketHash, params, newMetrics, localAttrs] = errorInfoArr;
|
|
207
|
+
let [type, bucketHash, params, newMetrics, localAttrs, targetEntityGuid] = errorInfoArr;
|
|
196
208
|
const allCustomAttrs = {};
|
|
197
209
|
if (softNavOccurredFinished) {
|
|
198
210
|
Object.entries(softNavCustomAttrs).forEach(([k, v]) => setCustom(k, v)); // when an ixn finishes, it'll include stuff in jsAttributes + attrs specific to the ixn
|
|
@@ -208,12 +220,22 @@ export class Aggregate extends AggregateBase {
|
|
|
208
220
|
|
|
209
221
|
const jsAttributesHash = stringHashCode(stringify(allCustomAttrs));
|
|
210
222
|
const aggregateHash = bucketHash + ':' + jsAttributesHash;
|
|
211
|
-
this.events.add([type, aggregateHash, params, newMetrics, allCustomAttrs]);
|
|
223
|
+
this.events.add([type, aggregateHash, params, newMetrics, allCustomAttrs], targetEntityGuid);
|
|
212
224
|
function setCustom(key, val) {
|
|
213
225
|
allCustomAttrs[key] = val && typeof val === 'object' ? stringify(val) : val;
|
|
214
226
|
}
|
|
215
227
|
}
|
|
216
228
|
|
|
229
|
+
/**
|
|
230
|
+
* If the event lacks an entityGuid (the default behavior), the main agent should capture the data. If the data is assigned to a sub-entity target
|
|
231
|
+
* the main agent should not capture events unless it is configured to do so.
|
|
232
|
+
* @param {string} entityGuid - the context object for the event
|
|
233
|
+
* @returns {boolean} - whether the main agent should capture the event to its internal target
|
|
234
|
+
*/
|
|
235
|
+
shouldAllowMainAgentToCapture(entityGuid) {
|
|
236
|
+
return !entityGuid || this.agentRef.init.api.duplicate_registered_data;
|
|
237
|
+
}
|
|
238
|
+
|
|
217
239
|
// TO-DO: Remove this function when old spa is taken out. #storeJserrorForHarvest handles the work with the softnav feature.
|
|
218
240
|
onInteractionDone(interaction, wasSaved) {
|
|
219
241
|
if (!this.bufferedErrorsUnderSpa[interaction.id] || this.blocked) return;
|
|
@@ -232,7 +254,7 @@ export class Aggregate extends AggregateBase {
|
|
|
232
254
|
var hash = wasSaved ? item[1] + interaction.root.attrs.id : item[1];
|
|
233
255
|
var jsAttributesHash = stringHashCode(stringify(allCustomAttrs));
|
|
234
256
|
var aggregateHash = hash + ':' + jsAttributesHash;
|
|
235
|
-
this.events.add([item[0], aggregateHash, params, item[3], allCustomAttrs]);
|
|
257
|
+
this.events.add([item[0], aggregateHash, params, item[3], allCustomAttrs], item[5]);
|
|
236
258
|
function setCustom([key, val]) {
|
|
237
259
|
allCustomAttrs[key] = val && typeof val === 'object' ? stringify(val) : val;
|
|
238
260
|
}
|