123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- Object.defineProperty(exports, '__esModule', { value: true });
- const core = require('@sentry/core');
- const utils = require('@sentry/utils');
- const debugBuild = require('../common/debug-build.js');
- const backgroundtab = require('./backgroundtab.js');
- const index = require('./metrics/index.js');
- const request = require('./request.js');
- const types = require('./types.js');
- const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';
- const DEFAULT_BROWSER_TRACING_OPTIONS = {
- ...core.TRACING_DEFAULTS,
- instrumentNavigation: true,
- instrumentPageLoad: true,
- markBackgroundSpan: true,
- enableLongTask: true,
- _experiments: {},
- ...request.defaultRequestInstrumentationOptions,
- };
- const browserTracingIntegration = ((_options = {}) => {
- const _hasSetTracePropagationTargets = debugBuild.DEBUG_BUILD
- ? !!(
-
- (_options.tracePropagationTargets || _options.tracingOrigins)
- )
- : false;
- core.addTracingExtensions();
-
-
-
-
- if (!_options.tracePropagationTargets && _options.tracingOrigins) {
-
- _options.tracePropagationTargets = _options.tracingOrigins;
- }
- const options = {
- ...DEFAULT_BROWSER_TRACING_OPTIONS,
- ..._options,
- };
- const _collectWebVitals = index.startTrackingWebVitals();
- if (options.enableLongTask) {
- index.startTrackingLongTasks();
- }
- if (options._experiments.enableInteractions) {
- index.startTrackingInteractions();
- }
- let latestRouteName;
- let latestRouteSource;
-
- function _createRouteTransaction(context) {
-
- const hub = core.getCurrentHub();
- const { beforeStartSpan, idleTimeout, finalTimeout, heartbeatInterval } = options;
- const isPageloadTransaction = context.op === 'pageload';
- let expandedContext;
- if (isPageloadTransaction) {
- const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : '';
- const baggage = isPageloadTransaction ? getMetaContent('baggage') : undefined;
- const { traceId, dsc, parentSpanId, sampled } = utils.propagationContextFromHeaders(sentryTrace, baggage);
- expandedContext = {
- traceId,
- parentSpanId,
- parentSampled: sampled,
- ...context,
- metadata: {
-
- ...context.metadata,
- dynamicSamplingContext: dsc,
- },
- trimEnd: true,
- };
- } else {
- expandedContext = {
- trimEnd: true,
- ...context,
- };
- }
- const finalContext = beforeStartSpan ? beforeStartSpan(expandedContext) : expandedContext;
-
-
- finalContext.metadata =
- finalContext.name !== expandedContext.name
- ?
- { ...finalContext.metadata, source: 'custom' }
- :
- finalContext.metadata;
- latestRouteName = finalContext.name;
- latestRouteSource = getSource(finalContext);
- if (finalContext.sampled === false) {
- debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`);
- }
- debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`);
- const { location } = types.WINDOW;
- const idleTransaction = core.startIdleTransaction(
- hub,
- finalContext,
- idleTimeout,
- finalTimeout,
- true,
- { location },
- heartbeatInterval,
- isPageloadTransaction,
- );
- if (isPageloadTransaction) {
- types.WINDOW.document.addEventListener('readystatechange', () => {
- if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
- idleTransaction.sendAutoFinishSignal();
- }
- });
- if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
- idleTransaction.sendAutoFinishSignal();
- }
- }
- idleTransaction.registerBeforeFinishCallback(transaction => {
- _collectWebVitals();
- index.addPerformanceEntries(transaction);
- });
- return idleTransaction ;
- }
- return {
- name: BROWSER_TRACING_INTEGRATION_ID,
-
- setupOnce: () => {},
- afterAllSetup(client) {
- const clientOptions = client.getOptions();
- const { markBackgroundSpan, traceFetch, traceXHR, shouldCreateSpanForRequest, enableHTTPTimings, _experiments } =
- options;
- const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets;
-
-
-
-
-
-
-
-
-
-
-
- const tracePropagationTargets = clientOptionsTracePropagationTargets || options.tracePropagationTargets;
- if (debugBuild.DEBUG_BUILD && _hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) {
- utils.logger.warn(
- '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.',
- );
- }
- let activeSpan;
- let startingUrl = types.WINDOW.location.href;
- if (client.on) {
- client.on('startNavigationSpan', (context) => {
- if (activeSpan) {
- debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`);
-
- activeSpan.end();
- }
- activeSpan = _createRouteTransaction({
- op: 'navigation',
- ...context,
- });
- });
- client.on('startPageLoadSpan', (context) => {
- if (activeSpan) {
- debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`);
-
- activeSpan.end();
- }
- activeSpan = _createRouteTransaction({
- op: 'pageload',
- ...context,
- });
- });
- }
- if (options.instrumentPageLoad && client.emit) {
- const context = {
- name: types.WINDOW.location.pathname,
-
- startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined,
- origin: 'auto.pageload.browser',
- attributes: {
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
- },
- };
- startBrowserTracingPageLoadSpan(client, context);
- }
- if (options.instrumentNavigation && client.emit) {
- utils.addHistoryInstrumentationHandler(({ to, from }) => {
-
- if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) {
- startingUrl = undefined;
- return;
- }
- if (from !== to) {
- startingUrl = undefined;
- const context = {
- name: types.WINDOW.location.pathname,
- origin: 'auto.navigation.browser',
- attributes: {
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
- },
- };
- startBrowserTracingNavigationSpan(client, context);
- }
- });
- }
- if (markBackgroundSpan) {
- backgroundtab.registerBackgroundTabDetection();
- }
- if (_experiments.enableInteractions) {
- registerInteractionListener(options, latestRouteName, latestRouteSource);
- }
- request.instrumentOutgoingRequests({
- traceFetch,
- traceXHR,
- tracePropagationTargets,
- shouldCreateSpanForRequest,
- enableHTTPTimings,
- });
- },
-
-
- options,
- };
- }) ;
- function startBrowserTracingPageLoadSpan(client, spanOptions) {
- if (!client.emit) {
- return;
- }
- client.emit('startPageLoadSpan', spanOptions);
- const span = core.getActiveSpan();
- const op = span && core.spanToJSON(span).op;
- return op === 'pageload' ? span : undefined;
- }
- function startBrowserTracingNavigationSpan(client, spanOptions) {
- if (!client.emit) {
- return;
- }
- client.emit('startNavigationSpan', spanOptions);
- const span = core.getActiveSpan();
- const op = span && core.spanToJSON(span).op;
- return op === 'navigation' ? span : undefined;
- }
- function getMetaContent(metaName) {
-
-
-
- const metaTag = utils.getDomElement(`meta[name=${metaName}]`);
-
- return metaTag ? metaTag.getAttribute('content') : undefined;
- }
- function registerInteractionListener(
- options,
- latestRouteName,
- latestRouteSource,
- ) {
- let inflightInteractionTransaction;
- const registerInteractionTransaction = () => {
- const { idleTimeout, finalTimeout, heartbeatInterval } = options;
- const op = 'ui.action.click';
-
- const currentTransaction = core.getActiveTransaction();
- if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) {
- debugBuild.DEBUG_BUILD &&
- utils.logger.warn(
- `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`,
- );
- return undefined;
- }
- if (inflightInteractionTransaction) {
- inflightInteractionTransaction.setFinishReason('interactionInterrupted');
- inflightInteractionTransaction.end();
- inflightInteractionTransaction = undefined;
- }
- if (!latestRouteName) {
- debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);
- return undefined;
- }
- const { location } = types.WINDOW;
- const context = {
- name: latestRouteName,
- op,
- trimEnd: true,
- data: {
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRouteSource || 'url',
- },
- };
- inflightInteractionTransaction = core.startIdleTransaction(
-
- core.getCurrentHub(),
- context,
- idleTimeout,
- finalTimeout,
- true,
- { location },
- heartbeatInterval,
- );
- };
- ['click'].forEach(type => {
- addEventListener(type, registerInteractionTransaction, { once: false, capture: true });
- });
- }
- function getSource(context) {
- const sourceFromAttributes = context.attributes && context.attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
-
- const sourceFromData = context.data && context.data[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
-
- const sourceFromMetadata = context.metadata && context.metadata.source;
- return sourceFromAttributes || sourceFromData || sourceFromMetadata;
- }
- exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID;
- exports.browserTracingIntegration = browserTracingIntegration;
- exports.getMetaContent = getMetaContent;
- exports.startBrowserTracingNavigationSpan = startBrowserTracingNavigationSpan;
- exports.startBrowserTracingPageLoadSpan = startBrowserTracingPageLoadSpan;
|