Skip to content

Commit ffab851

Browse files
committed
Merge commit 'ffc647c2c757034b14d56bac9b0103b2016c5fbb' into logapi-separation
2 parents d497a44 + ffc647c commit ffab851

File tree

28 files changed

+247
-129
lines changed

28 files changed

+247
-129
lines changed

.github/actions/build-ab/templates/experiments.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ window.NREUM.loader_config.licenseKey = '{{{args.abLicenseKey}}}'
44
window.NREUM.info.applicationID = '{{{args.abAppId}}}'
55
window.NREUM.info.licenseKey = '{{{args.abLicenseKey}}}'
66
window.NREUM.init.proxy = {} // Proxy won't work for experiments
7-
window.NREUM.init.session_replay.enabled = false // disabled for now to not double wrap the page which can cause extra processing burden
8-
window.NREUM.init.session_trace.enabled = false // disabled for now to not double wrap the page which can cause extra processing burden
7+
window.NREUM.init.session_replay.enabled = true // feature is enabled, but the app settings will have sampling at 0. We can proactively enable SR for certain test cases through app settings
8+
window.NREUM.init.session_trace.enabled = true // feature is enabled, but the app settings will have sampling at 0. We can proactively enable SR for certain test cases through app settings
99
window.NREUM.init.feature_flags = ['ajax_metrics_deny_list','soft_nav']
1010
window.NREUM.init.user_actions = {elementAttributes: ['id', 'className', 'tagName', 'type', 'ariaLabel', 'alt', 'title']}
1111

.github/actions/build-ab/templates/latest.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ window.NREUM.info.applicationID = '{{{args.abAppId}}}'
55
window.NREUM.info.licenseKey = '{{{args.abLicenseKey}}}'
66
window.NREUM.init.proxy.assets = 'https://staging-js-agent.newrelic.com/dev'
77
window.NREUM.init.feature_flags = ['soft_nav','ajax_metrics_deny_list']
8-
window.NREUM.init.session_replay.enabled = false // disabled for now to not double wrap the page which can cause extra processing burden
9-
window.NREUM.init.session_trace.enabled = false // disabled for now to not double wrap the page which can cause extra processing burden
8+
window.NREUM.init.session_replay.enabled = true // feature is enabled, but the app settings will have sampling at 0. We can proactively enable SR for certain test cases through app settings
9+
window.NREUM.init.session_trace.enabled = true // feature is enabled, but the app settings will have sampling at 0. We can proactively enable SR for certain test cases through app settings
1010
window.NREUM.init.user_actions = {elementAttributes: ['id', 'className', 'tagName', 'type', 'ariaLabel', 'alt', 'title']}
1111

