@newrelic/browser-agent 1.320.1-rc.0 → 1.320.1-rc.2
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/dist/cjs/common/config/runtime.js +3 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/dom/selector-path.js +1 -1
- package/dist/cjs/common/event-listener/event-listener-opts.js +1 -1
- package/dist/cjs/common/harvest/connector.js +200 -0
- package/dist/cjs/common/harvest/harvester.js +5 -8
- package/dist/cjs/common/harvest/send.js +8 -7
- package/dist/cjs/common/session/session-entity.js +1 -1
- package/dist/cjs/common/timer/interaction-timer.js +2 -2
- package/dist/cjs/common/unload/eol.js +3 -3
- package/dist/cjs/common/util/console.js +2 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/v2/constants.js +21 -0
- package/dist/cjs/common/v2/utils.js +25 -23
- package/dist/cjs/common/window/page-visibility.js +1 -1
- package/dist/cjs/common/wrap/wrap-events.js +4 -3
- package/dist/cjs/common/wrap/wrap-fetch.js +2 -2
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/common/wrap/wrap-history.js +3 -2
- package/dist/cjs/common/wrap/wrap-xhr.js +2 -2
- package/dist/cjs/features/ajax/aggregate/index.js +1 -1
- package/dist/cjs/features/generic_events/aggregate/index.js +1 -1
- package/dist/cjs/features/generic_events/instrument/index.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +5 -5
- package/dist/cjs/features/logging/instrument/index.js +1 -1
- package/dist/cjs/features/page_view_event/aggregate/index.js +2 -6
- package/dist/cjs/features/page_view_event/aggregate_v2/index.js +109 -0
- package/dist/cjs/features/page_view_event/instrument/index.js +6 -1
- package/dist/cjs/features/page_view_timing/aggregate/index.js +5 -1
- package/dist/cjs/features/session_replay/instrument/index.js +9 -0
- package/dist/cjs/features/session_replay/shared/recorder.js +2 -1
- package/dist/cjs/features/session_trace/instrument/index.js +3 -3
- package/dist/cjs/features/soft_navigations/instrument/index.js +2 -2
- package/dist/cjs/features/utils/aggregate-base.js +0 -12
- package/dist/cjs/features/utils/instrument-base.js +72 -29
- package/dist/cjs/loaders/agent.js +2 -1
- package/dist/cjs/loaders/api/consent.js +2 -2
- package/dist/cjs/loaders/api/register.js +8 -8
- package/dist/cjs/loaders/configure/configure.js +14 -0
- package/dist/cjs/loaders/features/features.js +2 -1
- package/dist/esm/common/config/runtime.js +3 -0
- 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/event-listener/event-listener-opts.js +1 -1
- package/dist/esm/common/harvest/connector.js +193 -0
- package/dist/esm/common/harvest/harvester.js +5 -8
- package/dist/esm/common/harvest/send.js +10 -9
- package/dist/esm/common/session/session-entity.js +1 -1
- package/dist/esm/common/timer/interaction-timer.js +2 -2
- package/dist/esm/common/unload/eol.js +3 -3
- package/dist/esm/common/util/console.js +2 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/v2/constants.js +15 -0
- package/dist/esm/common/v2/utils.js +24 -22
- package/dist/esm/common/window/page-visibility.js +1 -1
- package/dist/esm/common/wrap/wrap-events.js +4 -3
- package/dist/esm/common/wrap/wrap-fetch.js +2 -2
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-history.js +3 -2
- package/dist/esm/common/wrap/wrap-xhr.js +2 -2
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/generic_events/aggregate/index.js +1 -1
- package/dist/esm/features/generic_events/instrument/index.js +1 -1
- package/dist/esm/features/jserrors/aggregate/index.js +6 -6
- package/dist/esm/features/logging/instrument/index.js +1 -1
- package/dist/esm/features/page_view_event/aggregate/index.js +2 -6
- package/dist/esm/features/page_view_event/aggregate_v2/index.js +100 -0
- package/dist/esm/features/page_view_event/instrument/index.js +6 -1
- package/dist/esm/features/page_view_timing/aggregate/index.js +5 -1
- package/dist/esm/features/session_replay/instrument/index.js +9 -0
- package/dist/esm/features/session_replay/shared/recorder.js +2 -1
- package/dist/esm/features/session_trace/instrument/index.js +3 -3
- package/dist/esm/features/soft_navigations/instrument/index.js +2 -2
- package/dist/esm/features/utils/aggregate-base.js +0 -12
- package/dist/esm/features/utils/instrument-base.js +71 -28
- package/dist/esm/loaders/agent.js +2 -1
- package/dist/esm/loaders/api/consent.js +2 -2
- package/dist/esm/loaders/api/register.js +1 -1
- package/dist/esm/loaders/configure/configure.js +14 -0
- package/dist/esm/loaders/features/features.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/event-listener/event-listener-opts.d.ts +1 -1
- package/dist/types/common/harvest/connector.d.ts +6 -0
- package/dist/types/common/harvest/connector.d.ts.map +1 -0
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/harvest/send.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts +1 -1
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/console.d.ts +2 -1
- package/dist/types/common/util/console.d.ts.map +1 -1
- package/dist/types/common/v2/constants.d.ts +9 -0
- package/dist/types/common/v2/constants.d.ts.map +1 -0
- package/dist/types/common/v2/utils.d.ts +36 -11
- package/dist/types/common/v2/utils.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-events.d.ts +2 -1
- package/dist/types/common/wrap/wrap-events.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-history.d.ts +2 -1
- package/dist/types/common/wrap/wrap-history.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate_v2/index.d.ts +20 -0
- package/dist/types/features/page_view_event/aggregate_v2/index.d.ts.map +1 -0
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +0 -5
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +1 -0
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/config/runtime.js +3 -0
- package/src/common/dom/selector-path.js +1 -1
- package/src/common/event-listener/event-listener-opts.js +1 -1
- package/src/common/harvest/connector.js +168 -0
- package/src/common/harvest/harvester.js +7 -9
- package/src/common/harvest/send.js +9 -7
- package/src/common/session/session-entity.js +1 -1
- package/src/common/timer/interaction-timer.js +2 -2
- package/src/common/unload/eol.js +3 -3
- package/src/common/util/console.js +2 -1
- package/src/common/util/feature-flags.js +1 -1
- package/src/common/v2/constants.js +15 -0
- package/src/common/v2/utils.js +23 -21
- package/src/common/window/page-visibility.js +1 -1
- package/src/common/wrap/wrap-events.js +4 -3
- package/src/common/wrap/wrap-fetch.js +2 -2
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-history.js +3 -2
- package/src/common/wrap/wrap-xhr.js +2 -2
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/generic_events/aggregate/index.js +1 -1
- package/src/features/generic_events/instrument/index.js +1 -1
- package/src/features/jserrors/aggregate/index.js +6 -6
- package/src/features/logging/instrument/index.js +1 -1
- package/src/features/page_view_event/aggregate/index.js +2 -6
- package/src/features/page_view_event/aggregate_v2/index.js +97 -0
- package/src/features/page_view_event/instrument/index.js +6 -1
- package/src/features/page_view_timing/aggregate/index.js +5 -1
- package/src/features/session_replay/instrument/index.js +9 -0
- package/src/features/session_replay/shared/recorder.js +2 -1
- package/src/features/session_trace/instrument/index.js +3 -3
- package/src/features/soft_navigations/instrument/index.js +2 -2
- package/src/features/utils/aggregate-base.js +0 -12
- package/src/features/utils/instrument-base.js +71 -25
- package/src/loaders/agent.js +2 -1
- package/src/loaders/api/consent.js +2 -2
- package/src/loaders/api/register.js +1 -1
- package/src/loaders/configure/configure.js +12 -0
- package/src/loaders/features/features.js +1 -0
|
@@ -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 { Timer } from './timer'
|
|
@@ -53,7 +53,7 @@ export class InteractionTimer extends Timer {
|
|
|
53
53
|
if (state === 'hidden') this.pause()
|
|
54
54
|
// vis change --> visible is treated like a new interaction with the page
|
|
55
55
|
else this.resume()
|
|
56
|
-
}, false,
|
|
56
|
+
}, false, this.abortController?.signal)
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
package/src/common/unload/eol.js
CHANGED
|
@@ -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 { globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime'
|
|
@@ -22,9 +22,9 @@ if (isWorkerScope) {
|
|
|
22
22
|
* This is used, for example, to submit a final harvest and send all remaining data on best-effort.
|
|
23
23
|
* @param {function} cb - func to run before or during the last reliable event or time of an env's life span
|
|
24
24
|
*/
|
|
25
|
-
export function subscribeToEOL (cb
|
|
25
|
+
export function subscribeToEOL (cb) {
|
|
26
26
|
if (isBrowserScope) {
|
|
27
|
-
subscribeToVisibilityChange(cb, true
|
|
27
|
+
subscribeToVisibilityChange(cb, true) // when user switches tab or hides window, esp. mobile scenario
|
|
28
28
|
} else if (isWorkerScope) {
|
|
29
29
|
globalScope.cleanupTasks.push(cb) // close() should run these tasks before quitting thread
|
|
30
30
|
}
|
|
@@ -68,7 +68,7 @@ import { dispatchGlobalEvent } from '../dispatch/global-event'
|
|
|
68
68
|
* | 50 | Failed to connect. Cannot allow registered API. |
|
|
69
69
|
* | 51 | Container agent is not available to register with. Can not connect. |
|
|
70
70
|
* | 52 | Unexpected problem encountered. There should be at least one app for harvest! |
|
|
71
|
-
* | 53 |
|
|
71
|
+
* | 53 | Failed to parse connect response. |
|
|
72
72
|
* | 54 | An experimental feature is being used. Support can not be offered for issues. |
|
|
73
73
|
* | 55 | Register API has been disabled on the container agent. |
|
|
74
74
|
* | 56 | Could not find a matching entity to store data. |
|
|
@@ -94,6 +94,7 @@ import { dispatchGlobalEvent } from '../dispatch/global-event'
|
|
|
94
94
|
* | 76 | Agent rejected post message, could not match with existing entity. |
|
|
95
95
|
* | 77 | Agent rejected post message, could not validate origin. |
|
|
96
96
|
* | 78 | RegisteredIframeEntity could not determine parent origin and will not register, to avoid trusting messages from any origin. |
|
|
97
|
+
* | 79 | Unable to initialize Connector and/or Harvester. |
|
|
97
98
|
*
|
|
98
99
|
* @param {number} code The warning code to emit, which will be used to link to the warning code documentation
|
|
99
100
|
* @param {*} [secondary] Secondary data to include, usually an extra message, error or object
|
|
@@ -19,7 +19,7 @@ export function activateFeatures (flags, agentRef) {
|
|
|
19
19
|
// let any window level subscribers know that the agent is running, per install docs
|
|
20
20
|
dispatchGlobalEvent({
|
|
21
21
|
loaded: true,
|
|
22
|
-
drained:
|
|
22
|
+
drained: !agentRef.init.feature_flags.includes('rum_v2'), // v2 RUM always call activateFeatures before any group is drained (in waitForFlags)
|
|
23
23
|
type: 'lifecycle',
|
|
24
24
|
name: 'load',
|
|
25
25
|
feature: undefined,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @enum {string}
|
|
8
|
+
* @readonly
|
|
9
|
+
*/
|
|
10
|
+
export const V2_TYPES = {
|
|
11
|
+
/** Micro Frontend */
|
|
12
|
+
MFE: 'MFE',
|
|
13
|
+
/** Browser Application */
|
|
14
|
+
BA: 'BA'
|
|
15
|
+
}
|
package/src/common/v2/utils.js
CHANGED
|
@@ -4,16 +4,23 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { extractUrlsFromStack, getDeepStackTrace } from './script-tracker'
|
|
7
|
+
import { V2_TYPES } from './constants'
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
10
|
+
* @typedef {Object} V2Target
|
|
11
|
+
* @property {'BA'} type always V2_TYPES.BA -- identifies this as the container (main) agent, not a registered MFE
|
|
12
|
+
* @property {string} instance the container agent's agentIdentifier
|
|
13
|
+
* @property {string} [id] the container agent's entity guid, once known (getter, resolved asynchronously)
|
|
14
|
+
* @property {{[key:string]: any}} attributes the V2 payload attributes for the container agent (getter)
|
|
11
15
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Determines if a given target represents a registered MFE (as opposed to the container agent).
|
|
19
|
+
* @param {*} target the target to check
|
|
20
|
+
* @returns {boolean} true if the target is a registered MFE target
|
|
21
|
+
*/
|
|
22
|
+
export function isMfeTarget (target) {
|
|
23
|
+
return target?.type === V2_TYPES.MFE
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
/**
|
|
@@ -114,14 +121,8 @@ export function dedupeRegisteredEntitiesByAsset (entities) {
|
|
|
114
121
|
*/
|
|
115
122
|
export function getVersion2Attributes (target, aggregateInstance) {
|
|
116
123
|
if (!supportsV2(aggregateInstance)) return {}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!target) {
|
|
120
|
-
return {
|
|
121
|
-
'entity.guid': containerAgentEntityGuid,
|
|
122
|
-
appId: aggregateInstance.agentRef.info.applicationID
|
|
123
|
-
}
|
|
124
|
-
}
|
|
124
|
+
/** if the target isn't a registered MFE, but we are in v2 mode, this means the data belongs to the container agent */
|
|
125
|
+
if (!isMfeTarget(target)) return aggregateInstance.agentRef.runtime.v2Target.attributes
|
|
125
126
|
/** otherwise, the data belongs to the target (MFE) and should be attributed as such */
|
|
126
127
|
return target.attributes
|
|
127
128
|
}
|
|
@@ -147,16 +148,17 @@ export function getVersion2DuplicationAttributes (target, aggregateInstance) {
|
|
|
147
148
|
* @returns {boolean} returns true if the event should be duplicated for the target, false otherwise
|
|
148
149
|
*/
|
|
149
150
|
export function shouldDuplicate (target, aggregateInstance) {
|
|
150
|
-
return
|
|
151
|
+
return isMfeTarget(target) && !!supportsV2(aggregateInstance) && aggregateInstance.agentRef.init.api.register.duplicate_data_to_container
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
/**
|
|
154
155
|
* Finds the registered targets from the stack trace for a given agent reference.
|
|
155
156
|
* @param {*} agentRef The agent reference to use for finding targets.
|
|
156
|
-
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array
|
|
157
|
+
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array containing the container target.
|
|
157
158
|
*/
|
|
158
159
|
export function findTargetsFromStackTrace (agentRef) {
|
|
159
|
-
if (!
|
|
160
|
+
if (!agentRef?.runtime) return []
|
|
161
|
+
if (!isValid(true, agentRef) || !agentRef.runtime.registeredEntities?.length) return [agentRef.runtime.v2Target]
|
|
160
162
|
|
|
161
163
|
const targets = []
|
|
162
164
|
try {
|
|
@@ -170,15 +172,15 @@ export function findTargetsFromStackTrace (agentRef) {
|
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
const deduped = dedupeTargetsByInstance(targets)
|
|
173
|
-
if (!deduped.length) deduped.push(
|
|
175
|
+
if (!deduped.length) deduped.push(agentRef.runtime.v2Target) // if we can't find any targets from the stack trace, the container agent is the target
|
|
174
176
|
return deduped
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
/**
|
|
178
180
|
* Removes duplicate targets from an array, keyed by `target.instance`. This guards against the same canonical
|
|
179
181
|
* target re-entering the array via multiple matched stack-frame URLs (e.g. a recursive call whose stack contains the
|
|
180
|
-
* same file at multiple depths).
|
|
181
|
-
* naturally collapse to a single entry too, which is the desired behavior.
|
|
182
|
+
* same file at multiple depths). Multiple container-target entries (whose `instance` is the container agent's stable
|
|
183
|
+
* `agentIdentifier`) naturally collapse to a single entry too, which is the desired behavior.
|
|
182
184
|
* @param {Array} targets
|
|
183
185
|
* @returns {Array} deduped list of targets, preserving relative order of first occurrence
|
|
184
186
|
*/
|
|
@@ -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
|
|
|
@@ -24,16 +24,17 @@ const flag = `nr@wrapped:${contextId}`
|
|
|
24
24
|
* `document` (if in a browser scope). Adds custom events in context of a new emitter scoped only to these methods.
|
|
25
25
|
* @param {Object} sharedEE - The shared event emitter on which a new scoped
|
|
26
26
|
* event emitter will be based.
|
|
27
|
+
* @param {*} [agentRef] - The agent reference, used to attribute wrapped calls to the correct v2 target.
|
|
27
28
|
* @returns {Object} Scoped event emitter with a debug ID of `events`.
|
|
28
29
|
*/
|
|
29
|
-
export function wrapEvents (sharedEE) {
|
|
30
|
+
export function wrapEvents (sharedEE, agentRef) {
|
|
30
31
|
var ee = scopedEE(sharedEE)
|
|
31
32
|
|
|
32
33
|
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
33
34
|
// then we increment the count to track # of feats using this at runtime.
|
|
34
35
|
if (wrapped[ee.debugId]++) return ee
|
|
35
36
|
wrapped[ee.debugId] = 1 // otherwise, first feature to wrap events
|
|
36
|
-
var wrapFn = wfn(ee, true)
|
|
37
|
+
var wrapFn = wfn(ee, true, agentRef)
|
|
37
38
|
|
|
38
39
|
// Guard against instrumenting environments w/o necessary features
|
|
39
40
|
if ('getPrototypeOf' in Object) {
|
|
@@ -47,8 +47,8 @@ export function wrapFetch (sharedEE, agentRef) {
|
|
|
47
47
|
|
|
48
48
|
ee.on(prefix + 'end', function (err, res, targets) {
|
|
49
49
|
var ctx = this
|
|
50
|
-
//
|
|
51
|
-
ctx.targets = targets || [
|
|
50
|
+
// default target reports to container
|
|
51
|
+
ctx.targets = targets || [agentRef.runtime.v2Target]
|
|
52
52
|
if (res) {
|
|
53
53
|
var size = res.headers.get('content-length')
|
|
54
54
|
if (size !== null) {
|
|
@@ -88,7 +88,7 @@ export function createWrapperWithEmitter (emitter, always, agentRef) {
|
|
|
88
88
|
|
|
89
89
|
// certain wrappers can inform the function wrapper to evaluate the stack of the executed wrapped function to find targets of the execution
|
|
90
90
|
// (e.g. wrap-logger can inform this method to find try to find the MFE source of a console.log)
|
|
91
|
-
targets = evaluateStack ? findTargetsFromStackTrace(agentRef) : [
|
|
91
|
+
targets = evaluateStack ? findTargetsFromStackTrace(agentRef) : [agentRef?.runtime?.v2Target] // default target always maps to the container agent
|
|
92
92
|
|
|
93
93
|
if (typeof getContext === 'function') {
|
|
94
94
|
ctx = getContext(args, originalThis)
|
|
@@ -18,9 +18,10 @@ const HISTORY_FNS = ['pushState', 'replaceState']
|
|
|
18
18
|
* Wraps the `pushState` and `replaceState` methods of `window.history` and returns a corresponding event emitter
|
|
19
19
|
* scoped to the history object.
|
|
20
20
|
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
21
|
+
* @param {*} [agentRef] - The agent reference, used to attribute wrapped calls to the correct v2 target.
|
|
21
22
|
* @returns {Object} Scoped event emitter with a debug ID of `history`.
|
|
22
23
|
*/
|
|
23
|
-
export function wrapHistory (sharedEE) {
|
|
24
|
+
export function wrapHistory (sharedEE, agentRef) {
|
|
24
25
|
const ee = scopedEE(sharedEE)
|
|
25
26
|
|
|
26
27
|
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
@@ -29,7 +30,7 @@ export function wrapHistory (sharedEE) {
|
|
|
29
30
|
if (!isBrowserScope || wrapped[ee.debugId]++) return ee
|
|
30
31
|
wrapped[ee.debugId] = 1 // otherwise, first feature to wrap history
|
|
31
32
|
|
|
32
|
-
var wrapFn = wfn(ee)
|
|
33
|
+
var wrapFn = wfn(ee, undefined, agentRef)
|
|
33
34
|
/*
|
|
34
35
|
* For objects that will be instantiated more than once, we wrap the object's prototype methods. The history object
|
|
35
36
|
* is instantiated only once, so we can wrap its methods directly--and we must wrap the history methods directly as
|
|
@@ -37,8 +37,8 @@ export function wrapXhr (sharedEE, agentRef) {
|
|
|
37
37
|
if (wrapped[ee.debugId]++) return ee
|
|
38
38
|
wrapped[ee.debugId] = 1 // otherwise, first feature to wrap XHR
|
|
39
39
|
|
|
40
|
-
wrapEvents(baseEE) // wrap-events patches XMLHttpRequest.prototype.addEventListener for us
|
|
41
|
-
var wrapFn = wfn(ee)
|
|
40
|
+
wrapEvents(baseEE, agentRef) // wrap-events patches XMLHttpRequest.prototype.addEventListener for us
|
|
41
|
+
var wrapFn = wfn(ee, undefined, agentRef)
|
|
42
42
|
|
|
43
43
|
var OrigXHR = globalScope.XMLHttpRequest
|
|
44
44
|
var MutationObserver = globalScope.MutationObserver
|
|
@@ -14,7 +14,7 @@ import { gosNREUMOriginals } from '../../../common/window/nreum'
|
|
|
14
14
|
import { hasGQLErrors, parseGQL } from './gql'
|
|
15
15
|
import { canCapturePayload, isLikelyHumanReadable, parseQueryString, createStringAdders } from '../../../common/payloads/payloads'
|
|
16
16
|
import { Obfuscator } from '../../../common/util/obfuscate'
|
|
17
|
-
import { getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate } from '../../../common/v2/utils'
|
|
17
|
+
import { getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate, isMfeTarget } from '../../../common/v2/utils'
|
|
18
18
|
import { EVENT_TYPES } from '../../../common/constants/events'
|
|
19
19
|
import { generateUuid } from '../../../common/ids/unique-id'
|
|
20
20
|
|
|
@@ -137,7 +137,7 @@ export class Aggregate extends AggregateBase {
|
|
|
137
137
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', stringify(event.gql).length)
|
|
138
138
|
|
|
139
139
|
/** make a copy of the event for the MFE target if it exists */
|
|
140
|
-
if (target) {
|
|
140
|
+
if (isMfeTarget(target)) {
|
|
141
141
|
this.events.add({ ...event, targetAttributes: getVersion2Attributes(target, this) })
|
|
142
142
|
if (shouldDuplicate(target, this)) this.reportContainerEvent({ ...event, targetAttributes: getVersion2DuplicationAttributes(target, this) }, ctx)
|
|
143
143
|
} else {
|
|
@@ -252,7 +252,7 @@ export class Aggregate extends AggregateBase {
|
|
|
252
252
|
}, this.featureName, this.ee)
|
|
253
253
|
|
|
254
254
|
if (agentRef.init.feature_flags.includes('websockets') || agentRef.init.web_sockets?.enabled) {
|
|
255
|
-
registerHandler('ws-complete', (nrData, targets = [
|
|
255
|
+
registerHandler('ws-complete', (nrData, targets = [agentRef.runtime.v2Target]) => {
|
|
256
256
|
targets.forEach(target => {
|
|
257
257
|
const event = {
|
|
258
258
|
...nrData,
|
|
@@ -68,7 +68,7 @@ export class Instrument extends InstrumentBase {
|
|
|
68
68
|
if (isBrowserScope) {
|
|
69
69
|
wrapFetch(this.ee, agentRef)
|
|
70
70
|
wrapXhr(this.ee, agentRef)
|
|
71
|
-
historyEE = wrapHistory(this.ee)
|
|
71
|
+
historyEE = wrapHistory(this.ee, agentRef)
|
|
72
72
|
|
|
73
73
|
if (agentRef.init.user_actions.enabled) {
|
|
74
74
|
OBSERVED_EVENTS.forEach(eventType =>
|
|
@@ -19,7 +19,7 @@ import { AggregateBase } from '../../utils/aggregate-base'
|
|
|
19
19
|
import { now } from '../../../common/timing/now'
|
|
20
20
|
import { Obfuscator } from '../../../common/util/obfuscate'
|
|
21
21
|
import { evaluateInternalError } from './internal-errors'
|
|
22
|
-
import { getRegisteredTargetsFromFilename, getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate } from '../../../common/v2/utils'
|
|
22
|
+
import { getRegisteredTargetsFromFilename, getVersion2Attributes, getVersion2DuplicationAttributes, shouldDuplicate, isMfeTarget } from '../../../common/v2/utils'
|
|
23
23
|
import { buildCauseString } from './cause-string'
|
|
24
24
|
import { ShortCircuit } from '../../../common/util/short-circuit'
|
|
25
25
|
import { EVENT_TYPES } from '../../../common/constants/events'
|
|
@@ -209,7 +209,7 @@ export class Aggregate extends AggregateBase {
|
|
|
209
209
|
if (targets.length) break
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
-
if (!targets.length) targets.push(
|
|
212
|
+
if (!targets.length) targets.push(this.agentRef.runtime.v2Target)
|
|
213
213
|
}
|
|
214
214
|
return targets
|
|
215
215
|
}
|
|
@@ -253,7 +253,7 @@ export class Aggregate extends AggregateBase {
|
|
|
253
253
|
if (filterOutput?.group) params.errorGroup = filterOutput.group
|
|
254
254
|
|
|
255
255
|
// Should only decorate "hasReplay" for the container agent, so check if the target matches the config
|
|
256
|
-
if (hasReplay && !target) params.hasReplay = hasReplay
|
|
256
|
+
if (hasReplay && !isMfeTarget(target)) params.hasReplay = hasReplay
|
|
257
257
|
/**
|
|
258
258
|
* The bucketHash is different from the params.stackHash because the params.stackHash is based on the canonicalized
|
|
259
259
|
* stack trace and is used downstream in NR1 to attempt to group the same errors across different browsers. However,
|
|
@@ -289,7 +289,7 @@ export class Aggregate extends AggregateBase {
|
|
|
289
289
|
|
|
290
290
|
// Trace sends the error in its payload, and both trace & replay simply listens for any error to occur.
|
|
291
291
|
const jsErrorEvent = [type, bucketHash, params, newMetrics, customAttributes]
|
|
292
|
-
if (!target) handle('trace-jserror', jsErrorEvent, undefined, FEATURE_NAMES.sessionTrace, this.ee)
|
|
292
|
+
if (!isMfeTarget(target)) handle('trace-jserror', jsErrorEvent, undefined, FEATURE_NAMES.sessionTrace, this.ee)
|
|
293
293
|
// still send EE events for other features such as above, but stop this one from aggregating internal data
|
|
294
294
|
if (this.blocked) return
|
|
295
295
|
|
|
@@ -297,7 +297,7 @@ export class Aggregate extends AggregateBase {
|
|
|
297
297
|
customAttributes.socketId = err.__newrelic.socketId
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
if (!target) {
|
|
300
|
+
if (!isMfeTarget(target)) {
|
|
301
301
|
const softNavInUse = Boolean(this.agentRef.features?.[FEATURE_NAMES.softNav])
|
|
302
302
|
if (softNavInUse) { // pass the error to soft nav for evaluation - it will return it via 'returnJserror' when interaction is resolved
|
|
303
303
|
handle('jserror', [jsErrorEvent], undefined, FEATURE_NAMES.softNav, this.ee)
|
|
@@ -307,7 +307,7 @@ export class Aggregate extends AggregateBase {
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
// always add directly if scoped to a sub-entity, the other pathways above will be deterministic if the main agent should procede
|
|
310
|
-
if (target) this.#storeJserrorForHarvest(jsErrorEvent, {}, target)
|
|
310
|
+
if (isMfeTarget(target)) this.#storeJserrorForHarvest(jsErrorEvent, {}, target)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
/**
|
|
@@ -31,7 +31,7 @@ export class Instrument extends InstrumentBase {
|
|
|
31
31
|
})
|
|
32
32
|
|
|
33
33
|
/** emitted by wrap-logger function */
|
|
34
|
-
this.ee.on('wrap-logger-end', function handleLog ([message], _, __, targets = []) {
|
|
34
|
+
this.ee.on('wrap-logger-end', function handleLog ([message], _, __, targets = [agentRef.runtime.v2Target]) {
|
|
35
35
|
const { level, customAttributes, autoCaptured } = this
|
|
36
36
|
targets.forEach(target => {
|
|
37
37
|
bufferLog(instanceEE, message, customAttributes, level, autoCaptured, target)
|
|
@@ -132,9 +132,7 @@ export class Aggregate extends AggregateBase {
|
|
|
132
132
|
}
|
|
133
133
|
this.events.add(body)
|
|
134
134
|
|
|
135
|
-
if (this.agentRef.runtime.harvester.triggerHarvestFor(this
|
|
136
|
-
sendEmptyBody: true
|
|
137
|
-
}).ranSend) this.sentRum = true
|
|
135
|
+
if (this.agentRef.runtime.harvester.triggerHarvestFor(this).ranSend) this.sentRum = true
|
|
138
136
|
}
|
|
139
137
|
|
|
140
138
|
serializer (eventBuffer) { // this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
|
|
@@ -162,9 +160,7 @@ export class Aggregate extends AggregateBase {
|
|
|
162
160
|
super.postHarvestCleanup({ sent, retry: retry && !hasCachedRumResponse }) // this will set isRetrying & re-buffer the body if request is to be retried
|
|
163
161
|
|
|
164
162
|
if (this.isRetrying && this.retries++ < 1) { // Only retry once
|
|
165
|
-
setTimeout(() => this.agentRef.runtime.harvester.triggerHarvestFor(this,
|
|
166
|
-
sendEmptyBody: true
|
|
167
|
-
}), 5000) // Retry sending the RUM event after 5 seconds
|
|
163
|
+
setTimeout(() => this.agentRef.runtime.harvester.triggerHarvestFor(this), 5000) // Retry sending the RUM event after 5 seconds
|
|
168
164
|
return
|
|
169
165
|
}
|
|
170
166
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { globalScope, isBrowserScope, originTime, getNavigationEntry } from '../../../common/constants/runtime'
|
|
6
|
+
import { addPT, addPN } from '../../../common/timing/nav-timing'
|
|
7
|
+
import { stringify } from '../../../common/util/stringify'
|
|
8
|
+
import * as CONSTANTS from '../constants'
|
|
9
|
+
import { getActivatedFeaturesFlags } from '../aggregate/initialized-features'
|
|
10
|
+
import { AggregateBase } from '../../utils/aggregate-base'
|
|
11
|
+
import { firstContentfulPaint } from '../../../common/vitals/first-contentful-paint'
|
|
12
|
+
import { firstPaint } from '../../../common/vitals/first-paint'
|
|
13
|
+
import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte'
|
|
14
|
+
import { Obfuscator } from '../../../common/util/obfuscate'
|
|
15
|
+
import { webdriverDetected } from '../../../common/util/webdriver-detection'
|
|
16
|
+
import { EVENT_TYPES } from '../../../common/constants/events'
|
|
17
|
+
|
|
18
|
+
export class Aggregate extends AggregateBase {
|
|
19
|
+
static featureName = CONSTANTS.FEATURE_NAME
|
|
20
|
+
|
|
21
|
+
#timeToFirstByte = 0
|
|
22
|
+
#firstByteToWindowLoad = 0 // our "frontend" duration
|
|
23
|
+
#firstByteToDomContent = 0 // our "dom processing" duration
|
|
24
|
+
#obfuscator
|
|
25
|
+
|
|
26
|
+
constructor (agentRef) {
|
|
27
|
+
super(agentRef, CONSTANTS.FEATURE_NAME)
|
|
28
|
+
this.#obfuscator = new Obfuscator(agentRef, EVENT_TYPES.PVE)
|
|
29
|
+
|
|
30
|
+
if (isBrowserScope) {
|
|
31
|
+
timeToFirstByte.subscribe(({ value, attrs }) => {
|
|
32
|
+
const navEntry = attrs.navigationEntry
|
|
33
|
+
this.#timeToFirstByte = Math.max(value, this.#timeToFirstByte)
|
|
34
|
+
this.#firstByteToWindowLoad = Math.max(Math.round(navEntry.loadEventEnd - this.#timeToFirstByte), this.#firstByteToWindowLoad) // our "frontend" duration
|
|
35
|
+
this.#firstByteToDomContent = Math.max(Math.round(navEntry.domContentLoadedEventEnd - this.#timeToFirstByte), this.#firstByteToDomContent) // our "dom processing" duration
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.waitForFlags(([])).then(() => {
|
|
40
|
+
const body = this.#obfuscator.traverseAndObfuscateEvents({ ja: { ...agentRef.info.jsAttributes, webdriverDetected } })
|
|
41
|
+
this.events.add(body)
|
|
42
|
+
this.drain()
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
queryStringsBuilder () {
|
|
47
|
+
const info = this.agentRef.info
|
|
48
|
+
const measures = {}
|
|
49
|
+
|
|
50
|
+
if (info.queueTime) measures.qt = info.queueTime
|
|
51
|
+
if (info.applicationTime) measures.ap = info.applicationTime
|
|
52
|
+
|
|
53
|
+
// These 3 values should've been recorded after load and before this func runs. They are part of the minimum required for PageView events to be created.
|
|
54
|
+
// Following PR #428, which demands that the BA must drive entity indexing, these need to be sent even outside of the main window context where PerformanceTiming
|
|
55
|
+
// or PerformanceNavigationTiming do not exists. Hence, they'll be filled in by 0s instead in, for example, worker threads that still init the PVE module.
|
|
56
|
+
measures.be = this.#timeToFirstByte
|
|
57
|
+
measures.fe = this.#firstByteToWindowLoad
|
|
58
|
+
measures.dc = this.#firstByteToDomContent
|
|
59
|
+
|
|
60
|
+
const queryParameters = {
|
|
61
|
+
at: info.atts,
|
|
62
|
+
af: getActivatedFeaturesFlags(this.agentRef).join(','),
|
|
63
|
+
igp: this.agentRef.runtime.appMetadata.igp,
|
|
64
|
+
...measures,
|
|
65
|
+
fp: firstPaint.current.value,
|
|
66
|
+
fcp: firstContentfulPaint.current.value
|
|
67
|
+
}
|
|
68
|
+
if (globalScope.performance) {
|
|
69
|
+
const navTimingEntry = getNavigationEntry()
|
|
70
|
+
if (navTimingEntry) { // Navigation Timing level 2 API that replaced PerformanceTiming & PerformanceNavigation
|
|
71
|
+
const perf = ({
|
|
72
|
+
timing: addPT(originTime, navTimingEntry, {}),
|
|
73
|
+
navigation: addPN(navTimingEntry, {})
|
|
74
|
+
})
|
|
75
|
+
queryParameters.perf = stringify(perf)
|
|
76
|
+
} else if (typeof PerformanceTiming !== 'undefined') { // Modern Safari iFrames and Safari pre-15 do not support level 2 timing.
|
|
77
|
+
const perf = ({
|
|
78
|
+
timing: addPT(originTime, globalScope.performance.timing, {}, true),
|
|
79
|
+
navigation: addPN(globalScope.performance.navigation, {})
|
|
80
|
+
})
|
|
81
|
+
queryParameters.perf = stringify(perf)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const { correctedOriginTime } = this.agentRef.runtime.timeKeeper
|
|
85
|
+
if (correctedOriginTime) queryParameters.timestamp = correctedOriginTime // a "PageView" is set to represent the page's (server adjusted) origin time rather than when event is recorded/harvested
|
|
86
|
+
|
|
87
|
+
return queryParameters
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get harvestEndpointVersion () {
|
|
91
|
+
return 2
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
serializer (eventBuffer) { // this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
|
|
95
|
+
return eventBuffer[0]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -20,7 +20,12 @@ export class Instrument extends InstrumentBase {
|
|
|
20
20
|
/** feature specific APIs */
|
|
21
21
|
setupSetPageViewNameAPI(agentRef)
|
|
22
22
|
|
|
23
|
-
this.importAggregator(agentRef, () =>
|
|
23
|
+
this.importAggregator(agentRef, () => {
|
|
24
|
+
if (agentRef.init.feature_flags.includes('rum_v2')) {
|
|
25
|
+
return import(/* webpackChunkName: "page_view_event-aggregate" */ '../aggregate_v2')
|
|
26
|
+
}
|
|
27
|
+
return import(/* webpackChunkName: "page_view_event-aggregate" */ '../aggregate')
|
|
28
|
+
})
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
setupInspectionEvents () {
|
|
@@ -59,7 +59,11 @@ export class Aggregate extends AggregateBase {
|
|
|
59
59
|
const { name, value, attrs } = cumulativeLayoutShift.current
|
|
60
60
|
if (value === undefined) return
|
|
61
61
|
this.addTiming(name, value * 1000, attrs)
|
|
62
|
-
}, true, true) // CLS node should only
|
|
62
|
+
}, true, true) // CLS node should only report on vis change rather than on every change.
|
|
63
|
+
/* NOTE: the capture=true is required -- empirically verified against a real browser (Chrome) for CLS
|
|
64
|
+
timing node to reliably be in the same final harvest as the rest, alongside Harvester#startTimer's
|
|
65
|
+
queueMicrotask deferral of the EOL harvest itself. Dropping this flag caused CLS to be split into its own,
|
|
66
|
+
separate, later harvest instead of going out together with pageHide/INP. */
|
|
63
67
|
|
|
64
68
|
this.drain()
|
|
65
69
|
})
|
|
@@ -46,6 +46,10 @@ export class Instrument extends InstrumentBase {
|
|
|
46
46
|
}) // could handle specific fail-state behaviors with a .catch block here
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// If the aggregate never successfully loads (missing session prerequisite, or the aggregate module itself
|
|
50
|
+
// fails to import/construct), any preload recording that already started needs to be stopped.
|
|
51
|
+
this.abortHandler = this.#abort
|
|
52
|
+
|
|
49
53
|
this.importAggregator(this.agentRef, () => import(/* webpackChunkName: "session_replay-aggregate" */ '../aggregate'), this)
|
|
50
54
|
|
|
51
55
|
/** If the recorder is running, we can pass error events on to the agg to help it switch to full mode later */
|
|
@@ -109,6 +113,11 @@ export class Instrument extends InstrumentBase {
|
|
|
109
113
|
}) // could handle specific fail-state behaviors with a .catch block here
|
|
110
114
|
}
|
|
111
115
|
}
|
|
116
|
+
|
|
117
|
+
/** Stops any preload recording that already started if the aggregate never ends up successfully loading. */
|
|
118
|
+
#abort () {
|
|
119
|
+
this.recorder?.stopRecording()
|
|
120
|
+
}
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
export const SessionReplay = Instrument
|
|
@@ -204,7 +204,8 @@ export class Recorder {
|
|
|
204
204
|
|
|
205
205
|
// We are making an effort to try to keep payloads manageable for unloading. If they reach the unload limit before their interval,
|
|
206
206
|
// it will send immediately. This often happens on the first snapshot, which can be significantly larger than the other payloads.
|
|
207
|
-
|
|
207
|
+
// (the aggregate may not exist yet/at all if its own bootstrap hasn't finished or failed -- nothing to harvest for in that case.)
|
|
208
|
+
if (((this.events.hasSnapshot && this.events.hasMeta) || payloadSize > IDEAL_PAYLOAD_SIZE) && !this.isErrorMode && this.srInstrument.featAggregate) {
|
|
208
209
|
// if we've made it to the ideal size of ~16kb before the interval timer, we should send early.
|
|
209
210
|
this.agentRef.runtime.harvester.triggerHarvestFor(this.srInstrument.featAggregate)
|
|
210
211
|
}
|
|
@@ -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 { handle } from '../../../common/event-emitter/handle'
|
|
@@ -33,8 +33,8 @@ export class Instrument extends InstrumentBase {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const thisInstrumentEE = this.ee
|
|
36
|
-
wrapHistory(thisInstrumentEE)
|
|
37
|
-
this.eventsEE = wrapEvents(thisInstrumentEE)
|
|
36
|
+
wrapHistory(thisInstrumentEE, agentRef)
|
|
37
|
+
this.eventsEE = wrapEvents(thisInstrumentEE, agentRef)
|
|
38
38
|
|
|
39
39
|
this.eventsEE.on(FN_START, function (args, target) {
|
|
40
40
|
this.bstStart = now()
|
|
@@ -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 { gosNREUMOriginals } from '../../../common/window/nreum'
|
|
@@ -30,7 +30,7 @@ export class Instrument extends InstrumentBase {
|
|
|
30
30
|
|
|
31
31
|
if (!isBrowserScope || !gosNREUMOriginals().o.MO) return // soft navigations is not supported outside web env or browsers without the mutation observer API
|
|
32
32
|
|
|
33
|
-
const historyEE = wrapHistory(this.ee)
|
|
33
|
+
const historyEE = wrapHistory(this.ee, agentRef)
|
|
34
34
|
try {
|
|
35
35
|
this.removeOnAbort = new AbortController()
|
|
36
36
|
} catch (e) {}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { FeatureBase } from './feature-base'
|
|
6
6
|
import { drain } from '../../common/drain/drain'
|
|
7
7
|
import { FEATURE_NAMES } from '../../loaders/features/features'
|
|
8
|
-
import { Harvester } from '../../common/harvest/harvester'
|
|
9
8
|
import { EventBuffer } from './event-buffer'
|
|
10
9
|
import { handle } from '../../common/event-emitter/handle'
|
|
11
10
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../metrics/constants'
|
|
@@ -21,7 +20,6 @@ export class AggregateBase extends FeatureBase {
|
|
|
21
20
|
*/
|
|
22
21
|
constructor (agentRef, featureName) {
|
|
23
22
|
super(agentRef, featureName)
|
|
24
|
-
this.doOnceForAllAggregate(agentRef)
|
|
25
23
|
|
|
26
24
|
/** @type {Boolean} indicates if custom attributes are combined in each event payload for size estimation purposes. this is set to true in derived classes that need to evaluate custom attributes separately from the event payload */
|
|
27
25
|
this.customAttributesAreSeparate = false
|
|
@@ -178,16 +176,6 @@ export class AggregateBase extends FeatureBase {
|
|
|
178
176
|
this.events.clearSave(this.harvestOpts)
|
|
179
177
|
}
|
|
180
178
|
|
|
181
|
-
/**
|
|
182
|
-
* These are actions related to shared resources that should be initialized once by whichever feature Aggregate subclass loads first.
|
|
183
|
-
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
184
|
-
*/
|
|
185
|
-
doOnceForAllAggregate (agentRef) {
|
|
186
|
-
// Note: obfuscator is now created per-feature for their specific event types
|
|
187
|
-
|
|
188
|
-
if (!agentRef.runtime.harvester) agentRef.runtime.harvester = new Harvester(agentRef)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
179
|
/**
|
|
192
180
|
* Report a supportability metric
|
|
193
181
|
* @param {*} metricName The tag of the name matching the Angler aggregation tag
|