@newrelic/browser-agent 1.256.1 → 1.258.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 +32 -0
- package/dist/cjs/common/config/state/configurable.js +8 -5
- package/dist/cjs/common/config/state/init.js +0 -2
- package/dist/cjs/common/config/state/runtime.js +10 -8
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/runtime.js +8 -2
- package/dist/cjs/common/harvest/harvest.js +7 -5
- package/dist/cjs/common/session/constants.js +1 -0
- package/dist/cjs/common/session/session-entity.js +3 -0
- package/dist/cjs/common/timing/time-keeper.js +45 -9
- package/dist/cjs/common/vitals/time-to-first-byte.js +1 -1
- package/dist/cjs/common/vitals/vital-metric.js +1 -1
- package/dist/cjs/features/ajax/aggregate/chunk.js +50 -0
- package/dist/cjs/features/ajax/aggregate/index.js +131 -191
- package/dist/cjs/features/ajax/instrument/index.js +0 -3
- package/dist/cjs/features/jserrors/aggregate/index.js +26 -13
- package/dist/cjs/features/page_view_event/aggregate/index.js +3 -3
- package/dist/cjs/features/session_replay/aggregate/index.js +12 -5
- package/dist/cjs/features/session_replay/constants.js +2 -1
- package/dist/cjs/features/session_replay/instrument/index.js +15 -5
- package/dist/cjs/features/session_replay/shared/recorder.js +6 -3
- package/dist/cjs/features/session_replay/shared/utils.js +9 -8
- package/dist/cjs/features/session_trace/aggregate/index.js +3 -5
- package/dist/cjs/features/soft_navigations/aggregate/index.js +2 -2
- package/dist/cjs/features/spa/instrument/index.js +0 -2
- package/dist/cjs/features/utils/agent-session.js +1 -5
- package/dist/cjs/features/utils/instrument-base.js +11 -14
- package/dist/cjs/features/utils/nr1-debugger.js +27 -0
- package/dist/cjs/loaders/agent.js +4 -0
- package/dist/cjs/loaders/api/apiAsync.js +5 -4
- package/dist/esm/common/config/state/configurable.js +8 -5
- package/dist/esm/common/config/state/init.js +0 -2
- package/dist/esm/common/config/state/runtime.js +11 -9
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +7 -1
- package/dist/esm/common/harvest/harvest.js +7 -5
- package/dist/esm/common/session/constants.js +1 -0
- package/dist/esm/common/session/session-entity.js +3 -0
- package/dist/esm/common/timing/time-keeper.js +46 -9
- package/dist/esm/common/vitals/time-to-first-byte.js +2 -2
- package/dist/esm/common/vitals/vital-metric.js +1 -1
- package/dist/esm/features/ajax/aggregate/chunk.js +43 -0
- package/dist/esm/features/ajax/aggregate/index.js +130 -191
- package/dist/esm/features/ajax/instrument/index.js +1 -4
- package/dist/esm/features/jserrors/aggregate/index.js +26 -13
- package/dist/esm/features/page_view_event/aggregate/index.js +4 -4
- package/dist/esm/features/session_replay/aggregate/index.js +12 -5
- package/dist/esm/features/session_replay/constants.js +2 -1
- package/dist/esm/features/session_replay/instrument/index.js +16 -6
- package/dist/esm/features/session_replay/shared/recorder.js +6 -3
- package/dist/esm/features/session_replay/shared/utils.js +9 -7
- package/dist/esm/features/session_trace/aggregate/index.js +3 -5
- package/dist/esm/features/soft_navigations/aggregate/index.js +2 -2
- package/dist/esm/features/spa/instrument/index.js +0 -2
- package/dist/esm/features/utils/agent-session.js +1 -5
- package/dist/esm/features/utils/instrument-base.js +11 -14
- package/dist/esm/features/utils/nr1-debugger.js +21 -0
- package/dist/esm/loaders/agent.js +4 -0
- package/dist/esm/loaders/api/apiAsync.js +5 -4
- package/dist/types/common/config/state/configurable.d.ts.map +1 -1
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/constants/runtime.d.ts +6 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +1 -1
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/constants.d.ts +1 -0
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timing/time-keeper.d.ts +1 -1
- package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/chunk.d.ts +8 -0
- package/dist/types/features/ajax/aggregate/chunk.d.ts.map +1 -0
- package/dist/types/features/ajax/aggregate/index.d.ts +8 -6
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts +2 -2
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +0 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +0 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts +1 -0
- package/dist/types/features/session_replay/constants.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 +1 -0
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/utils.d.ts +5 -5
- package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +8 -8
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/features/utils/nr1-debugger.d.ts +2 -0
- package/dist/types/features/utils/nr1-debugger.d.ts.map +1 -0
- package/dist/types/loaders/agent.d.ts +5 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/config/state/configurable.js +9 -8
- package/src/common/config/state/init.js +0 -1
- package/src/common/config/state/runtime.js +12 -9
- package/src/common/constants/__mocks__/runtime.js +2 -0
- package/src/common/constants/runtime.js +6 -1
- package/src/common/drain/__mocks__/drain.js +2 -0
- package/src/common/harvest/harvest.js +8 -6
- package/src/common/session/constants.js +1 -0
- package/src/common/session/session-entity.js +2 -0
- package/src/common/timing/time-keeper.js +44 -10
- package/src/common/vitals/time-to-first-byte.js +2 -2
- package/src/common/vitals/vital-metric.js +1 -1
- package/src/common/window/__mocks__/load.js +3 -0
- package/src/features/ajax/aggregate/chunk.js +51 -0
- package/src/features/ajax/aggregate/index.js +128 -200
- package/src/features/ajax/instrument/index.js +1 -4
- package/src/features/jserrors/aggregate/index.js +28 -11
- package/src/features/page_view_event/aggregate/index.js +4 -4
- package/src/features/session_replay/aggregate/index.js +19 -7
- package/src/features/session_replay/constants.js +2 -1
- package/src/features/session_replay/instrument/index.js +16 -6
- package/src/features/session_replay/shared/__mocks__/utils.js +2 -0
- package/src/features/session_replay/shared/recorder.js +7 -4
- package/src/features/session_replay/shared/utils.js +9 -7
- package/src/features/session_trace/aggregate/index.js +3 -6
- package/src/features/soft_navigations/aggregate/index.js +2 -2
- package/src/features/spa/instrument/index.js +0 -3
- package/src/features/utils/__mocks__/agent-session.js +1 -0
- package/src/features/utils/__mocks__/feature-base.js +11 -0
- package/src/features/utils/agent-session.js +1 -7
- package/src/features/utils/instrument-base.js +11 -14
- package/src/features/utils/nr1-debugger.js +22 -0
- package/src/loaders/agent.js +4 -0
- package/src/loaders/api/apiAsync.js +5 -4
- package/dist/cjs/common/storage/first-party-cookies.js +0 -36
- package/dist/esm/common/storage/first-party-cookies.js +0 -29
- package/dist/types/common/storage/first-party-cookies.d.ts +0 -8
- package/dist/types/common/storage/first-party-cookies.d.ts.map +0 -1
- package/src/common/storage/first-party-cookies.js +0 -32
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiAsync.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/apiAsync.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apiAsync.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/apiAsync.js"],"names":[],"mappings":"AASA,mDA8CC"}
|
package/package.json
CHANGED
|
@@ -11,14 +11,15 @@ export function getModeledObject (obj, model) {
|
|
|
11
11
|
)
|
|
12
12
|
const target = Object.keys(output).length === 0 ? obj : output
|
|
13
13
|
for (let key in target) {
|
|
14
|
-
if (obj[key]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
if (obj[key] === undefined) continue
|
|
15
|
+
try {
|
|
16
|
+
if (obj[key] === null) { output[key] = null; continue }
|
|
17
|
+
|
|
18
|
+
if (Array.isArray(obj[key]) && Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]))
|
|
19
|
+
else if (typeof obj[key] === 'object' && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key])
|
|
20
|
+
else output[key] = obj[key]
|
|
21
|
+
} catch (e) {
|
|
22
|
+
warn('An error occurred while setting a property of a Configurable', e)
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
return output
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { getModeledObject } from './configurable'
|
|
2
2
|
import { getNREUMInitializedAgent } from '../../window/nreum'
|
|
3
|
-
import { globalScope } from '../../constants/runtime'
|
|
3
|
+
import { globalScope, originTime } from '../../constants/runtime'
|
|
4
4
|
import { BUILD_ENV, DIST_METHOD, VERSION } from '../../constants/env'
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const readonly = {
|
|
7
7
|
buildEnv: BUILD_ENV,
|
|
8
|
+
distMethod: DIST_METHOD,
|
|
9
|
+
version: VERSION,
|
|
10
|
+
originTime
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const model = {
|
|
8
14
|
customTransaction: undefined,
|
|
9
15
|
disabled: false,
|
|
10
|
-
distMethod: DIST_METHOD,
|
|
11
16
|
isolatedBacklog: false,
|
|
12
17
|
loaderType: undefined,
|
|
13
18
|
maxBytes: 30000,
|
|
14
|
-
// The "timeOrigin" property is the new standard timestamp property shared across main frame and workers, but is not supported in some early Safari browsers (safari<15) + IE
|
|
15
|
-
// ingest expects an integer value, and timeOrigin can return a float.
|
|
16
|
-
offset: Math.floor(globalScope?.performance?.timeOrigin || globalScope?.performance?.timing?.navigationStart || Date.now()),
|
|
17
19
|
onerror: undefined,
|
|
18
20
|
origin: '' + globalScope.location,
|
|
19
21
|
ptid: undefined,
|
|
@@ -21,8 +23,6 @@ const model = {
|
|
|
21
23
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
22
24
|
appMetadata: {},
|
|
23
25
|
session: undefined,
|
|
24
|
-
xhrWrappable: typeof globalScope.XMLHttpRequest?.prototype?.addEventListener === 'function',
|
|
25
|
-
version: VERSION,
|
|
26
26
|
denyList: undefined,
|
|
27
27
|
harvestCount: 0,
|
|
28
28
|
timeKeeper: undefined
|
|
@@ -38,7 +38,10 @@ export function getRuntime (id) {
|
|
|
38
38
|
|
|
39
39
|
export function setRuntime (id, obj) {
|
|
40
40
|
if (!id) throw new Error('All runtime objects require an agent identifier!')
|
|
41
|
-
_cache[id] =
|
|
41
|
+
_cache[id] = {
|
|
42
|
+
...getModeledObject(obj, model),
|
|
43
|
+
...readonly
|
|
44
|
+
}
|
|
42
45
|
const agentInst = getNREUMInitializedAgent(id)
|
|
43
46
|
if (agentInst) agentInst.runtime = _cache[id]
|
|
44
47
|
}
|
|
@@ -74,4 +74,9 @@ export const isIE = Boolean(isBrowserScope && window.document.documentMode) // d
|
|
|
74
74
|
|
|
75
75
|
export const supportsSendBeacon = !!globalScope.navigator?.sendBeacon
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Represents the absolute timestamp in milliseconds that the page was loaded
|
|
79
|
+
* according to the browser's local clock.
|
|
80
|
+
* @type {number}
|
|
81
|
+
*/
|
|
82
|
+
export const originTime = Math.floor(Date.now() - performance.now())
|
|
@@ -103,7 +103,7 @@ export class Harvest extends SharedContext {
|
|
|
103
103
|
if (customUrl) url = customUrl
|
|
104
104
|
if (raw) url = `${protocol}://${perceviedBeacon}/${endpoint}`
|
|
105
105
|
|
|
106
|
-
const baseParams = !raw && includeBaseParams ? this.baseQueryString(qs) : ''
|
|
106
|
+
const baseParams = !raw && includeBaseParams ? this.baseQueryString(qs, endpoint) : ''
|
|
107
107
|
let payloadParams = encodeObj(qs, agentRuntime.maxBytes)
|
|
108
108
|
if (!submitMethod) {
|
|
109
109
|
submitMethod = submitData.getSubmitMethod({ isFinalHarvest: opts.unload })
|
|
@@ -167,14 +167,15 @@ export class Harvest extends SharedContext {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
// The stuff that gets sent every time.
|
|
170
|
-
baseQueryString (qs) {
|
|
170
|
+
baseQueryString (qs, endpoint) {
|
|
171
171
|
const runtime = getRuntime(this.sharedContext.agentIdentifier)
|
|
172
172
|
const info = getInfo(this.sharedContext.agentIdentifier)
|
|
173
173
|
|
|
174
174
|
const location = cleanURL(getLocation())
|
|
175
175
|
const ref = this.obfuscator.shouldObfuscate() ? this.obfuscator.obfuscateString(location) : location
|
|
176
|
+
const hr = runtime?.session?.state.sessionReplayMode === 1 && endpoint !== 'jserrors'
|
|
176
177
|
|
|
177
|
-
|
|
178
|
+
const qps = [
|
|
178
179
|
'a=' + info.applicationID,
|
|
179
180
|
encodeParam('sa', (info.sa ? '' + info.sa : '')),
|
|
180
181
|
encodeParam('v', VERSION),
|
|
@@ -184,9 +185,10 @@ export class Harvest extends SharedContext {
|
|
|
184
185
|
'&ck=0', // ck param DEPRECATED - still expected by backend
|
|
185
186
|
'&s=' + (runtime.session?.state.value || '0'), // the 0 id encaps all untrackable and default traffic
|
|
186
187
|
encodeParam('ref', ref),
|
|
187
|
-
encodeParam('ptid', (runtime.ptid ? '' + runtime.ptid : ''))
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
encodeParam('ptid', (runtime.ptid ? '' + runtime.ptid : ''))
|
|
189
|
+
]
|
|
190
|
+
if (hr) qps.push(encodeParam('hr', '1', qs))
|
|
191
|
+
return qps.join('')
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
/**
|
|
@@ -24,6 +24,7 @@ const model = {
|
|
|
24
24
|
sessionReplaySentFirstChunk: false,
|
|
25
25
|
sessionTraceMode: MODE.OFF,
|
|
26
26
|
traceHarvestStarted: false,
|
|
27
|
+
serverTimeDiff: null, // set by TimeKeeper; "undefined" value will not be stringified and stored but "null" will
|
|
27
28
|
custom: {}
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -135,6 +136,7 @@ export class SessionEntity {
|
|
|
135
136
|
else this.sync(initialRead)
|
|
136
137
|
|
|
137
138
|
this.initialized = true
|
|
139
|
+
this.ee.emit(SESSION_EVENTS.STARTED, [this.isNew])
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
// This is the actual key appended to the storage API
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { originTime } from '../constants/runtime'
|
|
2
|
+
import { ee as baseEE } from '../event-emitter/contextual-ee'
|
|
3
|
+
import { getRuntime } from '../config/config'
|
|
4
|
+
import { SESSION_EVENT_TYPES, SESSION_EVENTS } from '../session/constants'
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Class used to adjust the timestamp of harvested data to New Relic server time. This
|
|
3
8
|
* is done by tracking the performance timings of the RUM call and applying a calculation
|
|
@@ -5,10 +10,10 @@
|
|
|
5
10
|
*/
|
|
6
11
|
export class TimeKeeper {
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @type {
|
|
13
|
+
* Pointer to the current agent session if it exists.
|
|
14
|
+
* @type {import('../session/session-entity').SessionEntity}
|
|
10
15
|
*/
|
|
11
|
-
#
|
|
16
|
+
#session
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
19
|
* Represents the browser origin time corrected to NR server time.
|
|
@@ -30,18 +35,25 @@ export class TimeKeeper {
|
|
|
30
35
|
*/
|
|
31
36
|
#ready = false
|
|
32
37
|
|
|
33
|
-
constructor () {
|
|
34
|
-
this.#
|
|
38
|
+
constructor (agentIdentifier) {
|
|
39
|
+
this.#session = getRuntime(agentIdentifier)?.session
|
|
40
|
+
|
|
41
|
+
if (this.#session) {
|
|
42
|
+
const ee = baseEE.get(agentIdentifier)
|
|
43
|
+
ee.on(SESSION_EVENTS.UPDATE, this.#processSessionUpdate.bind(this))
|
|
44
|
+
ee.on(SESSION_EVENTS.STARTED, () => {
|
|
45
|
+
if (this.#ready) {
|
|
46
|
+
this.#session.write({ serverTimeDiff: this.#localTimeDiff })
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
this.#processSessionUpdate(null, this.#session.read())
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
get ready () {
|
|
38
54
|
return this.#ready
|
|
39
55
|
}
|
|
40
56
|
|
|
41
|
-
get originTime () {
|
|
42
|
-
return this.#originTime
|
|
43
|
-
}
|
|
44
|
-
|
|
45
57
|
get correctedOriginTime () {
|
|
46
58
|
return this.#correctedOriginTime
|
|
47
59
|
}
|
|
@@ -53,6 +65,8 @@ export class TimeKeeper {
|
|
|
53
65
|
* @param endTime {number} The end time of the RUM request
|
|
54
66
|
*/
|
|
55
67
|
processRumRequest (rumRequest, startTime, endTime) {
|
|
68
|
+
if (this.#ready) return // Server time calculated from session entity
|
|
69
|
+
|
|
56
70
|
const responseDateHeader = rumRequest.getResponseHeader('Date')
|
|
57
71
|
if (!responseDateHeader) {
|
|
58
72
|
throw new Error('Missing date header on rum response.')
|
|
@@ -63,12 +77,13 @@ export class TimeKeeper {
|
|
|
63
77
|
|
|
64
78
|
// Corrected page origin time
|
|
65
79
|
this.#correctedOriginTime = Math.floor(Date.parse(responseDateHeader) - serverOffset)
|
|
66
|
-
this.#localTimeDiff =
|
|
80
|
+
this.#localTimeDiff = originTime - this.#correctedOriginTime
|
|
67
81
|
|
|
68
82
|
if (Number.isNaN(this.#correctedOriginTime)) {
|
|
69
83
|
throw new Error('Date header invalid format.')
|
|
70
84
|
}
|
|
71
85
|
|
|
86
|
+
if (this.#session) this.#session.write({ serverTimeDiff: this.#localTimeDiff })
|
|
72
87
|
this.#ready = true
|
|
73
88
|
}
|
|
74
89
|
|
|
@@ -90,4 +105,23 @@ export class TimeKeeper {
|
|
|
90
105
|
correctAbsoluteTimestamp (timestamp) {
|
|
91
106
|
return Math.floor(timestamp - this.#localTimeDiff)
|
|
92
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Processes a session entity update payload to extract the server time calculated.
|
|
111
|
+
* @param {import('../session/constants').SESSION_EVENT_TYPES | null} type
|
|
112
|
+
* @param {Object} data
|
|
113
|
+
*/
|
|
114
|
+
#processSessionUpdate (type, data) {
|
|
115
|
+
if (typeof data?.serverTimeDiff !== 'number') return
|
|
116
|
+
|
|
117
|
+
if (
|
|
118
|
+
(!type && !this.#ready) || // This captures the initial read from the session entity when the timekeeper first initializes
|
|
119
|
+
type === SESSION_EVENT_TYPES.CROSS_TAB // This captures any cross-tab write of the session entity
|
|
120
|
+
) {
|
|
121
|
+
// This captures the initial read from the session entity when the timekeeper first initializes
|
|
122
|
+
this.#localTimeDiff = data.serverTimeDiff
|
|
123
|
+
this.#correctedOriginTime = originTime - this.#localTimeDiff
|
|
124
|
+
this.#ready = true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
93
127
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { globalScope, isBrowserScope, isiOS,
|
|
1
|
+
import { globalScope, isBrowserScope, isiOS, originTime } from '../constants/runtime'
|
|
2
2
|
import { VITAL_NAMES } from './constants'
|
|
3
3
|
import { VitalMetric } from './vital-metric'
|
|
4
4
|
import { onTTFB } from 'web-vitals/attribution'
|
|
@@ -14,7 +14,7 @@ if (isBrowserScope && typeof PerformanceNavigationTiming !== 'undefined' && !isi
|
|
|
14
14
|
if (!timeToFirstByte.isValid) {
|
|
15
15
|
const entry = {}
|
|
16
16
|
// convert real timestamps to relative timestamps to match web-vitals behavior
|
|
17
|
-
for (let key in globalScope?.performance?.timing || {}) entry[key] = Math.max(globalScope?.performance?.timing[key] -
|
|
17
|
+
for (let key in globalScope?.performance?.timing || {}) entry[key] = Math.max(globalScope?.performance?.timing[key] - originTime, 0)
|
|
18
18
|
|
|
19
19
|
// ttfb is equiv to document's responseStart property in timing API --> https://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming/responseStart
|
|
20
20
|
timeToFirstByte.update({ value: entry.responseStart, attrs: { navigationEntry: entry } })
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer'
|
|
2
|
+
import { getInfo } from '../../../common/config/config'
|
|
3
|
+
|
|
4
|
+
export default class Chunk {
|
|
5
|
+
constructor (events, aggregateInstance) {
|
|
6
|
+
this.addString = getAddStringContext(aggregateInstance.agentIdentifier) // pass agentIdentifier here
|
|
7
|
+
this.events = events
|
|
8
|
+
this.payload = 'bel.7;'
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < events.length; i++) {
|
|
11
|
+
const event = events[i]
|
|
12
|
+
const fields = [
|
|
13
|
+
numeric(event.startTime),
|
|
14
|
+
numeric(event.endTime - event.startTime),
|
|
15
|
+
numeric(0), // callbackEnd
|
|
16
|
+
numeric(0), // no callbackDuration for non-SPA events
|
|
17
|
+
this.addString(event.method),
|
|
18
|
+
numeric(event.status),
|
|
19
|
+
this.addString(event.domain),
|
|
20
|
+
this.addString(event.path),
|
|
21
|
+
numeric(event.requestSize),
|
|
22
|
+
numeric(event.responseSize),
|
|
23
|
+
event.type === 'fetch' ? 1 : '',
|
|
24
|
+
this.addString(0), // nodeId
|
|
25
|
+
nullable(event.spanId, this.addString, true) + // guid
|
|
26
|
+
nullable(event.traceId, this.addString, true) + // traceId
|
|
27
|
+
nullable(event.spanTimestamp, numeric, false) // timestamp
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
let insert = '2,'
|
|
31
|
+
|
|
32
|
+
// Since configuration objects (like info) are created new each time they are set, we have to grab the current pointer to the attr object here.
|
|
33
|
+
const jsAttributes = getInfo(aggregateInstance.agentIdentifier).jsAttributes
|
|
34
|
+
|
|
35
|
+
// add custom attributes
|
|
36
|
+
// gql decorators are added as custom attributes to alleviate need for new BEL schema
|
|
37
|
+
const attrParts = addCustomAttributes({ ...(jsAttributes || {}), ...(event.gql || {}) }, this.addString)
|
|
38
|
+
fields.unshift(numeric(attrParts.length))
|
|
39
|
+
|
|
40
|
+
insert += fields.join(',')
|
|
41
|
+
if (attrParts && attrParts.length > 0) {
|
|
42
|
+
insert += ';' + attrParts.join(';')
|
|
43
|
+
}
|
|
44
|
+
if ((i + 1) < events.length) insert += ';'
|
|
45
|
+
|
|
46
|
+
this.payload += insert
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.tooBig = this.payload.length * 2 > aggregateInstance.MAX_PAYLOAD_SIZE
|
|
50
|
+
}
|
|
51
|
+
}
|