@newrelic/browser-agent 1.281.0 → 1.283.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 +15 -0
- package/README.md +17 -0
- package/dist/cjs/common/config/info.js +21 -0
- package/dist/cjs/common/config/init.js +88 -20
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/session/session-entity.js +2 -0
- package/dist/cjs/common/wrap/wrap-function.js +1 -0
- package/dist/cjs/common/wrap/wrap-websocket.js +23 -39
- package/dist/cjs/features/logging/aggregate/index.js +52 -3
- package/dist/cjs/features/logging/constants.js +9 -1
- package/dist/cjs/features/logging/instrument/index.js +20 -0
- package/dist/cjs/features/metrics/aggregate/index.js +7 -9
- package/dist/cjs/features/metrics/constants.js +3 -5
- package/dist/cjs/features/metrics/instrument/index.js +8 -11
- package/dist/cjs/features/session_replay/aggregate/index.js +7 -3
- package/dist/cjs/features/utils/aggregate-base.js +3 -0
- package/dist/cjs/loaders/agent.js +12 -1
- package/dist/cjs/loaders/browser-agent.js +5 -2
- package/dist/cjs/loaders/micro-agent.js +1 -1
- package/dist/esm/common/config/info.js +22 -0
- package/dist/esm/common/config/init.js +86 -17
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/session/session-entity.js +2 -0
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-websocket.js +23 -39
- package/dist/esm/features/logging/aggregate/index.js +53 -4
- package/dist/esm/features/logging/constants.js +8 -0
- package/dist/esm/features/logging/instrument/index.js +20 -0
- package/dist/esm/features/metrics/aggregate/index.js +8 -10
- package/dist/esm/features/metrics/constants.js +2 -3
- package/dist/esm/features/metrics/instrument/index.js +9 -11
- package/dist/esm/features/session_replay/aggregate/index.js +7 -3
- package/dist/esm/features/utils/aggregate-base.js +3 -0
- package/dist/esm/loaders/agent.js +12 -1
- package/dist/esm/loaders/browser-agent.js +5 -2
- package/dist/esm/loaders/micro-agent.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/common/aggregate/event-aggregator.d.ts +1 -3
- package/dist/types/common/aggregate/event-aggregator.d.ts.map +1 -1
- package/dist/types/common/config/info.d.ts +31 -0
- package/dist/types/common/config/info.d.ts.map +1 -1
- package/dist/types/common/config/init.d.ts +262 -0
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/constants/agent-constants.d.ts.map +1 -1
- package/dist/types/common/constants/env.cdn.d.ts.map +1 -1
- package/dist/types/common/constants/env.d.ts.map +1 -1
- package/dist/types/common/constants/env.npm.d.ts.map +1 -1
- package/dist/types/common/session/constants.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/url/clean-url.d.ts +1 -1
- package/dist/types/common/url/clean-url.d.ts.map +1 -1
- package/dist/types/common/util/traverse.d.ts +1 -1
- package/dist/types/common/util/traverse.d.ts.map +1 -1
- package/dist/types/common/window/page-visibility.d.ts +1 -1
- package/dist/types/common/window/page-visibility.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-function.d.ts +11 -1
- package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-websocket.d.ts.map +1 -1
- package/dist/types/features/generic_events/constants.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +7 -0
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/constants.d.ts +13 -0
- package/dist/types/features/logging/constants.d.ts.map +1 -1
- package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/constants.d.ts +1 -0
- package/dist/types/features/metrics/constants.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +3 -2
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/constants.d.ts.map +1 -1
- package/dist/types/features/spa/constants.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +1 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +2 -2
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +2 -2
- package/dist/types/loaders/agent-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts +43 -3
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +0 -10
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/browser-agent.d.ts +0 -1
- package/dist/types/loaders/browser-agent.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent-base.d.ts +6 -6
- package/dist/types/loaders/micro-agent-base.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts +3 -3
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/config/info.js +22 -3
- package/src/common/config/init.js +95 -17
- package/src/common/session/session-entity.js +2 -0
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-websocket.js +24 -40
- package/src/features/logging/aggregate/index.js +57 -4
- package/src/features/logging/constants.js +9 -0
- package/src/features/logging/instrument/index.js +8 -0
- package/src/features/metrics/aggregate/index.js +8 -8
- package/src/features/metrics/constants.js +2 -2
- package/src/features/metrics/instrument/index.js +9 -9
- package/src/features/session_replay/aggregate/index.js +8 -3
- package/src/features/utils/aggregate-base.js +4 -0
- package/src/loaders/agent.js +12 -1
- package/src/loaders/browser-agent.js +5 -3
- package/src/loaders/micro-agent.js +1 -1
|
@@ -27,51 +27,35 @@ export function wrapWebSocket (sharedEE) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
class WrappedWebSocket extends WebSocket {
|
|
31
|
+
static name = 'WebSocket'
|
|
32
|
+
|
|
33
|
+
constructor (...args) {
|
|
34
|
+
super(...args)
|
|
35
|
+
const socketId = generateRandomHexString(6)
|
|
36
|
+
this.report = reporter(socketId)
|
|
37
|
+
this.report('new')
|
|
38
|
+
|
|
39
|
+
const events = ['message', 'error', 'open', 'close']
|
|
40
|
+
/** add event listeners */
|
|
41
|
+
events.forEach(evt => {
|
|
42
|
+
this.addEventListener(evt, function (e) {
|
|
43
|
+
this.report(ADD_EVENT_LISTENER_TAG, { eventType: evt, event: e })
|
|
44
|
+
})
|
|
45
45
|
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** could also observe the on-events for runtime processing, but not implemented yet */
|
|
49
|
-
|
|
50
|
-
/** observe the static method send, but noteably not close, as that is currently observed with the event listener */
|
|
51
|
-
;['send'].forEach(wrapStaticProperty)
|
|
46
|
+
}
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
report(prop, ...arguments)
|
|
61
|
-
try {
|
|
62
|
-
return originalProp.apply(this, arguments)
|
|
63
|
-
} catch (err) {
|
|
64
|
-
report(prop + '-err', ...arguments)
|
|
65
|
-
// rethrow error so we don't effect execution by observing.
|
|
66
|
-
throw err
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
ws[prop] = proxiedProp
|
|
48
|
+
send (...args) {
|
|
49
|
+
this.report('send', ...args)
|
|
50
|
+
try {
|
|
51
|
+
return super.send(...args)
|
|
52
|
+
} catch (err) {
|
|
53
|
+
this.report('send-err', ...args)
|
|
54
|
+
throw err
|
|
70
55
|
}
|
|
71
56
|
}
|
|
72
|
-
|
|
73
|
-
return ws
|
|
74
57
|
}
|
|
58
|
+
|
|
75
59
|
globalScope.WebSocket = WrappedWebSocket
|
|
76
60
|
return sharedEE
|
|
77
61
|
}
|
|
@@ -8,20 +8,47 @@ import { warn } from '../../../common/util/console'
|
|
|
8
8
|
import { stringify } from '../../../common/util/stringify'
|
|
9
9
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
|
|
10
10
|
import { AggregateBase } from '../../utils/aggregate-base'
|
|
11
|
-
import { FEATURE_NAME, LOGGING_EVENT_EMITTER_CHANNEL, LOG_LEVELS } from '../constants'
|
|
11
|
+
import { FEATURE_NAME, LOGGING_EVENT_EMITTER_CHANNEL, LOG_LEVELS, LOGGING_MODE } from '../constants'
|
|
12
12
|
import { Log } from '../shared/log'
|
|
13
13
|
import { isValidLogLevel } from '../shared/utils'
|
|
14
14
|
import { applyFnToProps } from '../../../common/util/traverse'
|
|
15
15
|
import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
|
|
16
16
|
import { FEATURE_NAMES } from '../../../loaders/features/features'
|
|
17
|
+
import { SESSION_EVENT_TYPES, SESSION_EVENTS } from '../../../common/session/constants'
|
|
18
|
+
import { ABORT_REASONS } from '../../session_replay/constants'
|
|
19
|
+
import { canEnableSessionTracking } from '../../utils/feature-gates'
|
|
17
20
|
|
|
18
21
|
export class Aggregate extends AggregateBase {
|
|
19
22
|
static featureName = FEATURE_NAME
|
|
20
23
|
constructor (agentRef) {
|
|
21
24
|
super(agentRef, FEATURE_NAME)
|
|
25
|
+
this.isSessionTrackingEnabled = canEnableSessionTracking(this.agentIdentifier) && this.agentRef.runtime.session
|
|
26
|
+
|
|
27
|
+
// The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
|
|
28
|
+
this.ee.on(SESSION_EVENTS.RESET, () => {
|
|
29
|
+
this.abort(ABORT_REASONS.RESET)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
this.ee.on(SESSION_EVENTS.UPDATE, (type, data) => {
|
|
33
|
+
if (this.blocked || type !== SESSION_EVENT_TYPES.CROSS_TAB) return
|
|
34
|
+
if (this.mode !== LOGGING_MODE.OFF && data.loggingMode === LOGGING_MODE.OFF) this.abort(ABORT_REASONS.CROSS_TAB)
|
|
35
|
+
else this.mode = data.loggingMode
|
|
36
|
+
})
|
|
37
|
+
|
|
22
38
|
this.harvestOpts.raw = true
|
|
39
|
+
this.waitForFlags(['log']).then(([loggingMode]) => {
|
|
40
|
+
const session = this.agentRef.runtime.session ?? {}
|
|
41
|
+
if (this.loggingMode === LOGGING_MODE.OFF || (session.isNew && loggingMode === LOGGING_MODE.OFF)) {
|
|
42
|
+
this.blocked = true
|
|
43
|
+
this.deregisterDrain()
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
if (session.isNew || !this.isSessionTrackingEnabled) {
|
|
47
|
+
this.updateLoggingMode(loggingMode)
|
|
48
|
+
} else {
|
|
49
|
+
this.loggingMode = session.state.loggingMode
|
|
50
|
+
}
|
|
23
51
|
|
|
24
|
-
this.waitForFlags([]).then(() => {
|
|
25
52
|
/** emitted by instrument class (wrapped loggers) or the api methods directly */
|
|
26
53
|
registerHandler(LOGGING_EVENT_EMITTER_CHANNEL, this.handleLog.bind(this), this.featureName, this.ee)
|
|
27
54
|
this.drain()
|
|
@@ -30,12 +57,20 @@ export class Aggregate extends AggregateBase {
|
|
|
30
57
|
})
|
|
31
58
|
}
|
|
32
59
|
|
|
60
|
+
updateLoggingMode (loggingMode) {
|
|
61
|
+
this.loggingMode = loggingMode
|
|
62
|
+
this.syncWithSessionManager({
|
|
63
|
+
loggingMode: this.loggingMode
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
33
67
|
handleLog (timestamp, message, attributes = {}, level = LOG_LEVELS.INFO) {
|
|
34
|
-
if (this.blocked) return
|
|
68
|
+
if (this.blocked || !this.loggingMode) return
|
|
35
69
|
|
|
36
70
|
if (!attributes || typeof attributes !== 'object') attributes = {}
|
|
37
71
|
if (typeof level === 'string') level = level.toUpperCase()
|
|
38
72
|
if (!isValidLogLevel(level)) return warn(30, level)
|
|
73
|
+
if (this.loggingMode < (LOGGING_MODE[level] || Infinity)) return
|
|
39
74
|
|
|
40
75
|
try {
|
|
41
76
|
if (typeof message !== 'string') {
|
|
@@ -99,7 +134,9 @@ export class Aggregate extends AggregateBase {
|
|
|
99
134
|
// The following 3 attributes are evaluated and dropped at ingest processing time and do not get stored on NRDB:
|
|
100
135
|
'instrumentation.provider': 'browser',
|
|
101
136
|
'instrumentation.version': this.agentRef.runtime.version,
|
|
102
|
-
'instrumentation.name': this.agentRef.runtime.loaderType
|
|
137
|
+
'instrumentation.name': this.agentRef.runtime.loaderType,
|
|
138
|
+
// Custom attributes
|
|
139
|
+
...this.agentRef.info.jsAttributes
|
|
103
140
|
}
|
|
104
141
|
},
|
|
105
142
|
/** logs section contains individual unique log entries */
|
|
@@ -113,4 +150,20 @@ export class Aggregate extends AggregateBase {
|
|
|
113
150
|
queryStringsBuilder () {
|
|
114
151
|
return { browser_monitoring_key: this.agentRef.info.licenseKey }
|
|
115
152
|
}
|
|
153
|
+
|
|
154
|
+
/** Abort the feature, once aborted it will not resume */
|
|
155
|
+
abort (reason = {}) {
|
|
156
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, [`Logging/Abort/${reason.sm}`], undefined, FEATURE_NAMES.logging, this.ee)
|
|
157
|
+
this.blocked = true
|
|
158
|
+
this.events.clear()
|
|
159
|
+
this.events.clearSave()
|
|
160
|
+
this.updateLoggingMode(LOGGING_MODE.OFF)
|
|
161
|
+
this.deregisterDrain()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
syncWithSessionManager (state = {}) {
|
|
165
|
+
if (this.isSessionTrackingEnabled) {
|
|
166
|
+
this.agentRef.runtime.session.write(state)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
116
169
|
}
|
|
@@ -12,6 +12,15 @@ export const LOG_LEVELS = {
|
|
|
12
12
|
TRACE: 'TRACE'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export const LOGGING_MODE = {
|
|
16
|
+
OFF: 0,
|
|
17
|
+
ERROR: 1,
|
|
18
|
+
WARN: 2,
|
|
19
|
+
INFO: 3,
|
|
20
|
+
DEBUG: 4,
|
|
21
|
+
TRACE: 5
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export const LOGGING_EVENT_EMITTER_CHANNEL = 'log'
|
|
16
25
|
|
|
17
26
|
export const FEATURE_NAME = FEATURE_NAMES.logging
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import { InstrumentBase } from '../../utils/instrument-base'
|
|
6
6
|
import { FEATURE_NAME } from '../constants'
|
|
7
7
|
import { bufferLog } from '../shared/utils'
|
|
8
|
+
import { wrapLogger } from '../../../common/wrap/wrap-logger'
|
|
9
|
+
import { globalScope } from '../../../common/constants/runtime'
|
|
8
10
|
|
|
9
11
|
export class Instrument extends InstrumentBase {
|
|
10
12
|
static featureName = FEATURE_NAME
|
|
@@ -12,6 +14,12 @@ export class Instrument extends InstrumentBase {
|
|
|
12
14
|
super(agentRef, FEATURE_NAME, auto)
|
|
13
15
|
|
|
14
16
|
const instanceEE = this.ee
|
|
17
|
+
wrapLogger(instanceEE, globalScope.console, 'log', { level: 'info' })
|
|
18
|
+
wrapLogger(instanceEE, globalScope.console, 'error', { level: 'error' })
|
|
19
|
+
wrapLogger(instanceEE, globalScope.console, 'warn', { level: 'warn' })
|
|
20
|
+
wrapLogger(instanceEE, globalScope.console, 'info', { level: 'info' })
|
|
21
|
+
wrapLogger(instanceEE, globalScope.console, 'debug', { level: 'debug' })
|
|
22
|
+
wrapLogger(instanceEE, globalScope.console, 'trace', { level: 'trace' })
|
|
15
23
|
/** emitted by wrap-logger function */
|
|
16
24
|
this.ee.on('wrap-logger-end', function handleLog ([message]) {
|
|
17
25
|
const { level, customAttributes } = this
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { registerHandler } from '../../../common/event-emitter/register-handler'
|
|
6
|
-
import { FEATURE_NAME, SUPPORTABILITY_METRIC, CUSTOM_METRIC, SUPPORTABILITY_METRIC_CHANNEL, CUSTOM_METRIC_CHANNEL
|
|
6
|
+
import { FEATURE_NAME, SUPPORTABILITY_METRIC, CUSTOM_METRIC, SUPPORTABILITY_METRIC_CHANNEL, CUSTOM_METRIC_CHANNEL, WATCHABLE_WEB_SOCKET_EVENTS } from '../constants'
|
|
7
7
|
import { getFrameworks } from './framework-detection'
|
|
8
8
|
import { isFileProtocol } from '../../../common/url/protocol'
|
|
9
9
|
import { onDOMContentLoaded } from '../../../common/window/load'
|
|
@@ -11,8 +11,8 @@ import { windowAddEventListener } from '../../../common/event-listener/event-lis
|
|
|
11
11
|
import { isBrowserScope, isWorkerScope } from '../../../common/constants/runtime'
|
|
12
12
|
import { AggregateBase } from '../../utils/aggregate-base'
|
|
13
13
|
import { isIFrameWindow } from '../../../common/dom/iframe'
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
import { WEBSOCKET_TAG } from '../../../common/wrap/wrap-websocket'
|
|
15
|
+
import { handleWebsocketEvents } from './websocket-detection'
|
|
16
16
|
|
|
17
17
|
export class Aggregate extends AggregateBase {
|
|
18
18
|
static featureName = FEATURE_NAME
|
|
@@ -116,11 +116,11 @@ export class Aggregate extends AggregateBase {
|
|
|
116
116
|
mo.observe(window.document.body, { childList: true, subtree: true })
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
WATCHABLE_WEB_SOCKET_EVENTS.forEach(tag => {
|
|
120
|
+
registerHandler('buffered-' + WEBSOCKET_TAG + tag, (...args) => {
|
|
121
|
+
handleWebsocketEvents(this.storeSupportabilityMetrics.bind(this), tag, ...args)
|
|
122
|
+
}, this.featureName, this.ee)
|
|
123
|
+
})
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
eachSessionChecks () {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { ADD_EVENT_LISTENER_TAG } from '../../common/wrap/wrap-websocket'
|
|
7
7
|
import { FEATURE_NAMES } from '../../loaders/features/features'
|
|
8
8
|
|
|
9
9
|
export const FEATURE_NAME = FEATURE_NAMES.metrics
|
|
@@ -12,4 +12,4 @@ export const CUSTOM_METRIC = 'cm'
|
|
|
12
12
|
export const SUPPORTABILITY_METRIC_CHANNEL = 'storeSupportabilityMetrics'
|
|
13
13
|
export const CUSTOM_METRIC_CHANNEL = 'storeEventMetrics'
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
export const WATCHABLE_WEB_SOCKET_EVENTS = ['new', 'send', 'close', ADD_EVENT_LISTENER_TAG]
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { handle } from '../../../common/event-emitter/handle'
|
|
7
|
+
import { WEBSOCKET_TAG, wrapWebSocket } from '../../../common/wrap/wrap-websocket'
|
|
8
8
|
import { InstrumentBase } from '../../utils/instrument-base'
|
|
9
|
-
import { FEATURE_NAME
|
|
9
|
+
import { FEATURE_NAME, WATCHABLE_WEB_SOCKET_EVENTS } from '../constants'
|
|
10
10
|
|
|
11
11
|
export class Instrument extends InstrumentBase {
|
|
12
12
|
static featureName = FEATURE_NAME
|
|
13
13
|
constructor (agentRef, auto = true) {
|
|
14
14
|
super(agentRef, FEATURE_NAME, auto)
|
|
15
|
-
|
|
15
|
+
wrapWebSocket(this.ee)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
WATCHABLE_WEB_SOCKET_EVENTS.forEach((suffix) => {
|
|
18
|
+
this.ee.on(WEBSOCKET_TAG + suffix, (...args) => {
|
|
19
|
+
handle('buffered-' + WEBSOCKET_TAG + suffix, [...args], undefined, this.featureName, this.ee)
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
22
|
|
|
23
23
|
this.importAggregator(agentRef)
|
|
24
24
|
}
|
|
@@ -24,6 +24,7 @@ import { now } from '../../../common/timing/now'
|
|
|
24
24
|
import { buildNRMetaNode } from '../shared/utils'
|
|
25
25
|
import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
|
|
26
26
|
import { cleanURL } from '../../../common/url/clean-url'
|
|
27
|
+
import { canEnableSessionTracking } from '../../utils/feature-gates'
|
|
27
28
|
|
|
28
29
|
export class Aggregate extends AggregateBase {
|
|
29
30
|
static featureName = FEATURE_NAME
|
|
@@ -50,6 +51,8 @@ export class Aggregate extends AggregateBase {
|
|
|
50
51
|
this.errorNoticed = args?.errorNoticed || false
|
|
51
52
|
this.harvestOpts.raw = true
|
|
52
53
|
|
|
54
|
+
this.isSessionTrackingEnabled = canEnableSessionTracking(this.agentIdentifier) && this.agentRef.runtime.session
|
|
55
|
+
|
|
53
56
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Config/SessionReplay/Enabled'], undefined, FEATURE_NAMES.metrics, this.ee)
|
|
54
57
|
|
|
55
58
|
// The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
|
|
@@ -71,7 +74,7 @@ export class Aggregate extends AggregateBase {
|
|
|
71
74
|
this.ee.on(SESSION_EVENTS.UPDATE, (type, data) => {
|
|
72
75
|
if (!this.recorder || !this.initialized || this.blocked || type !== SESSION_EVENT_TYPES.CROSS_TAB) return
|
|
73
76
|
if (this.mode !== MODE.OFF && data.sessionReplayMode === MODE.OFF) this.abort(ABORT_REASONS.CROSS_TAB)
|
|
74
|
-
this.mode = data.
|
|
77
|
+
this.mode = data.sessionReplayMode
|
|
75
78
|
})
|
|
76
79
|
|
|
77
80
|
registerHandler(SR_EVENT_EMITTER_TYPES.PAUSE, () => {
|
|
@@ -142,7 +145,7 @@ export class Aggregate extends AggregateBase {
|
|
|
142
145
|
|
|
143
146
|
/**
|
|
144
147
|
* Evaluate entitlements and sampling before starting feature mechanics, importing and configuring recording library, and setting storage state
|
|
145
|
-
* @param {boolean}
|
|
148
|
+
* @param {boolean} srMode - the true/false state of the "sr" flag (aka. entitlements) from RUM response
|
|
146
149
|
* @param {boolean} ignoreSession - whether to force the method to ignore the session state and use just the sample flags
|
|
147
150
|
* @returns {void}
|
|
148
151
|
*/
|
|
@@ -373,6 +376,8 @@ export class Aggregate extends AggregateBase {
|
|
|
373
376
|
}
|
|
374
377
|
|
|
375
378
|
syncWithSessionManager (state = {}) {
|
|
376
|
-
this.
|
|
379
|
+
if (this.isSessionTrackingEnabled) {
|
|
380
|
+
this.agentRef.runtime.session.write(state)
|
|
381
|
+
}
|
|
377
382
|
}
|
|
378
383
|
}
|
|
@@ -74,6 +74,10 @@ export class AggregateBase extends FeatureBase {
|
|
|
74
74
|
this.drained = true
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
preHarvestChecks (opts) {
|
|
78
|
+
return !this.blocked
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
/**
|
|
78
82
|
* Return harvest payload. A "serializer" function can be defined on a derived class to format the payload.
|
|
79
83
|
* @param {Boolean} shouldRetryOnFail - harvester flag to backup payload for retry later if harvest request fails; this should be moved to harvester logic
|
package/src/loaders/agent.js
CHANGED
|
@@ -19,13 +19,24 @@ import { gosNREUM, setNREUMInitializedAgent } from '../common/window/nreum'
|
|
|
19
19
|
import { warn } from '../common/util/console'
|
|
20
20
|
import { globalScope } from '../common/constants/runtime'
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {Object} AgentOptions
|
|
24
|
+
* @property {import('../common/config/info').Info} info - An object containing operational info needed by the agent. It's strongly encouraged to define this.
|
|
25
|
+
* @property {import('../common/config/init').Init} [init] - An object containing initialization configurations for the agent.
|
|
26
|
+
* @property {Object} [loader_config] - An object containing configuration primarily passed by APM injection. This is not recommended for use if not already provided by installation.
|
|
27
|
+
* @property {Object} [runtime] - An object containing runtime references by the agent. This is not recommended for use.
|
|
28
|
+
* @property {Array<Object>} [features] - A list of feature modules to include in the agent. This is only necessary when using the `Agent` class strictly.
|
|
29
|
+
* @property {boolean} [exposed] - Whether the agent should expose its API to (be affected by) the global `newrelic` object.
|
|
30
|
+
* @property {string} [loaderType] - The type of loader that is initializing the agent. It's recommended to allow the default.
|
|
31
|
+
*/
|
|
32
|
+
|
|
22
33
|
/**
|
|
23
34
|
* A flexible class that may be used to compose an agent from a select subset of feature modules. In applications
|
|
24
35
|
* sensitive to network load, this may result in smaller builds with slightly lower performance impact.
|
|
25
36
|
*/
|
|
26
37
|
export class Agent extends AgentBase {
|
|
27
38
|
/**
|
|
28
|
-
* @param {
|
|
39
|
+
* @param {AgentOptions} options
|
|
29
40
|
*/
|
|
30
41
|
constructor (options) {
|
|
31
42
|
super()
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { Agent } from './agent'
|
|
6
|
-
|
|
7
6
|
import { Instrument as InstrumentPageViewEvent } from '../features/page_view_event/instrument'
|
|
8
7
|
import { Instrument as InstrumentPageViewTiming } from '../features/page_view_timing/instrument'
|
|
9
8
|
import { Instrument as InstrumentMetrics } from '../features/metrics/instrument'
|
|
@@ -21,9 +20,12 @@ import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/in
|
|
|
21
20
|
* The BrowserAgent class is the most convenient and reliable option for most use cases.
|
|
22
21
|
*/
|
|
23
22
|
export class BrowserAgent extends Agent {
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* @param {import('./agent').AgentOptions} options
|
|
25
|
+
*/
|
|
26
|
+
constructor (options) {
|
|
25
27
|
super({
|
|
26
|
-
...
|
|
28
|
+
...options,
|
|
27
29
|
features: [
|
|
28
30
|
InstrumentXhr,
|
|
29
31
|
InstrumentPageViewEvent,
|
|
@@ -27,7 +27,7 @@ const nonAutoFeatures = [
|
|
|
27
27
|
*/
|
|
28
28
|
export class MicroAgent extends MicroAgentBase {
|
|
29
29
|
/**
|
|
30
|
-
* @param {
|
|
30
|
+
* @param {import('./agent').AgentOptions} options
|
|
31
31
|
*/
|
|
32
32
|
constructor (options) {
|
|
33
33
|
super()
|