1212
{{{latestScript}}}

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [1.297.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.296.0...v1.297.0) (2025-09-10)
7+
8+
9+
### Features
10+
11+
* Prevent early harvests when in retry period ([#1548](https://github.com/newrelic/newrelic-browser-agent/issues/1548)) ([5ce9e70](https://github.com/newrelic/newrelic-browser-agent/commit/5ce9e705c2d8e55d4f3f93bd704ad78707aa3c84))
12+
* remove newrelic meta attribute ([#1550](https://github.com/newrelic/newrelic-browser-agent/issues/1550)) ([f165b3e](https://github.com/newrelic/newrelic-browser-agent/commit/f165b3e877fc4fc4c8b2b77c942b791a25d58705))
13+
14+
15+
### Bug Fixes
16+
17+
* Fix exceptions for null bodies arising from empty harvests ([#1553](https://github.com/newrelic/newrelic-browser-agent/issues/1553)) ([b763d03](https://github.com/newrelic/newrelic-browser-agent/commit/b763d03215f043e5be555e2dfe2fba85351d672f))
18+
619
## [1.296.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.295.0...v1.296.0) (2025-08-19)
720

821

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ browserAgent.recordCustomEvent(...)
245245

246246
## Deploying one or more "micro" agents per page
247247

248+
> **ℹ️ Note:**
249+
> This loader strategy is slated to be deprecated and eventually removed in a future product release. For better memory usage, build size impacts, entity management and relationships -- a new strategy focused around using a single centralized browser agent instance is actively being worked on. Reach out by email to [email protected] for more information or if you would like to participate in a limited preview when the feature is ready for early adoption.
250+
248251
The examples above use the `Agent` class at their core, which is ideal for most cases as it will automatically detect page-level events across your web application.
249252

250253
Using the `MicroAgent` class, it is possible to skip the "auto" instrumentation phases of the other loader types, and provide a *very small* agent designed for capturing data in a controlled manner via the API interfaces. The `MicroAgent` captures a distinct `PageView` event when instantiated, and additional `PageAction` and `JavaScriptError` events may be captured by calling the `noticeError` and `addPageAction` methods.

changelog.json

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,39 @@
11
{
22
"repository": "newrelic/newrelic-browser-agent",
33
"entries": [
4+
{
5+
"changes": [
6+
{
7+
"type": "feat",
8+
"sha": "5ce9e705c2d8e55d4f3f93bd704ad78707aa3c84",
9+
"message": "Prevent early harvests when in retry period",
10+
"issues": [
11+
"1548"
12+
]
13+
},
14+
{
15+
"type": "feat",
16+
"sha": "f165b3e877fc4fc4c8b2b77c942b791a25d58705",
17+
"message": "remove newrelic meta attribute",
18+
"issues": [
19+
"1550"
20+
]
21+
},
22+
{
23+
"type": "fix",
24+
"sha": "b763d03215f043e5be555e2dfe2fba85351d672f",
25+
"message": "Fix exceptions for null bodies arising from empty harvests",
26+
"issues": [
27+
"1553"
28+
]
29+
}
30+
],
31+
"version": "1.297.0",
32+
"language": "JAVASCRIPT",
33+
"artifactName": "@newrelic/browser-agent",
34+
"id": "929351c8-1b39-4255-bbc8-c935c1f27c32",
35+
"createTime": "2025-09-10T21:46:13.910Z"
36+
},
437
{
538
"changes": [
639
{
@@ -3132,5 +3165,5 @@
31323165
"createTime": "2023-05-08T21:11:35.144Z"
31333166
}
31343167
],
3135-
"updateTime": "2025-08-19T21:32:44.379Z"
3168+
"updateTime": "2025-09-10T21:46:13.910Z"
31363169
}

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@newrelic/browser-agent",
3-
"version": "1.296.0",
3+
"version": "1.297.0",
44
"private": false,
55
"author": "New Relic Browser Agent Team <[email protected]>",
66
"description": "New Relic Browser Agent",

src/common/constants/agent-constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
export const IDEAL_PAYLOAD_SIZE = 16000
66
export const MAX_PAYLOAD_SIZE = 1000000
77
export const DEFAULT_KEY = 'NR_CONTAINER_AGENT'
8+
export const SESSION_ERROR = 'SESSION_ERROR'

src/features/session_replay/aggregate/index.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ export class Aggregate extends AggregateBase {
4343
/** set at BCS response, stored in runtime */
4444
this.timeKeeper = undefined
4545

46-
this.recorder = args?.recorder
47-
this.errorNoticed = args?.errorNoticed || false
46+
this.instrumentClass = args
47+
// point this var here just in case it already exists and can be used by APIs (session pause, resume, etc.) before handling rum flags
48+
this.recorder = this.instrumentClass?.recorder
49+
4850
this.harvestOpts.raw = true
4951

5052
this.isSessionTrackingEnabled = canEnableSessionTracking(agentRef.init) && !!agentRef.runtime.session
@@ -64,7 +66,7 @@ export class Aggregate extends AggregateBase {
6466
// if the mode changed on a different tab, it needs to update this instance to match
6567
this.mode = agentRef.runtime.session.state.sessionReplayMode
6668
if (!this.initialized || this.mode === MODE.OFF) return
67-
this.recorder?.startRecording()
69+
this.recorder?.startRecording(TRIGGERS.RESUME, this.mode)
6870
})
6971

7072
this.ee.on(SESSION_EVENTS.UPDATE, (type, data) => {
@@ -131,7 +133,7 @@ export class Aggregate extends AggregateBase {
131133
this.mode = MODE.FULL
132134
// if the error was noticed AFTER the recorder was already imported....
133135
if (this.recorder && this.initialized) {
134-
if (!this.agentRef.runtime.isRecording) this.recorder.startRecording()
136+
if (!this.agentRef.runtime.isRecording) this.recorder.startRecording(TRIGGERS.SWITCH_TO_FULL, this.mode) // off --> full
135137
this.syncWithSessionManager({ sessionReplayMode: this.mode })
136138
} else {
137139
this.initializeRecording(MODE.FULL, true)
@@ -142,9 +144,10 @@ export class Aggregate extends AggregateBase {
142144
* Evaluate entitlements and sampling before starting feature mechanics, importing and configuring recording library, and setting storage state
143145
* @param {boolean} srMode - the true/false state of the "sr" flag (aka. entitlements) from RUM response
144146
* @param {boolean} ignoreSession - whether to force the method to ignore the session state and use just the sample flags
147+
* @param {TRIGGERS} [trigger=TRIGGERS.INITIALIZE] - the trigger that initiated the recording. Usually TRIGGERS.INITIALIZE, but could be TRIGGERS.API since in certain cases that trigger calls this method
145148
* @returns {void}
146149
*/
147-
async initializeRecording (srMode, ignoreSession) {
150+
async initializeRecording (srMode, ignoreSession, trigger = TRIGGERS.INITIALIZE) {
148151
this.initialized = true
149152
if (!this.entitled) return
150153

@@ -156,7 +159,8 @@ export class Aggregate extends AggregateBase {
156159
// session replays can continue if already in progress
157160
const { session, timeKeeper } = this.agentRef.runtime
158161
this.timeKeeper = timeKeeper
159-
if (this.recorder?.parent.trigger === TRIGGERS.API && this.agentRef.runtime.isRecording) {
162+
163+
if (this.recorder?.trigger === TRIGGERS.API && this.agentRef.runtime.isRecording) {
160164
this.mode = MODE.FULL
161165
} else if (!session.isNew && !ignoreSession) { // inherit the mode of the existing session
162166
this.mode = session.state.sessionReplayMode
@@ -167,29 +171,24 @@ export class Aggregate extends AggregateBase {
167171
// If off, then don't record (early return)
168172
if (this.mode === MODE.OFF) return
169173

170-
if (!this.recorder) {
171-
try {
172-
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
173-
const { Recorder } = (await import(/* webpackChunkName: "recorder" */'../shared/recorder'))
174-
this.recorder = new Recorder(this)
175-
this.recorder.events.hasError = this.errorNoticed
176-
} catch (err) {
177-
return this.abort(ABORT_REASONS.IMPORT)
178-
}
179-
} else {
180-
this.recorder.parent = this
174+
try {
175+
/** will return a recorder instance if already imported, otherwise, will fetch the recorder and initialize it */
176+
this.recorder ??= await this.instrumentClass.importRecorder()
177+
} catch (err) {
178+
/** if the recorder fails to import, abort the feature */
179+
return this.abort(ABORT_REASONS.IMPORT, err)
181180
}
182181

183182
// If an error was noticed before the mode could be set (like in the early lifecycle of the page), immediately set to FULL mode
184-
if (this.mode === MODE.ERROR && this.errorNoticed) this.mode = MODE.FULL
183+
if (this.mode === MODE.ERROR && this.instrumentClass.errorNoticed) { this.mode = MODE.FULL }
185184

186185
// FULL mode records AND reports from the beginning, while ERROR mode only records (but does not report).
187186
// ERROR mode will do this until an error is thrown, and then switch into FULL mode.
188187
// The makeHarvestPayload should ensure that no payload is returned if we're not in FULL mode...
189188

190189
await this.prepUtils()
191190

192-
if (!this.agentRef.runtime.isRecording) this.recorder.startRecording()
191+
if (!this.agentRef.runtime.isRecording) this.recorder.startRecording(trigger, this.mode)
193192

194193
this.syncWithSessionManager({ sessionReplayMode: this.mode })
195194
}

src/features/session_replay/constants.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,9 @@ export const ABORT_REASONS = {
5454
export const QUERY_PARAM_PADDING = 5000
5555

5656
export const TRIGGERS = {
57-
API: 'api'
57+
API: 'api',
58+
RESUME: 'resume',
59+
SWITCH_TO_FULL: 'switchToFull',
60+
INITIALIZE: 'initialize',
61+
PRELOAD: 'preload'
5862
}

0 commit comments

Comments
 (0)