Skip to content

Commit 8601424

Browse files
authored
fix: Patch newrelic event detail (#1428)
1 parent 44786ae commit 8601424

File tree

9 files changed

+121
-14
lines changed

9 files changed

+121
-14
lines changed

src/common/harvest/harvester.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ function send (agentRef, { endpoint, targetApp, payload, localOpts = {}, submitM
178178

179179
dispatchGlobalEvent({
180180
agentIdentifier: agentRef.agentIdentifier,
181-
loaded: !!activatedFeatures?.[agentRef.agentIdentifier],
181+
drained: !!activatedFeatures?.[agentRef.agentIdentifier],
182182
type: 'data',
183183
name: 'harvest',
184184
feature: featureName,

src/common/util/feature-flags.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ export function activateFeatures (flags, agentIdentifier) {
2828

2929
sentIds.add(agentIdentifier)
3030

31-
// let any window level subscribers know that the agent is running
31+
// let any window level subscribers know that the agent is running, per install docs
3232
dispatchGlobalEvent({
3333
agentIdentifier,
3434
loaded: true,
35+
drained: true,
3536
type: 'lifecycle',
3637
name: 'load',
3738
feature: undefined,

src/features/utils/event-store-manager.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class EventStoreManager {
5353
add (event, target) {
5454
dispatchGlobalEvent({
5555
agentIdentifier: this.agentIdentifier,
56-
loaded: !!activatedFeatures?.[this.agentIdentifier],
56+
drained: !!activatedFeatures?.[this.agentIdentifier],
5757
type: 'data',
5858
name: 'buffer',
5959
feature: this.featureName,

src/loaders/api/api.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export function setAPI (agent, forceDrain) {
194194
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
195195
dispatchGlobalEvent({
196196
agentIdentifier: agent.agentIdentifier,
197-
loaded: !!activatedFeatures?.[agent.agentIdentifier],
197+
drained: !!activatedFeatures?.[agent.agentIdentifier],
198198
type: 'data',
199199
name: 'api',
200200
feature: prefix + name,

src/loaders/configure/configure.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function configure (agent, opts = {}, loaderType, forceDrain) {
7373

7474
dispatchGlobalEvent({
7575
agentIdentifier: agent.agentIdentifier,
76-
loaded: !!activatedFeatures?.[agent.agentIdentifier],
76+
drained: !!activatedFeatures?.[agent.agentIdentifier],
7777
type: 'lifecycle',
7878
name: 'initialize',
7979
feature: undefined,
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Copyright 2020 New Relic Corporation.
4+
PDX-License-Identifier: Apache-2.0
5+
-->
6+
<html lang="en">
7+
<head>
8+
<title>RUM Unit Test</title>
9+
{init}
10+
{config}
11+
{loader}
12+
<script>
13+
addEventListener("newrelic", (evt) => {
14+
window.newrelicEventTime = Date.now()
15+
if (evt.detail.loaded) {
16+
// ensure API works as expected when listening to `newrelic` event
17+
newrelic.setPageViewName('some-page');
18+
newrelic.setApplicationVersion('1.0.0');
19+
newrelic.setCustomAttribute('foo', 'bar');
20+
newrelic.setErrorHandler((error) => {
21+
if (error.foobar) {
22+
return true;
23+
}
24+
25+
// To group errors: return { group: 'GroupName' };
26+
return false;
27+
}
28+
);
29+
newrelic.log('test message');
30+
31+
throw new Error('error 1')
32+
}
33+
})
34+
</script>
35+
</head>
36+
<body>
37+
<div id="initial">initial content</div>
38+
</body>
39+
</html>

tests/assets/inspection-events.html

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
}
1818
window.addEventListener('newrelic', ({ detail }) => {
1919
if (!detail || !detail.agentIdentifier) return
20-
const { name, loaded, type, feature, data } = detail
20+
const { name, drained, type, feature, data } = detail
2121

2222
if (
2323
name == 'initialize' &&
24-
loaded == false &&
24+
drained == false &&
2525
type == 'lifecycle' &&
2626
feature == undefined &&
2727
data
@@ -31,7 +31,7 @@
3131

3232
if (
3333
name === 'load' &&
34-
loaded === true &&
34+
drained === true &&
3535
type === 'lifecycle' &&
3636
feature === undefined &&
3737
data
@@ -41,7 +41,7 @@
4141

4242
if (
4343
name === 'buffer' &&
44-
loaded === true &&
44+
drained === true &&
4545
type === 'data' &&
4646
feature &&
4747
data
@@ -51,7 +51,7 @@
5151

5252
if (
5353
name === 'harvest' &&
54-
loaded === true &&
54+
drained === true &&
5555
type === 'data' &&
5656
feature &&
5757
data
@@ -62,7 +62,7 @@
6262
// The API call in this test is called before the agent is loaded, so loaded should be false
6363
if (
6464
name === 'api' &&
65-
loaded === false &&
65+
drained === false &&
6666
type === 'data' &&
6767
feature &&
6868
data
@@ -81,4 +81,4 @@
8181
</script>
8282
</body>
8383

84-
</html>
84+
</html>

tests/specs/api.e2e.js

+68-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { apiMethods, asyncApiMethods } from '../../src/loaders/api/api-methods'
22
import { checkAjaxEvents, checkJsErrors, checkMetrics, checkGenericEvents, checkPVT, checkRumBody, checkRumQuery, checkSessionTrace, checkSpa } from '../util/basic-checks'
3-
import { testAjaxEventsRequest, testAjaxTimeSlicesRequest, testBlobTraceRequest, testCustomMetricsRequest, testErrorsRequest, testEventsRequest, testInsRequest, testInteractionEventsRequest, testMetricsRequest, testRumRequest, testTimingEventsRequest } from '../../tools/testing-server/utils/expect-tests'
3+
import { testAjaxEventsRequest, testAjaxTimeSlicesRequest, testBlobTraceRequest, testCustomMetricsRequest, testErrorsRequest, testEventsRequest, testInsRequest, testInteractionEventsRequest, testLogsRequest, testMetricsRequest, testRumRequest, testTimingEventsRequest } from '../../tools/testing-server/utils/expect-tests'
4+
import { rumFlags } from '../../tools/testing-server/constants'
5+
import { LOGGING_MODE } from '../../src/features/logging/constants'
46

57
describe('newrelic api', () => {
68
afterEach(async () => {
@@ -49,6 +51,71 @@ describe('newrelic api', () => {
4951
expect(result).toEqual(true)
5052
})
5153

54+
it('should fire `newrelic` event after RUM call', async () => {
55+
const rumCapture = await browser.testHandle.createNetworkCaptures('bamServer', { test: testRumRequest })
56+
57+
await browser.testHandle.scheduleReply('bamServer', {
58+
test: testRumRequest,
59+
body: JSON.stringify(rumFlags({ log: LOGGING_MODE.INFO }))
60+
})
61+
62+
const [rumHarvests] =
63+
await Promise.all([
64+
rumCapture.waitForResult({ timeout: 10000 }),
65+
browser.url(await browser.testHandle.assetURL('event-listener-newrelic.html'))
66+
.then(() => browser.waitForAgentLoad())
67+
.then(() => browser.waitUntil(
68+
() => browser.execute(function () {
69+
return window?.newrelicEventTime
70+
}),
71+
{
72+
timeout: 10000,
73+
timeoutMsg: 'Timeout while waiting on `newrelic` event'
74+
}
75+
))
76+
])
77+
78+
expect(rumHarvests.length).toEqual(1)
79+
const rumResult = JSON.parse(rumHarvests[0].reply.body)
80+
81+
const newrelicEventTime = await browser.execute(function () {
82+
return window.newrelicEventTime
83+
})
84+
85+
expect(newrelicEventTime > rumResult.app.nrServerTime).toBe(true)
86+
})
87+
88+
it('should work as expected within `newrelic` event listeners', async () => {
89+
const [logsCapture, errorsCapture] = await browser.testHandle.createNetworkCaptures('bamServer', [
90+
{ test: testLogsRequest },
91+
{ test: testErrorsRequest }
92+
])
93+
await browser.testHandle.scheduleReply('bamServer', {
94+
test: testRumRequest,
95+
body: JSON.stringify(rumFlags({ log: LOGGING_MODE.INFO }))
96+
})
97+
98+
const [logsHarvests, errorsHarvests] =
99+
await Promise.all([
100+
logsCapture.waitForResult({ totalCount: 1, timeout: 10000 }),
101+
errorsCapture.waitForResult({ totalCount: 1, timeout: 10000 }),
102+
browser.url(await browser.testHandle.assetURL('event-listener-newrelic.html'))
103+
.then(() => browser.waitForAgentLoad())
104+
])
105+
106+
expect(errorsHarvests.length).toEqual(1)
107+
expect(errorsHarvests[0].request.query.ct).toEqual('http://custom.transaction/some-page')
108+
const actualErrors = errorsHarvests[0].request.body.err
109+
expect(actualErrors.length).toEqual(1)
110+
expect(actualErrors[0].params.message).toEqual('error 1')
111+
112+
expect(logsHarvests.length).toEqual(1)
113+
const logsPayload = JSON.parse(logsHarvests[0].request.body)
114+
expect(logsPayload[0].common.attributes['application.version']).toEqual('1.0.0')
115+
expect(logsPayload[0].common.attributes.foo).toEqual('bar')
116+
expect(logsPayload[0].logs[0].message).toEqual('test message')
117+
})
118+
52119
describe('setPageViewName()', () => {
53120
it('includes the 1st argument (page name) in rum, resources, events, and ajax calls', async () => {
54121
const [rumCapture, eventsCapture, ajaxCapture] =

tests/specs/rum/index.e2e.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('basic pve capturing', () => {
5050
checkRumQuery(rumHarvest.request)
5151
checkRumBody(rumHarvest.request)
5252
expect(parseInt(rumHarvest.request.query.be, 10)).toBeGreaterThanOrEqual(500)
53-
expect(parseInt(rumHarvest.request.query.fe, 10)).toBeGreaterThanOrEqual(100)
53+
expect(parseInt(rumHarvest.request.query.fe, 10)).toBeGreaterThanOrEqual(80)
5454
expect(parseInt(rumHarvest.request.query.dc, 10)).toBeGreaterThanOrEqual(100)
5555
})
5656

0 commit comments

Comments
 (0)