@sentry-internal/tracing
Advanced tools
Comparing version 7.106.1 to 7.107.0
@@ -7,2 +7,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const backgroundtab = require('./backgroundtab.js'); | ||
const instrument = require('./instrument.js'); | ||
const index = require('./metrics/index.js'); | ||
@@ -24,2 +25,3 @@ const request = require('./request.js'); | ||
enableLongTask: true, | ||
enableInp: false, | ||
_experiments: {}, | ||
@@ -29,2 +31,5 @@ ...request.defaultRequestInstrumentationOptions, | ||
/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */ | ||
const MAX_INTERACTIONS = 10; | ||
/** | ||
@@ -86,2 +91,8 @@ * The Browser Tracing integration automatically instruments browser pageload/navigation | ||
this._collectWebVitals = index.startTrackingWebVitals(); | ||
/** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */ | ||
this._interactionIdtoRouteNameMapping = {}; | ||
if (this.options.enableInp) { | ||
index.startTrackingINP(this._interactionIdtoRouteNameMapping); | ||
} | ||
if (this.options.enableLongTask) { | ||
@@ -93,2 +104,7 @@ index.startTrackingLongTasks(); | ||
} | ||
this._latestRoute = { | ||
name: undefined, | ||
context: undefined, | ||
}; | ||
} | ||
@@ -158,2 +174,6 @@ | ||
if (this.options.enableInp) { | ||
this._registerInpInteractionListener(); | ||
} | ||
request.instrumentOutgoingRequests({ | ||
@@ -221,4 +241,4 @@ traceFetch, | ||
this._latestRouteName = finalContext.name; | ||
this._latestRouteSource = getSource(finalContext); | ||
this._latestRoute.name = finalContext.name; | ||
this._latestRoute.context = finalContext; | ||
@@ -293,3 +313,3 @@ // eslint-disable-next-line deprecation/deprecation | ||
if (!this._latestRouteName) { | ||
if (!this._latestRoute.name) { | ||
debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); | ||
@@ -303,7 +323,9 @@ return undefined; | ||
const context = { | ||
name: this._latestRouteName, | ||
name: this._latestRoute.name, | ||
op, | ||
trimEnd: true, | ||
data: { | ||
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRouteSource || 'url', | ||
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRoute.context | ||
? getSource(this._latestRoute.context) | ||
: 'url', | ||
}, | ||
@@ -327,2 +349,57 @@ }; | ||
} | ||
/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ | ||
_registerInpInteractionListener() { | ||
instrument.addPerformanceInstrumentationHandler('event', ({ entries }) => { | ||
const client = core.getClient(); | ||
// We need to get the replay, user, and activeTransaction from the current scope | ||
// so that we can associate replay id, profile id, and a user display to the span | ||
const replay = | ||
client !== undefined && client.getIntegrationByName !== undefined | ||
? (client.getIntegrationByName('Replay') ) | ||
: undefined; | ||
const replayId = replay !== undefined ? replay.getReplayId() : undefined; | ||
// eslint-disable-next-line deprecation/deprecation | ||
const activeTransaction = core.getActiveTransaction(); | ||
const currentScope = core.getCurrentScope(); | ||
const user = currentScope !== undefined ? currentScope.getUser() : undefined; | ||
for (const entry of entries) { | ||
if (isPerformanceEventTiming(entry)) { | ||
const duration = entry.duration; | ||
const keys = Object.keys(this._interactionIdtoRouteNameMapping); | ||
const minInteractionId = | ||
keys.length > 0 | ||
? keys.reduce((a, b) => { | ||
return this._interactionIdtoRouteNameMapping[a].duration < | ||
this._interactionIdtoRouteNameMapping[b].duration | ||
? a | ||
: b; | ||
}) | ||
: undefined; | ||
if ( | ||
minInteractionId === undefined || | ||
duration > this._interactionIdtoRouteNameMapping[minInteractionId].duration | ||
) { | ||
const interactionId = entry.interactionId; | ||
const routeName = this._latestRoute.name; | ||
const parentContext = this._latestRoute.context; | ||
if (interactionId && routeName && parentContext) { | ||
if (minInteractionId && Object.keys(this._interactionIdtoRouteNameMapping).length >= MAX_INTERACTIONS) { | ||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete | ||
delete this._interactionIdtoRouteNameMapping[minInteractionId]; | ||
} | ||
this._interactionIdtoRouteNameMapping[interactionId] = { | ||
routeName, | ||
duration, | ||
parentContext, | ||
user, | ||
activeTransaction, | ||
replayId, | ||
}; | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
@@ -350,2 +427,6 @@ | ||
function isPerformanceEventTiming(entry) { | ||
return 'duration' in entry; | ||
} | ||
exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID; | ||
@@ -352,0 +433,0 @@ exports.BrowserTracing = BrowserTracing; |
@@ -184,3 +184,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
return instrument.addInpInstrumentationHandler(({ metric }) => { | ||
const entry = metric.entries.find(e => e.name === 'click'); | ||
const entry = metric.entries.find(e => e.name === 'click' || e.name === 'pointerdown'); | ||
const client = core.getClient(); | ||
@@ -233,3 +233,3 @@ if (!entry || !client) { | ||
if (Math.random() < (sampleRate )) { | ||
const envelope = span ? core.createSpanEnvelope([span]) : undefined; | ||
const envelope = span ? core.createSpanEnvelope([span], client.getDsn()) : undefined; | ||
const transport = client && client.getTransport(); | ||
@@ -236,0 +236,0 @@ if (transport && envelope) { |
@@ -1,6 +0,7 @@ | ||
import { TRACING_DEFAULTS, addTracingExtensions, startIdleTransaction, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveTransaction } from '@sentry/core'; | ||
import { TRACING_DEFAULTS, addTracingExtensions, startIdleTransaction, getActiveTransaction, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getClient, getCurrentScope } from '@sentry/core'; | ||
import { logger, propagationContextFromHeaders, getDomElement } from '@sentry/utils'; | ||
import { DEBUG_BUILD } from '../common/debug-build.js'; | ||
import { registerBackgroundTabDetection } from './backgroundtab.js'; | ||
import { startTrackingWebVitals, startTrackingLongTasks, startTrackingInteractions, addPerformanceEntries } from './metrics/index.js'; | ||
import { addPerformanceInstrumentationHandler } from './instrument.js'; | ||
import { startTrackingWebVitals, startTrackingINP, startTrackingLongTasks, startTrackingInteractions, addPerformanceEntries } from './metrics/index.js'; | ||
import { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request.js'; | ||
@@ -21,2 +22,3 @@ import { instrumentRoutingWithDefaults } from './router.js'; | ||
enableLongTask: true, | ||
enableInp: false, | ||
_experiments: {}, | ||
@@ -26,2 +28,5 @@ ...defaultRequestInstrumentationOptions, | ||
/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */ | ||
const MAX_INTERACTIONS = 10; | ||
/** | ||
@@ -83,2 +88,8 @@ * The Browser Tracing integration automatically instruments browser pageload/navigation | ||
this._collectWebVitals = startTrackingWebVitals(); | ||
/** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */ | ||
this._interactionIdtoRouteNameMapping = {}; | ||
if (this.options.enableInp) { | ||
startTrackingINP(this._interactionIdtoRouteNameMapping); | ||
} | ||
if (this.options.enableLongTask) { | ||
@@ -90,2 +101,7 @@ startTrackingLongTasks(); | ||
} | ||
this._latestRoute = { | ||
name: undefined, | ||
context: undefined, | ||
}; | ||
} | ||
@@ -155,2 +171,6 @@ | ||
if (this.options.enableInp) { | ||
this._registerInpInteractionListener(); | ||
} | ||
instrumentOutgoingRequests({ | ||
@@ -218,4 +238,4 @@ traceFetch, | ||
this._latestRouteName = finalContext.name; | ||
this._latestRouteSource = getSource(finalContext); | ||
this._latestRoute.name = finalContext.name; | ||
this._latestRoute.context = finalContext; | ||
@@ -290,3 +310,3 @@ // eslint-disable-next-line deprecation/deprecation | ||
if (!this._latestRouteName) { | ||
if (!this._latestRoute.name) { | ||
DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); | ||
@@ -300,7 +320,9 @@ return undefined; | ||
const context = { | ||
name: this._latestRouteName, | ||
name: this._latestRoute.name, | ||
op, | ||
trimEnd: true, | ||
data: { | ||
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRouteSource || 'url', | ||
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRoute.context | ||
? getSource(this._latestRoute.context) | ||
: 'url', | ||
}, | ||
@@ -324,2 +346,57 @@ }; | ||
} | ||
/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ | ||
_registerInpInteractionListener() { | ||
addPerformanceInstrumentationHandler('event', ({ entries }) => { | ||
const client = getClient(); | ||
// We need to get the replay, user, and activeTransaction from the current scope | ||
// so that we can associate replay id, profile id, and a user display to the span | ||
const replay = | ||
client !== undefined && client.getIntegrationByName !== undefined | ||
? (client.getIntegrationByName('Replay') ) | ||
: undefined; | ||
const replayId = replay !== undefined ? replay.getReplayId() : undefined; | ||
// eslint-disable-next-line deprecation/deprecation | ||
const activeTransaction = getActiveTransaction(); | ||
const currentScope = getCurrentScope(); | ||
const user = currentScope !== undefined ? currentScope.getUser() : undefined; | ||
for (const entry of entries) { | ||
if (isPerformanceEventTiming(entry)) { | ||
const duration = entry.duration; | ||
const keys = Object.keys(this._interactionIdtoRouteNameMapping); | ||
const minInteractionId = | ||
keys.length > 0 | ||
? keys.reduce((a, b) => { | ||
return this._interactionIdtoRouteNameMapping[a].duration < | ||
this._interactionIdtoRouteNameMapping[b].duration | ||
? a | ||
: b; | ||
}) | ||
: undefined; | ||
if ( | ||
minInteractionId === undefined || | ||
duration > this._interactionIdtoRouteNameMapping[minInteractionId].duration | ||
) { | ||
const interactionId = entry.interactionId; | ||
const routeName = this._latestRoute.name; | ||
const parentContext = this._latestRoute.context; | ||
if (interactionId && routeName && parentContext) { | ||
if (minInteractionId && Object.keys(this._interactionIdtoRouteNameMapping).length >= MAX_INTERACTIONS) { | ||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete | ||
delete this._interactionIdtoRouteNameMapping[minInteractionId]; | ||
} | ||
this._interactionIdtoRouteNameMapping[interactionId] = { | ||
routeName, | ||
duration, | ||
parentContext, | ||
user, | ||
activeTransaction, | ||
replayId, | ||
}; | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
@@ -347,3 +424,7 @@ | ||
function isPerformanceEventTiming(entry) { | ||
return 'duration' in entry; | ||
} | ||
export { BROWSER_TRACING_INTEGRATION_ID, BrowserTracing, getMetaContent }; | ||
//# sourceMappingURL=browsertracing.js.map |
@@ -182,3 +182,3 @@ import { getActiveTransaction, spanToJSON, setMeasurement, getClient, Span, createSpanEnvelope, hasTracingEnabled, isValidSampleRate } from '@sentry/core'; | ||
return addInpInstrumentationHandler(({ metric }) => { | ||
const entry = metric.entries.find(e => e.name === 'click'); | ||
const entry = metric.entries.find(e => e.name === 'click' || e.name === 'pointerdown'); | ||
const client = getClient(); | ||
@@ -231,3 +231,3 @@ if (!entry || !client) { | ||
if (Math.random() < (sampleRate )) { | ||
const envelope = span ? createSpanEnvelope([span]) : undefined; | ||
const envelope = span ? createSpanEnvelope([span], client.getDsn()) : undefined; | ||
const transport = client && client.getTransport(); | ||
@@ -234,0 +234,0 @@ if (transport && envelope) { |
{ | ||
"name": "@sentry-internal/tracing", | ||
"version": "7.106.1", | ||
"version": "7.107.0", | ||
"description": "Sentry Internal Tracing Package", | ||
@@ -32,5 +32,5 @@ "repository": "git://github.com/getsentry/sentry-javascript.git", | ||
"dependencies": { | ||
"@sentry/core": "7.106.1", | ||
"@sentry/types": "7.106.1", | ||
"@sentry/utils": "7.106.1" | ||
"@sentry/core": "7.107.0", | ||
"@sentry/types": "7.107.0", | ||
"@sentry/utils": "7.107.0" | ||
}, | ||
@@ -37,0 +37,0 @@ "devDependencies": { |
@@ -61,2 +61,8 @@ import { Hub } from '@sentry/core'; | ||
/** | ||
* If true, Sentry will capture INP web vitals as standalone spans . | ||
* | ||
* Default: false | ||
*/ | ||
enableInp: boolean; | ||
/** | ||
* _metricOptions allows the user to send options to change how metrics are collected. | ||
@@ -121,6 +127,6 @@ * | ||
private _getCurrentHub?; | ||
private _latestRouteName?; | ||
private _latestRouteSource?; | ||
private _collectWebVitals; | ||
private _hasSetTracePropagationTargets; | ||
private _interactionIdtoRouteNameMapping; | ||
private _latestRoute; | ||
constructor(_options?: Partial<BrowserTracingOptions>); | ||
@@ -135,2 +141,4 @@ /** | ||
private _registerInteractionListener; | ||
/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ | ||
private _registerInpInteractionListener; | ||
} | ||
@@ -137,0 +145,0 @@ /** Returns the value of a meta tag */ |
@@ -61,2 +61,8 @@ import type { Hub } from '@sentry/core'; | ||
/** | ||
* If true, Sentry will capture INP web vitals as standalone spans . | ||
* | ||
* Default: false | ||
*/ | ||
enableInp: boolean; | ||
/** | ||
* _metricOptions allows the user to send options to change how metrics are collected. | ||
@@ -121,6 +127,6 @@ * | ||
private _getCurrentHub?; | ||
private _latestRouteName?; | ||
private _latestRouteSource?; | ||
private _collectWebVitals; | ||
private _hasSetTracePropagationTargets; | ||
private _interactionIdtoRouteNameMapping; | ||
private _latestRoute; | ||
constructor(_options?: Partial<BrowserTracingOptions>); | ||
@@ -135,2 +141,4 @@ /** | ||
private _registerInteractionListener; | ||
/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ | ||
private _registerInpInteractionListener; | ||
} | ||
@@ -137,0 +145,0 @@ /** Returns the value of a meta tag */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1325118
11318
+ Added@sentry/core@7.107.0(transitive)
+ Added@sentry/types@7.107.0(transitive)
+ Added@sentry/utils@7.107.0(transitive)
- Removed@sentry/core@7.106.1(transitive)
- Removed@sentry/types@7.106.1(transitive)
- Removed@sentry/utils@7.106.1(transitive)
Updated@sentry/core@7.107.0
Updated@sentry/types@7.107.0
Updated@sentry/utils@7.107.0