Skip to content

Commit

Permalink
feat: Report Page Actions with Generic Events Feature (#1124)
Browse files Browse the repository at this point in the history
  • Loading branch information
metal-messiah authored Aug 5, 2024
1 parent 9fbbba1 commit 0d52acf
Show file tree
Hide file tree
Showing 46 changed files with 375 additions and 215 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ const options = {
The following features may be disabled by adding `init` entries as shown above. Note that the `page_view_event` feature may not be disabled.

- `ajax`
- `generic_events`
- `jserrors`
- `metrics`
- `page_action`
- `page_view_timing`
- `session_replay`
- `session_trace`
Expand Down Expand Up @@ -125,7 +125,7 @@ The following feature modules are available for inclusion in the `features` arra
import { Ajax } from '@newrelic/browser-agent/features/ajax';
import { JSErrors } from '@newrelic/browser-agent/features/jserrors';
import { Metrics } from '@newrelic/browser-agent/features/metrics';
import { PageAction } from '@newrelic/browser-agent/features/page_action';
import { GenericEvents } from '@newrelic/browser-agent/features/generic_events';
import { PageViewEvent } from '@newrelic/browser-agent/features/page_view_event';
import { PageViewTiming } from '@newrelic/browser-agent/features/page_view_timing';
import { SessionTrace } from '@newrelic/browser-agent/features/session_trace';
Expand Down
4 changes: 3 additions & 1 deletion docs/warning-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@
### 42
`Failed to execute setApplicationVersion. Expected <String | null>`
### 43
`Agent not configured properly.`
`Agent not configured properly.`
### 44
`Invalid object passed to generic event aggregate. Missing "eventType".`
4 changes: 0 additions & 4 deletions src/cdn/experimental.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
// import { Instrument as InstrumentSpa } from '../features/spa/instrument'
import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
import { Instrument as InstrumentLogs } from '../features/logging/instrument'

new Agent({
Expand All @@ -31,11 +29,9 @@ new Agent({
InstrumentSessionTrace,
InstrumentSessionReplay,
InstrumentMetrics,
InstrumentPageAction,
InstrumentErrors,
InstrumentGenericEvents,
InstrumentLogs,
// InstrumentSpa,
InstrumentSoftNav
],
loaderType: 'experimental'
Expand Down
2 changes: 0 additions & 2 deletions src/cdn/polyfills/pro.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Instrument as InstrumentMetrics } from '../../features/metrics/instrume
import { Instrument as InstrumentErrors } from '../../features/jserrors/instrument'
import { Instrument as InstrumentXhr } from '../../features/ajax/instrument'
import { Instrument as InstrumentSessionTrace } from '../../features/session_trace/instrument'
import { Instrument as InstrumentPageAction } from '../../features/page_action/instrument'
import { Instrument as InstrumentGenericEvents } from '../../features/generic_events/instrument'
import { Instrument as InstrumentLogs } from '../../features/logging/instrument'

Expand All @@ -23,7 +22,6 @@ new Agent({
InstrumentSessionTrace,
InstrumentXhr,
InstrumentMetrics,
InstrumentPageAction,
InstrumentErrors,
InstrumentGenericEvents,
InstrumentLogs
Expand Down
2 changes: 0 additions & 2 deletions src/cdn/polyfills/spa.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Instrument as InstrumentErrors } from '../../features/jserrors/instrume
import { Instrument as InstrumentXhr } from '../../features/ajax/instrument'
import { Instrument as InstrumentSessionTrace } from '../../features/session_trace/instrument'
import { Instrument as InstrumentSpa } from '../../features/spa/instrument'
import { Instrument as InstrumentPageAction } from '../../features/page_action/instrument'
import { Instrument as InstrumentGenericEvents } from '../../features/generic_events/instrument'
import { Instrument as InstrumentLogs } from '../../features/logging/instrument'

Expand All @@ -24,7 +23,6 @@ new Agent({
InstrumentPageViewTiming,
InstrumentSessionTrace,
InstrumentMetrics,
InstrumentPageAction,
InstrumentErrors,
InstrumentGenericEvents,
InstrumentLogs,
Expand Down
2 changes: 0 additions & 2 deletions src/cdn/pro.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Instrument as InstrumentErrors } from '../features/jserrors/instrument'
import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
import { Instrument as InstrumentLogs } from '../features/logging/instrument'

Expand All @@ -24,7 +23,6 @@ new Agent({
InstrumentSessionReplay,
InstrumentXhr,
InstrumentMetrics,
InstrumentPageAction,
InstrumentErrors,
InstrumentGenericEvents,
InstrumentLogs
Expand Down
2 changes: 0 additions & 2 deletions src/cdn/spa.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Instrument as InstrumentSessionTrace } from '../features/session_trace/
import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
import { Instrument as InstrumentSpa } from '../features/spa/instrument'
import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
import { Instrument as InstrumentLogs } from '../features/logging/instrument'

Expand All @@ -25,7 +24,6 @@ new Agent({
InstrumentSessionTrace,
InstrumentSessionReplay,
InstrumentMetrics,
InstrumentPageAction,
InstrumentErrors,
InstrumentGenericEvents,
InstrumentLogs,
Expand Down
4 changes: 2 additions & 2 deletions src/common/config/state/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ const model = () => {
allowed_origins: undefined
},
feature_flags: [],
generic_events: { enabled: true, harvestTimeSeconds: 10, autoStart: true },
generic_events: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
harvest: { tooManyRequestsDelay: 60 },
jserrors: { enabled: true, harvestTimeSeconds: 10, autoStart: true },
logging: { enabled: true, harvestTimeSeconds: 10, autoStart: true, level: LOG_LEVELS.INFO },
metrics: { enabled: true, autoStart: true },
obfuscate: undefined,
page_action: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
page_action: { enabled: true },
page_view_event: { enabled: true, autoStart: true },
page_view_timing: { enabled: true, harvestTimeSeconds: 30, long_task: false, autoStart: true },
privacy: { cookies_enabled: true }, // *cli - per discussion, default should be true
Expand Down
47 changes: 32 additions & 15 deletions src/features/generic_events/aggregate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { isBrowserScope } from '../../../common/constants/runtime'
import { AggregateBase } from '../../utils/aggregate-base'
import { warn } from '../../../common/util/console'
import { now } from '../../../common/timing/now'
import { registerHandler } from '../../../common/event-emitter/register-handler'
import { deregisterDrain } from '../../../common/drain/drain'

export class Aggregate extends AggregateBase {
Expand All @@ -22,27 +23,42 @@ export class Aggregate extends AggregateBase {
this.eventsPerHarvest = 1000
this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'generic_events.harvestTimeSeconds')

this.referrerUrl = undefined
this.referrerUrl = (isBrowserScope && document.referrer) ? cleanURL(document.referrer) : undefined
this.currentEvents = []

this.events = []
this.overflow = []

this.#agentRuntime = getRuntime(this.agentIdentifier)

if (isBrowserScope && document.referrer) this.referrerUrl = cleanURL(document.referrer)

this.waitForFlags(['ins']).then(([ins]) => {
if (!ins) {
this.blocked = true
deregisterDrain(this.agentIdentifier, this.featureName)
return
}

// handle page actions and other generic events here
if (getConfigurationValue(this.agentIdentifier, 'page_action.enabled')) {
registerHandler('api-addPageAction', (timestamp, name, attributes) => {
this.addEvent({
...attributes,
eventType: 'PageAction',
timestamp: this.#agentRuntime.timeKeeper.convertRelativeTimestamp(timestamp),
timeSinceLoad: timestamp / 1000,
actionName: name,
referrerUrl: this.referrerUrl,
currentUrl: cleanURL('' + location),
...(isBrowserScope && {
browserWidth: window.document.documentElement?.clientWidth,
browserHeight: window.document.documentElement?.clientHeight
})
})
}, this.featureName, this.ee)
}

this.harvestScheduler = new HarvestScheduler('ins', { onFinished: (...args) => this.onHarvestFinished(...args) }, this)
this.harvestScheduler.harvest.on('ins', (...args) => this.onHarvestStarted(...args))
// this.harvestScheduler.startTimer(this.harvestTimeSeconds, 0)
this.harvestScheduler.startTimer(this.harvestTimeSeconds, 0)

this.drain()
})
Expand Down Expand Up @@ -79,30 +95,31 @@ export class Aggregate extends AggregateBase {
addEvent (obj = {}) {
if (!obj || !Object.keys(obj).length) return
if (!obj.eventType) {
warn('Invalid object passed to generic event aggregate. Missing "eventType".')
warn(44)
return
}

for (let key in obj) {
let val = obj[key]
if (key === 'timestamp') val = this.#agentRuntime.timeKeeper.correctAbsoluteTimestamp(val)
obj[key] = (val && typeof val === 'object' ? stringify(val) : val)
}

const defaultEventAttributes = {
/** should be overridden by the event-specific attributes, but just in case -- set it to now() */
timestamp: this.#agentRuntime.timeKeeper.convertRelativeTimestamp(now()),
/** all generic events require a pageUrl */
pageUrl: cleanURL(getRuntime(this.agentIdentifier).origin)
}

const eventAttributes = {
/** Agent-level custom attributes */
...(getInfo(this.agentIdentifier).jsAttributes || {}),
/** Common attributes shared on all generic events */
referrerUrl: this.referrerUrl,
currentUrl: cleanURL('' + location),
pageUrl: cleanURL(getRuntime(this.agentIdentifier).origin),
/** Event-specific attributes take precedence over everything else */
/** Fallbacks for required properties in-case the event did not supply them, should take precedence over agent-level custom attrs */
...defaultEventAttributes,
/** Event-specific attributes take precedence over agent-level custom attributes and fallbacks */
...obj
}

/** should have been provided by reporting feature -- but falls back to now if not */
eventAttributes.timestamp ??= this.#agentRuntime.timeKeeper.convertRelativeTimestamp(now())

this.events.push(eventAttributes)

// check if we've reached the harvest limit...
Expand Down
10 changes: 9 additions & 1 deletion src/features/generic_events/instrument/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { getConfigurationValue } from '../../../common/config/config'
import { deregisterDrain } from '../../../common/drain/drain'
import { InstrumentBase } from '../../utils/instrument-base'
import { FEATURE_NAME } from '../constants'

export class Instrument extends InstrumentBase {
static featureName = FEATURE_NAME
constructor (agentIdentifier, aggregator, auto = true) {
super(agentIdentifier, aggregator, FEATURE_NAME, auto)
this.importAggregator()
const genericEventSourceConfigs = [
getConfigurationValue(this.agentIdentifier, 'page_action.enabled')
// other future generic event source configs to go here, like M&Ms, PageResouce, etc.
]
/** If any of the sources are active, import the aggregator. otherwise deregister */
if (genericEventSourceConfigs.some(x => x)) this.importAggregator()
else deregisterDrain(this.agentIdentifier, this.featureName)
}
}
113 changes: 0 additions & 113 deletions src/features/page_action/aggregate/index.js

This file was deleted.

12 changes: 6 additions & 6 deletions src/features/page_action/instrument/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { InstrumentBase } from '../../utils/instrument-base'
import { FEATURE_NAME } from '../constants'
import { GenericEvents } from '../../generic_events'

export class Instrument extends InstrumentBase {
static featureName = FEATURE_NAME
/**
* @deprecated This feature has been replaced by Generic Events. Use/Import `GenericEvents` instead. This wrapper will be removed in a future release
*/
export class Instrument extends GenericEvents {
constructor (agentIdentifier, aggregator, auto = true) {
super(agentIdentifier, aggregator, FEATURE_NAME, auto)
this.importAggregator()
super(agentIdentifier, aggregator, auto)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function getActivatedFeaturesFlags (agentId) {
flagArr.push('xhr'); break
case FEATURE_NAMES.jserrors:
flagArr.push('err'); break
case FEATURE_NAMES.pageAction:
case FEATURE_NAMES.genericEvents:
flagArr.push('ins'); break
case FEATURE_NAMES.sessionTrace:
flagArr.push('stn'); break
Expand Down
Loading

0 comments on commit 0d52acf

Please sign in to comment.