@sentry/browser 10.53.1 → 10.54.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/build/npm/cjs/dev/client.js +15 -54
- package/build/npm/cjs/dev/client.js.map +1 -1
- package/build/npm/cjs/dev/debug-build.js +0 -5
- package/build/npm/cjs/dev/debug-build.js.map +1 -1
- package/build/npm/cjs/dev/diagnose-sdk.js +15 -37
- package/build/npm/cjs/dev/diagnose-sdk.js.map +1 -1
- package/build/npm/cjs/dev/eventbuilder.js +59 -217
- package/build/npm/cjs/dev/eventbuilder.js.map +1 -1
- package/build/npm/cjs/dev/feedbackAsync.js +1 -5
- package/build/npm/cjs/dev/feedbackAsync.js.map +1 -1
- package/build/npm/cjs/dev/feedbackSync.js +1 -2
- package/build/npm/cjs/dev/feedbackSync.js.map +1 -1
- package/build/npm/cjs/dev/helpers.js +24 -102
- package/build/npm/cjs/dev/helpers.js.map +1 -1
- package/build/npm/cjs/dev/index.js +2 -0
- package/build/npm/cjs/dev/index.js.map +1 -1
- package/build/npm/cjs/dev/integrations/breadcrumbs.js +52 -134
- package/build/npm/cjs/dev/integrations/breadcrumbs.js.map +1 -1
- package/build/npm/cjs/dev/integrations/browserapierrors.js +45 -111
- package/build/npm/cjs/dev/integrations/browserapierrors.js.map +1 -1
- package/build/npm/cjs/dev/integrations/browsersession.js +7 -35
- package/build/npm/cjs/dev/integrations/browsersession.js.map +1 -1
- package/build/npm/cjs/dev/integrations/contextlines.js +9 -45
- package/build/npm/cjs/dev/integrations/contextlines.js.map +1 -1
- package/build/npm/cjs/dev/integrations/culturecontext.js +11 -36
- package/build/npm/cjs/dev/integrations/culturecontext.js.map +1 -1
- package/build/npm/cjs/dev/integrations/featureFlags/growthbook/integration.js +1 -22
- package/build/npm/cjs/dev/integrations/featureFlags/growthbook/integration.js.map +1 -1
- package/build/npm/cjs/dev/integrations/featureFlags/launchdarkly/integration.js +6 -31
- package/build/npm/cjs/dev/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
- package/build/npm/cjs/dev/integrations/featureFlags/openfeature/integration.js +6 -12
- package/build/npm/cjs/dev/integrations/featureFlags/openfeature/integration.js.map +1 -1
- package/build/npm/cjs/dev/integrations/featureFlags/statsig/integration.js +5 -30
- package/build/npm/cjs/dev/integrations/featureFlags/statsig/integration.js.map +1 -1
- package/build/npm/cjs/dev/integrations/featureFlags/unleash/integration.js +10 -47
- package/build/npm/cjs/dev/integrations/featureFlags/unleash/integration.js.map +1 -1
- package/build/npm/cjs/dev/integrations/fetchStreamPerformance.js +60 -0
- package/build/npm/cjs/dev/integrations/fetchStreamPerformance.js.map +1 -0
- package/build/npm/cjs/dev/integrations/globalhandlers.js +38 -99
- package/build/npm/cjs/dev/integrations/globalhandlers.js.map +1 -1
- package/build/npm/cjs/dev/integrations/graphqlClient.js +31 -119
- package/build/npm/cjs/dev/integrations/graphqlClient.js.map +1 -1
- package/build/npm/cjs/dev/integrations/httpclient.js +43 -203
- package/build/npm/cjs/dev/integrations/httpclient.js.map +1 -1
- package/build/npm/cjs/dev/integrations/httpcontext.js +7 -17
- package/build/npm/cjs/dev/integrations/httpcontext.js.map +1 -1
- package/build/npm/cjs/dev/integrations/linkederrors.js +7 -15
- package/build/npm/cjs/dev/integrations/linkederrors.js.map +1 -1
- package/build/npm/cjs/dev/integrations/reportingobserver.js +19 -44
- package/build/npm/cjs/dev/integrations/reportingobserver.js.map +1 -1
- package/build/npm/cjs/dev/integrations/spanstreaming.js +11 -29
- package/build/npm/cjs/dev/integrations/spanstreaming.js.map +1 -1
- package/build/npm/cjs/dev/integrations/spotlight.js +17 -30
- package/build/npm/cjs/dev/integrations/spotlight.js.map +1 -1
- package/build/npm/cjs/dev/integrations/view-hierarchy.js +19 -46
- package/build/npm/cjs/dev/integrations/view-hierarchy.js.map +1 -1
- package/build/npm/cjs/dev/integrations/webWorker.js +40 -211
- package/build/npm/cjs/dev/integrations/webWorker.js.map +1 -1
- package/build/npm/cjs/dev/profiling/UIProfiler.js +87 -190
- package/build/npm/cjs/dev/profiling/UIProfiler.js.map +1 -1
- package/build/npm/cjs/dev/profiling/index.js +9 -30
- package/build/npm/cjs/dev/profiling/index.js.map +1 -1
- package/build/npm/cjs/dev/profiling/integration.js +30 -64
- package/build/npm/cjs/dev/profiling/integration.js.map +1 -1
- package/build/npm/cjs/dev/profiling/startProfileForSpan.js +28 -84
- package/build/npm/cjs/dev/profiling/startProfileForSpan.js.map +1 -1
- package/build/npm/cjs/dev/profiling/utils.js +131 -398
- package/build/npm/cjs/dev/profiling/utils.js.map +1 -1
- package/build/npm/cjs/dev/report-dialog.js +10 -25
- package/build/npm/cjs/dev/report-dialog.js.map +1 -1
- package/build/npm/cjs/dev/sdk.js +8 -76
- package/build/npm/cjs/dev/sdk.js.map +1 -1
- package/build/npm/cjs/dev/stack-parsers.js +42 -126
- package/build/npm/cjs/dev/stack-parsers.js.map +1 -1
- package/build/npm/cjs/dev/tracing/backgroundtab.js +4 -16
- package/build/npm/cjs/dev/tracing/backgroundtab.js.map +1 -1
- package/build/npm/cjs/dev/tracing/browserTracingIntegration.js +102 -291
- package/build/npm/cjs/dev/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/cjs/dev/tracing/linkedTraces.js +25 -116
- package/build/npm/cjs/dev/tracing/linkedTraces.js.map +1 -1
- package/build/npm/cjs/dev/tracing/reportPageLoaded.js +1 -9
- package/build/npm/cjs/dev/tracing/reportPageLoaded.js.map +1 -1
- package/build/npm/cjs/dev/tracing/request.js +58 -223
- package/build/npm/cjs/dev/tracing/request.js.map +1 -1
- package/build/npm/cjs/dev/tracing/setActiveSpan.js +1 -48
- package/build/npm/cjs/dev/tracing/setActiveSpan.js.map +1 -1
- package/build/npm/cjs/dev/tracing/utils.js +4 -27
- package/build/npm/cjs/dev/tracing/utils.js.map +1 -1
- package/build/npm/cjs/dev/transports/fetch.js +10 -23
- package/build/npm/cjs/dev/transports/fetch.js.map +1 -1
- package/build/npm/cjs/dev/transports/offline.js +27 -84
- package/build/npm/cjs/dev/transports/offline.js.map +1 -1
- package/build/npm/cjs/dev/userfeedback.js +12 -22
- package/build/npm/cjs/dev/userfeedback.js.map +1 -1
- package/build/npm/cjs/dev/utils/detectBrowserExtension.js +5 -26
- package/build/npm/cjs/dev/utils/detectBrowserExtension.js.map +1 -1
- package/build/npm/cjs/dev/utils/lazyLoadIntegration.js +40 -75
- package/build/npm/cjs/dev/utils/lazyLoadIntegration.js.map +1 -1
- package/build/npm/cjs/prod/client.js +15 -54
- package/build/npm/cjs/prod/client.js.map +1 -1
- package/build/npm/cjs/prod/debug-build.js +0 -5
- package/build/npm/cjs/prod/debug-build.js.map +1 -1
- package/build/npm/cjs/prod/diagnose-sdk.js +15 -37
- package/build/npm/cjs/prod/diagnose-sdk.js.map +1 -1
- package/build/npm/cjs/prod/eventbuilder.js +59 -217
- package/build/npm/cjs/prod/eventbuilder.js.map +1 -1
- package/build/npm/cjs/prod/feedbackAsync.js +1 -5
- package/build/npm/cjs/prod/feedbackAsync.js.map +1 -1
- package/build/npm/cjs/prod/feedbackSync.js +1 -2
- package/build/npm/cjs/prod/feedbackSync.js.map +1 -1
- package/build/npm/cjs/prod/helpers.js +24 -102
- package/build/npm/cjs/prod/helpers.js.map +1 -1
- package/build/npm/cjs/prod/index.js +2 -0
- package/build/npm/cjs/prod/index.js.map +1 -1
- package/build/npm/cjs/prod/integrations/breadcrumbs.js +52 -134
- package/build/npm/cjs/prod/integrations/breadcrumbs.js.map +1 -1
- package/build/npm/cjs/prod/integrations/browserapierrors.js +45 -111
- package/build/npm/cjs/prod/integrations/browserapierrors.js.map +1 -1
- package/build/npm/cjs/prod/integrations/browsersession.js +7 -35
- package/build/npm/cjs/prod/integrations/browsersession.js.map +1 -1
- package/build/npm/cjs/prod/integrations/contextlines.js +9 -45
- package/build/npm/cjs/prod/integrations/contextlines.js.map +1 -1
- package/build/npm/cjs/prod/integrations/culturecontext.js +11 -36
- package/build/npm/cjs/prod/integrations/culturecontext.js.map +1 -1
- package/build/npm/cjs/prod/integrations/featureFlags/growthbook/integration.js +1 -22
- package/build/npm/cjs/prod/integrations/featureFlags/growthbook/integration.js.map +1 -1
- package/build/npm/cjs/prod/integrations/featureFlags/launchdarkly/integration.js +6 -31
- package/build/npm/cjs/prod/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
- package/build/npm/cjs/prod/integrations/featureFlags/openfeature/integration.js +6 -12
- package/build/npm/cjs/prod/integrations/featureFlags/openfeature/integration.js.map +1 -1
- package/build/npm/cjs/prod/integrations/featureFlags/statsig/integration.js +5 -30
- package/build/npm/cjs/prod/integrations/featureFlags/statsig/integration.js.map +1 -1
- package/build/npm/cjs/prod/integrations/featureFlags/unleash/integration.js +10 -47
- package/build/npm/cjs/prod/integrations/featureFlags/unleash/integration.js.map +1 -1
- package/build/npm/cjs/prod/integrations/fetchStreamPerformance.js +60 -0
- package/build/npm/cjs/prod/integrations/fetchStreamPerformance.js.map +1 -0
- package/build/npm/cjs/prod/integrations/globalhandlers.js +38 -99
- package/build/npm/cjs/prod/integrations/globalhandlers.js.map +1 -1
- package/build/npm/cjs/prod/integrations/graphqlClient.js +31 -119
- package/build/npm/cjs/prod/integrations/graphqlClient.js.map +1 -1
- package/build/npm/cjs/prod/integrations/httpclient.js +43 -203
- package/build/npm/cjs/prod/integrations/httpclient.js.map +1 -1
- package/build/npm/cjs/prod/integrations/httpcontext.js +7 -17
- package/build/npm/cjs/prod/integrations/httpcontext.js.map +1 -1
- package/build/npm/cjs/prod/integrations/linkederrors.js +7 -15
- package/build/npm/cjs/prod/integrations/linkederrors.js.map +1 -1
- package/build/npm/cjs/prod/integrations/reportingobserver.js +19 -44
- package/build/npm/cjs/prod/integrations/reportingobserver.js.map +1 -1
- package/build/npm/cjs/prod/integrations/spanstreaming.js +11 -29
- package/build/npm/cjs/prod/integrations/spanstreaming.js.map +1 -1
- package/build/npm/cjs/prod/integrations/spotlight.js +17 -30
- package/build/npm/cjs/prod/integrations/spotlight.js.map +1 -1
- package/build/npm/cjs/prod/integrations/view-hierarchy.js +19 -46
- package/build/npm/cjs/prod/integrations/view-hierarchy.js.map +1 -1
- package/build/npm/cjs/prod/integrations/webWorker.js +40 -211
- package/build/npm/cjs/prod/integrations/webWorker.js.map +1 -1
- package/build/npm/cjs/prod/profiling/UIProfiler.js +87 -190
- package/build/npm/cjs/prod/profiling/UIProfiler.js.map +1 -1
- package/build/npm/cjs/prod/profiling/index.js +9 -30
- package/build/npm/cjs/prod/profiling/index.js.map +1 -1
- package/build/npm/cjs/prod/profiling/integration.js +30 -64
- package/build/npm/cjs/prod/profiling/integration.js.map +1 -1
- package/build/npm/cjs/prod/profiling/startProfileForSpan.js +28 -84
- package/build/npm/cjs/prod/profiling/startProfileForSpan.js.map +1 -1
- package/build/npm/cjs/prod/profiling/utils.js +131 -398
- package/build/npm/cjs/prod/profiling/utils.js.map +1 -1
- package/build/npm/cjs/prod/report-dialog.js +10 -25
- package/build/npm/cjs/prod/report-dialog.js.map +1 -1
- package/build/npm/cjs/prod/sdk.js +5 -73
- package/build/npm/cjs/prod/sdk.js.map +1 -1
- package/build/npm/cjs/prod/stack-parsers.js +42 -126
- package/build/npm/cjs/prod/stack-parsers.js.map +1 -1
- package/build/npm/cjs/prod/tracing/backgroundtab.js +4 -16
- package/build/npm/cjs/prod/tracing/backgroundtab.js.map +1 -1
- package/build/npm/cjs/prod/tracing/browserTracingIntegration.js +102 -291
- package/build/npm/cjs/prod/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/cjs/prod/tracing/linkedTraces.js +25 -117
- package/build/npm/cjs/prod/tracing/linkedTraces.js.map +1 -1
- package/build/npm/cjs/prod/tracing/reportPageLoaded.js +1 -9
- package/build/npm/cjs/prod/tracing/reportPageLoaded.js.map +1 -1
- package/build/npm/cjs/prod/tracing/request.js +58 -223
- package/build/npm/cjs/prod/tracing/request.js.map +1 -1
- package/build/npm/cjs/prod/tracing/setActiveSpan.js +1 -48
- package/build/npm/cjs/prod/tracing/setActiveSpan.js.map +1 -1
- package/build/npm/cjs/prod/tracing/utils.js +4 -27
- package/build/npm/cjs/prod/tracing/utils.js.map +1 -1
- package/build/npm/cjs/prod/transports/fetch.js +10 -23
- package/build/npm/cjs/prod/transports/fetch.js.map +1 -1
- package/build/npm/cjs/prod/transports/offline.js +27 -84
- package/build/npm/cjs/prod/transports/offline.js.map +1 -1
- package/build/npm/cjs/prod/userfeedback.js +12 -22
- package/build/npm/cjs/prod/userfeedback.js.map +1 -1
- package/build/npm/cjs/prod/utils/detectBrowserExtension.js +5 -26
- package/build/npm/cjs/prod/utils/detectBrowserExtension.js.map +1 -1
- package/build/npm/cjs/prod/utils/lazyLoadIntegration.js +40 -75
- package/build/npm/cjs/prod/utils/lazyLoadIntegration.js.map +1 -1
- package/build/npm/esm/dev/client.js +15 -54
- package/build/npm/esm/dev/client.js.map +1 -1
- package/build/npm/esm/dev/debug-build.js +0 -5
- package/build/npm/esm/dev/debug-build.js.map +1 -1
- package/build/npm/esm/dev/diagnose-sdk.js +15 -37
- package/build/npm/esm/dev/diagnose-sdk.js.map +1 -1
- package/build/npm/esm/dev/eventbuilder.js +59 -217
- package/build/npm/esm/dev/eventbuilder.js.map +1 -1
- package/build/npm/esm/dev/feedbackAsync.js +1 -5
- package/build/npm/esm/dev/feedbackAsync.js.map +1 -1
- package/build/npm/esm/dev/feedbackSync.js +1 -2
- package/build/npm/esm/dev/feedbackSync.js.map +1 -1
- package/build/npm/esm/dev/helpers.js +24 -102
- package/build/npm/esm/dev/helpers.js.map +1 -1
- package/build/npm/esm/dev/index.js +1 -0
- package/build/npm/esm/dev/index.js.map +1 -1
- package/build/npm/esm/dev/integrations/breadcrumbs.js +52 -134
- package/build/npm/esm/dev/integrations/breadcrumbs.js.map +1 -1
- package/build/npm/esm/dev/integrations/browserapierrors.js +45 -111
- package/build/npm/esm/dev/integrations/browserapierrors.js.map +1 -1
- package/build/npm/esm/dev/integrations/browsersession.js +7 -35
- package/build/npm/esm/dev/integrations/browsersession.js.map +1 -1
- package/build/npm/esm/dev/integrations/contextlines.js +9 -45
- package/build/npm/esm/dev/integrations/contextlines.js.map +1 -1
- package/build/npm/esm/dev/integrations/culturecontext.js +11 -36
- package/build/npm/esm/dev/integrations/culturecontext.js.map +1 -1
- package/build/npm/esm/dev/integrations/featureFlags/growthbook/integration.js +1 -22
- package/build/npm/esm/dev/integrations/featureFlags/growthbook/integration.js.map +1 -1
- package/build/npm/esm/dev/integrations/featureFlags/launchdarkly/integration.js +6 -31
- package/build/npm/esm/dev/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
- package/build/npm/esm/dev/integrations/featureFlags/openfeature/integration.js +6 -12
- package/build/npm/esm/dev/integrations/featureFlags/openfeature/integration.js.map +1 -1
- package/build/npm/esm/dev/integrations/featureFlags/statsig/integration.js +5 -30
- package/build/npm/esm/dev/integrations/featureFlags/statsig/integration.js.map +1 -1
- package/build/npm/esm/dev/integrations/featureFlags/unleash/integration.js +10 -47
- package/build/npm/esm/dev/integrations/featureFlags/unleash/integration.js.map +1 -1
- package/build/npm/esm/dev/integrations/fetchStreamPerformance.js +58 -0
- package/build/npm/esm/dev/integrations/fetchStreamPerformance.js.map +1 -0
- package/build/npm/esm/dev/integrations/globalhandlers.js +38 -99
- package/build/npm/esm/dev/integrations/globalhandlers.js.map +1 -1
- package/build/npm/esm/dev/integrations/graphqlClient.js +31 -119
- package/build/npm/esm/dev/integrations/graphqlClient.js.map +1 -1
- package/build/npm/esm/dev/integrations/httpclient.js +43 -203
- package/build/npm/esm/dev/integrations/httpclient.js.map +1 -1
- package/build/npm/esm/dev/integrations/httpcontext.js +7 -17
- package/build/npm/esm/dev/integrations/httpcontext.js.map +1 -1
- package/build/npm/esm/dev/integrations/linkederrors.js +7 -15
- package/build/npm/esm/dev/integrations/linkederrors.js.map +1 -1
- package/build/npm/esm/dev/integrations/reportingobserver.js +19 -44
- package/build/npm/esm/dev/integrations/reportingobserver.js.map +1 -1
- package/build/npm/esm/dev/integrations/spanstreaming.js +11 -29
- package/build/npm/esm/dev/integrations/spanstreaming.js.map +1 -1
- package/build/npm/esm/dev/integrations/spotlight.js +17 -30
- package/build/npm/esm/dev/integrations/spotlight.js.map +1 -1
- package/build/npm/esm/dev/integrations/view-hierarchy.js +19 -46
- package/build/npm/esm/dev/integrations/view-hierarchy.js.map +1 -1
- package/build/npm/esm/dev/integrations/webWorker.js +40 -211
- package/build/npm/esm/dev/integrations/webWorker.js.map +1 -1
- package/build/npm/esm/dev/package.json +1 -1
- package/build/npm/esm/dev/profiling/UIProfiler.js +87 -190
- package/build/npm/esm/dev/profiling/UIProfiler.js.map +1 -1
- package/build/npm/esm/dev/profiling/index.js +9 -30
- package/build/npm/esm/dev/profiling/index.js.map +1 -1
- package/build/npm/esm/dev/profiling/integration.js +30 -64
- package/build/npm/esm/dev/profiling/integration.js.map +1 -1
- package/build/npm/esm/dev/profiling/startProfileForSpan.js +28 -84
- package/build/npm/esm/dev/profiling/startProfileForSpan.js.map +1 -1
- package/build/npm/esm/dev/profiling/utils.js +131 -398
- package/build/npm/esm/dev/profiling/utils.js.map +1 -1
- package/build/npm/esm/dev/report-dialog.js +10 -25
- package/build/npm/esm/dev/report-dialog.js.map +1 -1
- package/build/npm/esm/dev/sdk.js +8 -76
- package/build/npm/esm/dev/sdk.js.map +1 -1
- package/build/npm/esm/dev/stack-parsers.js +42 -126
- package/build/npm/esm/dev/stack-parsers.js.map +1 -1
- package/build/npm/esm/dev/tracing/backgroundtab.js +4 -16
- package/build/npm/esm/dev/tracing/backgroundtab.js.map +1 -1
- package/build/npm/esm/dev/tracing/browserTracingIntegration.js +102 -291
- package/build/npm/esm/dev/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/esm/dev/tracing/linkedTraces.js +25 -116
- package/build/npm/esm/dev/tracing/linkedTraces.js.map +1 -1
- package/build/npm/esm/dev/tracing/reportPageLoaded.js +1 -9
- package/build/npm/esm/dev/tracing/reportPageLoaded.js.map +1 -1
- package/build/npm/esm/dev/tracing/request.js +59 -224
- package/build/npm/esm/dev/tracing/request.js.map +1 -1
- package/build/npm/esm/dev/tracing/setActiveSpan.js +1 -48
- package/build/npm/esm/dev/tracing/setActiveSpan.js.map +1 -1
- package/build/npm/esm/dev/tracing/utils.js +4 -27
- package/build/npm/esm/dev/tracing/utils.js.map +1 -1
- package/build/npm/esm/dev/transports/fetch.js +10 -23
- package/build/npm/esm/dev/transports/fetch.js.map +1 -1
- package/build/npm/esm/dev/transports/offline.js +27 -84
- package/build/npm/esm/dev/transports/offline.js.map +1 -1
- package/build/npm/esm/dev/userfeedback.js +12 -22
- package/build/npm/esm/dev/userfeedback.js.map +1 -1
- package/build/npm/esm/dev/utils/detectBrowserExtension.js +5 -26
- package/build/npm/esm/dev/utils/detectBrowserExtension.js.map +1 -1
- package/build/npm/esm/dev/utils/lazyLoadIntegration.js +40 -75
- package/build/npm/esm/dev/utils/lazyLoadIntegration.js.map +1 -1
- package/build/npm/esm/prod/client.js +15 -54
- package/build/npm/esm/prod/client.js.map +1 -1
- package/build/npm/esm/prod/debug-build.js +0 -5
- package/build/npm/esm/prod/debug-build.js.map +1 -1
- package/build/npm/esm/prod/diagnose-sdk.js +15 -37
- package/build/npm/esm/prod/diagnose-sdk.js.map +1 -1
- package/build/npm/esm/prod/eventbuilder.js +59 -217
- package/build/npm/esm/prod/eventbuilder.js.map +1 -1
- package/build/npm/esm/prod/feedbackAsync.js +1 -5
- package/build/npm/esm/prod/feedbackAsync.js.map +1 -1
- package/build/npm/esm/prod/feedbackSync.js +1 -2
- package/build/npm/esm/prod/feedbackSync.js.map +1 -1
- package/build/npm/esm/prod/helpers.js +24 -102
- package/build/npm/esm/prod/helpers.js.map +1 -1
- package/build/npm/esm/prod/index.js +1 -0
- package/build/npm/esm/prod/index.js.map +1 -1
- package/build/npm/esm/prod/integrations/breadcrumbs.js +52 -134
- package/build/npm/esm/prod/integrations/breadcrumbs.js.map +1 -1
- package/build/npm/esm/prod/integrations/browserapierrors.js +45 -111
- package/build/npm/esm/prod/integrations/browserapierrors.js.map +1 -1
- package/build/npm/esm/prod/integrations/browsersession.js +7 -35
- package/build/npm/esm/prod/integrations/browsersession.js.map +1 -1
- package/build/npm/esm/prod/integrations/contextlines.js +9 -45
- package/build/npm/esm/prod/integrations/contextlines.js.map +1 -1
- package/build/npm/esm/prod/integrations/culturecontext.js +11 -36
- package/build/npm/esm/prod/integrations/culturecontext.js.map +1 -1
- package/build/npm/esm/prod/integrations/featureFlags/growthbook/integration.js +1 -22
- package/build/npm/esm/prod/integrations/featureFlags/growthbook/integration.js.map +1 -1
- package/build/npm/esm/prod/integrations/featureFlags/launchdarkly/integration.js +6 -31
- package/build/npm/esm/prod/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
- package/build/npm/esm/prod/integrations/featureFlags/openfeature/integration.js +6 -12
- package/build/npm/esm/prod/integrations/featureFlags/openfeature/integration.js.map +1 -1
- package/build/npm/esm/prod/integrations/featureFlags/statsig/integration.js +5 -30
- package/build/npm/esm/prod/integrations/featureFlags/statsig/integration.js.map +1 -1
- package/build/npm/esm/prod/integrations/featureFlags/unleash/integration.js +10 -47
- package/build/npm/esm/prod/integrations/featureFlags/unleash/integration.js.map +1 -1
- package/build/npm/esm/prod/integrations/fetchStreamPerformance.js +58 -0
- package/build/npm/esm/prod/integrations/fetchStreamPerformance.js.map +1 -0
- package/build/npm/esm/prod/integrations/globalhandlers.js +38 -99
- package/build/npm/esm/prod/integrations/globalhandlers.js.map +1 -1
- package/build/npm/esm/prod/integrations/graphqlClient.js +31 -119
- package/build/npm/esm/prod/integrations/graphqlClient.js.map +1 -1
- package/build/npm/esm/prod/integrations/httpclient.js +43 -203
- package/build/npm/esm/prod/integrations/httpclient.js.map +1 -1
- package/build/npm/esm/prod/integrations/httpcontext.js +7 -17
- package/build/npm/esm/prod/integrations/httpcontext.js.map +1 -1
- package/build/npm/esm/prod/integrations/linkederrors.js +7 -15
- package/build/npm/esm/prod/integrations/linkederrors.js.map +1 -1
- package/build/npm/esm/prod/integrations/reportingobserver.js +19 -44
- package/build/npm/esm/prod/integrations/reportingobserver.js.map +1 -1
- package/build/npm/esm/prod/integrations/spanstreaming.js +11 -29
- package/build/npm/esm/prod/integrations/spanstreaming.js.map +1 -1
- package/build/npm/esm/prod/integrations/spotlight.js +17 -30
- package/build/npm/esm/prod/integrations/spotlight.js.map +1 -1
- package/build/npm/esm/prod/integrations/view-hierarchy.js +19 -46
- package/build/npm/esm/prod/integrations/view-hierarchy.js.map +1 -1
- package/build/npm/esm/prod/integrations/webWorker.js +40 -211
- package/build/npm/esm/prod/integrations/webWorker.js.map +1 -1
- package/build/npm/esm/prod/package.json +1 -1
- package/build/npm/esm/prod/profiling/UIProfiler.js +87 -190
- package/build/npm/esm/prod/profiling/UIProfiler.js.map +1 -1
- package/build/npm/esm/prod/profiling/index.js +9 -30
- package/build/npm/esm/prod/profiling/index.js.map +1 -1
- package/build/npm/esm/prod/profiling/integration.js +30 -64
- package/build/npm/esm/prod/profiling/integration.js.map +1 -1
- package/build/npm/esm/prod/profiling/startProfileForSpan.js +28 -84
- package/build/npm/esm/prod/profiling/startProfileForSpan.js.map +1 -1
- package/build/npm/esm/prod/profiling/utils.js +131 -398
- package/build/npm/esm/prod/profiling/utils.js.map +1 -1
- package/build/npm/esm/prod/report-dialog.js +10 -25
- package/build/npm/esm/prod/report-dialog.js.map +1 -1
- package/build/npm/esm/prod/sdk.js +5 -73
- package/build/npm/esm/prod/sdk.js.map +1 -1
- package/build/npm/esm/prod/stack-parsers.js +42 -126
- package/build/npm/esm/prod/stack-parsers.js.map +1 -1
- package/build/npm/esm/prod/tracing/backgroundtab.js +4 -16
- package/build/npm/esm/prod/tracing/backgroundtab.js.map +1 -1
- package/build/npm/esm/prod/tracing/browserTracingIntegration.js +102 -291
- package/build/npm/esm/prod/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/esm/prod/tracing/linkedTraces.js +25 -117
- package/build/npm/esm/prod/tracing/linkedTraces.js.map +1 -1
- package/build/npm/esm/prod/tracing/reportPageLoaded.js +1 -9
- package/build/npm/esm/prod/tracing/reportPageLoaded.js.map +1 -1
- package/build/npm/esm/prod/tracing/request.js +59 -224
- package/build/npm/esm/prod/tracing/request.js.map +1 -1
- package/build/npm/esm/prod/tracing/setActiveSpan.js +1 -48
- package/build/npm/esm/prod/tracing/setActiveSpan.js.map +1 -1
- package/build/npm/esm/prod/tracing/utils.js +4 -27
- package/build/npm/esm/prod/tracing/utils.js.map +1 -1
- package/build/npm/esm/prod/transports/fetch.js +10 -23
- package/build/npm/esm/prod/transports/fetch.js.map +1 -1
- package/build/npm/esm/prod/transports/offline.js +27 -84
- package/build/npm/esm/prod/transports/offline.js.map +1 -1
- package/build/npm/esm/prod/userfeedback.js +12 -22
- package/build/npm/esm/prod/userfeedback.js.map +1 -1
- package/build/npm/esm/prod/utils/detectBrowserExtension.js +5 -26
- package/build/npm/esm/prod/utils/detectBrowserExtension.js.map +1 -1
- package/build/npm/esm/prod/utils/lazyLoadIntegration.js +40 -75
- package/build/npm/esm/prod/utils/lazyLoadIntegration.js.map +1 -1
- package/build/npm/types/eventbuilder.d.ts.map +1 -1
- package/build/npm/types/helpers.d.ts.map +1 -1
- package/build/npm/types/index.bundle.d.ts +2 -2
- package/build/npm/types/index.bundle.d.ts.map +1 -1
- package/build/npm/types/index.bundle.feedback.d.ts +2 -2
- package/build/npm/types/index.bundle.feedback.d.ts.map +1 -1
- package/build/npm/types/index.bundle.logs.metrics.d.ts +2 -2
- package/build/npm/types/index.bundle.logs.metrics.d.ts.map +1 -1
- package/build/npm/types/index.bundle.replay.d.ts +2 -2
- package/build/npm/types/index.bundle.replay.d.ts.map +1 -1
- package/build/npm/types/index.bundle.replay.feedback.d.ts +2 -2
- package/build/npm/types/index.bundle.replay.feedback.d.ts.map +1 -1
- package/build/npm/types/index.bundle.replay.logs.metrics.d.ts +2 -2
- package/build/npm/types/index.bundle.replay.logs.metrics.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.logs.metrics.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.logs.metrics.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.replay.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.replay.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.replay.feedback.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.replay.feedback.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.replay.feedback.logs.metrics.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.replay.feedback.logs.metrics.d.ts.map +1 -1
- package/build/npm/types/index.bundle.tracing.replay.logs.metrics.d.ts +1 -0
- package/build/npm/types/index.bundle.tracing.replay.logs.metrics.d.ts.map +1 -1
- package/build/npm/types/index.d.ts +1 -0
- package/build/npm/types/index.d.ts.map +1 -1
- package/build/npm/types/integrations/fetchStreamPerformance.d.ts +14 -0
- package/build/npm/types/integrations/fetchStreamPerformance.d.ts.map +1 -0
- package/build/npm/types/tracing/browserTracingIntegration.d.ts +3 -0
- package/build/npm/types/tracing/browserTracingIntegration.d.ts.map +1 -1
- package/build/npm/types/tracing/request.d.ts +3 -0
- package/build/npm/types/tracing/request.d.ts.map +1 -1
- package/build/npm/types-ts3.8/index.bundle.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.feedback.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.logs.metrics.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.replay.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.replay.feedback.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.replay.logs.metrics.d.ts +2 -2
- package/build/npm/types-ts3.8/index.bundle.tracing.d.ts +1 -0
- package/build/npm/types-ts3.8/index.bundle.tracing.logs.metrics.d.ts +1 -0
- package/build/npm/types-ts3.8/index.bundle.tracing.replay.d.ts +1 -0
- package/build/npm/types-ts3.8/index.bundle.tracing.replay.feedback.d.ts +1 -0
- package/build/npm/types-ts3.8/index.bundle.tracing.replay.feedback.logs.metrics.d.ts +1 -0
- package/build/npm/types-ts3.8/index.bundle.tracing.replay.logs.metrics.d.ts +1 -0
- package/build/npm/types-ts3.8/index.d.ts +1 -0
- package/build/npm/types-ts3.8/integrations/fetchStreamPerformance.d.ts +14 -0
- package/build/npm/types-ts3.8/tracing/browserTracingIntegration.d.ts +3 -0
- package/build/npm/types-ts3.8/tracing/request.d.ts +3 -0
- package/package.json +7 -7
|
@@ -1,56 +1,35 @@
|
|
|
1
1
|
import { getClient, debug } from '@sentry/core/browser';
|
|
2
2
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Starts the Sentry UI profiler.
|
|
6
|
-
* This mode is exclusive with the transaction profiler and will only work if the profilesSampleRate is set to a falsy value.
|
|
7
|
-
* In UI profiling mode, the profiler will keep reporting profile chunks to Sentry until it is stopped, which allows for continuous profiling of the application.
|
|
8
|
-
*/
|
|
9
4
|
function startProfiler() {
|
|
10
5
|
const client = getClient();
|
|
11
6
|
if (!client) {
|
|
12
|
-
DEBUG_BUILD && debug.warn(
|
|
7
|
+
DEBUG_BUILD && debug.warn("No Sentry client available, profiling is not started");
|
|
13
8
|
return;
|
|
14
9
|
}
|
|
15
|
-
|
|
16
|
-
const integration = client.getIntegrationByName('BrowserProfiling');
|
|
17
|
-
|
|
10
|
+
const integration = client.getIntegrationByName("BrowserProfiling");
|
|
18
11
|
if (!integration) {
|
|
19
|
-
DEBUG_BUILD && debug.warn(
|
|
12
|
+
DEBUG_BUILD && debug.warn("BrowserProfiling integration is not available");
|
|
20
13
|
return;
|
|
21
14
|
}
|
|
22
|
-
|
|
23
|
-
client.emit('startUIProfiler');
|
|
15
|
+
client.emit("startUIProfiler");
|
|
24
16
|
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Stops the Sentry UI profiler.
|
|
28
|
-
* Calls to stop will stop the profiler and flush the currently collected profile data to Sentry.
|
|
29
|
-
*/
|
|
30
17
|
function stopProfiler() {
|
|
31
18
|
const client = getClient();
|
|
32
19
|
if (!client) {
|
|
33
|
-
DEBUG_BUILD && debug.warn(
|
|
20
|
+
DEBUG_BUILD && debug.warn("No Sentry client available, profiling is not started");
|
|
34
21
|
return;
|
|
35
22
|
}
|
|
36
|
-
|
|
37
|
-
const integration = client.getIntegrationByName('BrowserProfiling');
|
|
23
|
+
const integration = client.getIntegrationByName("BrowserProfiling");
|
|
38
24
|
if (!integration) {
|
|
39
|
-
DEBUG_BUILD && debug.warn(
|
|
25
|
+
DEBUG_BUILD && debug.warn("ProfilingIntegration is not available");
|
|
40
26
|
return;
|
|
41
27
|
}
|
|
42
|
-
|
|
43
|
-
client.emit('stopUIProfiler');
|
|
28
|
+
client.emit("stopUIProfiler");
|
|
44
29
|
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Profiler namespace for controlling the JS profiler in 'manual' mode.
|
|
48
|
-
*
|
|
49
|
-
* Requires the `browserProfilingIntegration` from the `@sentry/browser` package.
|
|
50
|
-
*/
|
|
51
30
|
const uiProfiler = {
|
|
52
31
|
startProfiler,
|
|
53
|
-
stopProfiler
|
|
32
|
+
stopProfiler
|
|
54
33
|
};
|
|
55
34
|
|
|
56
35
|
export { uiProfiler };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../src/profiling/index.ts"],"sourcesContent":["import type { Profiler } from '@sentry/core/browser';\nimport { debug, getClient } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Starts the Sentry UI profiler.\n * This mode is exclusive with the transaction profiler and will only work if the profilesSampleRate is set to a falsy value.\n * In UI profiling mode, the profiler will keep reporting profile chunks to Sentry until it is stopped, which allows for continuous profiling of the application.\n */\nfunction startProfiler(): void {\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No Sentry client available, profiling is not started');\n return;\n }\n\n const integration = client.getIntegrationByName('BrowserProfiling');\n\n if (!integration) {\n DEBUG_BUILD && debug.warn('BrowserProfiling integration is not available');\n return;\n }\n\n client.emit('startUIProfiler');\n}\n\n/**\n * Stops the Sentry UI profiler.\n * Calls to stop will stop the profiler and flush the currently collected profile data to Sentry.\n */\nfunction stopProfiler(): void {\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No Sentry client available, profiling is not started');\n return;\n }\n\n const integration = client.getIntegrationByName('BrowserProfiling');\n if (!integration) {\n DEBUG_BUILD && debug.warn('ProfilingIntegration is not available');\n return;\n }\n\n client.emit('stopUIProfiler');\n}\n\n/**\n * Profiler namespace for controlling the JS profiler in 'manual' mode.\n *\n * Requires the `browserProfilingIntegration` from the `@sentry/browser` package.\n */\nexport const uiProfiler: Profiler = {\n startProfiler,\n stopProfiler,\n};\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/profiling/index.ts"],"sourcesContent":["import type { Profiler } from '@sentry/core/browser';\nimport { debug, getClient } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Starts the Sentry UI profiler.\n * This mode is exclusive with the transaction profiler and will only work if the profilesSampleRate is set to a falsy value.\n * In UI profiling mode, the profiler will keep reporting profile chunks to Sentry until it is stopped, which allows for continuous profiling of the application.\n */\nfunction startProfiler(): void {\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No Sentry client available, profiling is not started');\n return;\n }\n\n const integration = client.getIntegrationByName('BrowserProfiling');\n\n if (!integration) {\n DEBUG_BUILD && debug.warn('BrowserProfiling integration is not available');\n return;\n }\n\n client.emit('startUIProfiler');\n}\n\n/**\n * Stops the Sentry UI profiler.\n * Calls to stop will stop the profiler and flush the currently collected profile data to Sentry.\n */\nfunction stopProfiler(): void {\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No Sentry client available, profiling is not started');\n return;\n }\n\n const integration = client.getIntegrationByName('BrowserProfiling');\n if (!integration) {\n DEBUG_BUILD && debug.warn('ProfilingIntegration is not available');\n return;\n }\n\n client.emit('stopUIProfiler');\n}\n\n/**\n * Profiler namespace for controlling the JS profiler in 'manual' mode.\n *\n * Requires the `browserProfilingIntegration` from the `@sentry/browser` package.\n */\nexport const uiProfiler: Profiler = {\n startProfiler,\n stopProfiler,\n};\n"],"names":[],"mappings":";;;AASA,SAAS,aAAA,GAAsB;AAC7B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,WAAA,IAAe,KAAA,CAAM,KAAK,sDAAsD,CAAA;AAChF,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,oBAAA,CAAqB,kBAAkB,CAAA;AAElE,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,WAAA,IAAe,KAAA,CAAM,KAAK,+CAA+C,CAAA;AACzE,IAAA;AAAA,EACF;AAEA,EAAA,MAAA,CAAO,KAAK,iBAAiB,CAAA;AAC/B;AAMA,SAAS,YAAA,GAAqB;AAC5B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,WAAA,IAAe,KAAA,CAAM,KAAK,sDAAsD,CAAA;AAChF,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,oBAAA,CAAqB,kBAAkB,CAAA;AAClE,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,WAAA,IAAe,KAAA,CAAM,KAAK,uCAAuC,CAAA;AACjE,IAAA;AAAA,EACF;AAEA,EAAA,MAAA,CAAO,KAAK,gBAAgB,CAAA;AAC9B;AAOO,MAAM,UAAA,GAAuB;AAAA,EAClC,aAAA;AAAA,EACA;AACF;;;;"}
|
|
@@ -5,63 +5,44 @@ import { startProfileForSpan } from './startProfileForSpan.js';
|
|
|
5
5
|
import { UIProfiler } from './UIProfiler.js';
|
|
6
6
|
import { hasLegacyProfiling, isAutomatedPageLoadSpan, shouldProfileSpanLegacy, PROFILED_ROOT_SPANS, setThreadAttributes, getActiveProfilesCount, findProfiledTransactionsFromEnvelope, takeProfileFromGlobalCache, createProfilingEvent, addProfilesToEnvelope } from './utils.js';
|
|
7
7
|
|
|
8
|
-
const INTEGRATION_NAME =
|
|
9
|
-
|
|
8
|
+
const INTEGRATION_NAME = "BrowserProfiling";
|
|
10
9
|
const _browserProfilingIntegration = (() => {
|
|
11
10
|
return {
|
|
12
11
|
name: INTEGRATION_NAME,
|
|
13
12
|
setup(client) {
|
|
14
|
-
const options = client.getOptions()
|
|
13
|
+
const options = client.getOptions();
|
|
15
14
|
const profiler = new UIProfiler();
|
|
16
|
-
|
|
17
15
|
if (!hasLegacyProfiling(options) && !options.profileLifecycle) {
|
|
18
|
-
|
|
19
|
-
options.profileLifecycle = 'manual';
|
|
16
|
+
options.profileLifecycle = "manual";
|
|
20
17
|
}
|
|
21
|
-
|
|
22
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
23
18
|
if (hasLegacyProfiling(options) && !options.profilesSampleRate) {
|
|
24
|
-
DEBUG_BUILD && debug.log(
|
|
19
|
+
DEBUG_BUILD && debug.log("[Profiling] Profiling disabled, no profiling options found.");
|
|
25
20
|
return;
|
|
26
21
|
}
|
|
27
|
-
|
|
28
22
|
const activeSpan = getActiveSpan();
|
|
29
23
|
const rootSpan = activeSpan && getRootSpan(activeSpan);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled.',
|
|
35
|
-
);
|
|
24
|
+
if (hasLegacyProfiling(options) && options.profileSessionSampleRate !== void 0) {
|
|
25
|
+
DEBUG_BUILD && debug.warn(
|
|
26
|
+
"[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled."
|
|
27
|
+
);
|
|
36
28
|
}
|
|
37
|
-
|
|
38
|
-
// UI PROFILING (Profiling V2)
|
|
39
29
|
if (!hasLegacyProfiling(options)) {
|
|
40
30
|
const lifecycleMode = options.profileLifecycle;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
client.on('stopUIProfiler', () => profiler.stop());
|
|
45
|
-
|
|
46
|
-
if (lifecycleMode === 'manual') {
|
|
31
|
+
client.on("startUIProfiler", () => profiler.start());
|
|
32
|
+
client.on("stopUIProfiler", () => profiler.stop());
|
|
33
|
+
if (lifecycleMode === "manual") {
|
|
47
34
|
profiler.initialize(client);
|
|
48
|
-
} else if (lifecycleMode ===
|
|
35
|
+
} else if (lifecycleMode === "trace") {
|
|
49
36
|
if (!hasSpansEnabled(options)) {
|
|
50
|
-
DEBUG_BUILD &&
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
);
|
|
37
|
+
DEBUG_BUILD && debug.warn(
|
|
38
|
+
"[Profiling] `profileLifecycle` is 'trace' but tracing is disabled. Set a `tracesSampleRate` or `tracesSampler` to enable span tracing."
|
|
39
|
+
);
|
|
54
40
|
return;
|
|
55
41
|
}
|
|
56
|
-
|
|
57
42
|
profiler.initialize(client);
|
|
58
|
-
|
|
59
|
-
// If there is an active, sampled root span already, notify the profiler
|
|
60
43
|
if (rootSpan) {
|
|
61
44
|
profiler.notifyRootSpanActive(rootSpan);
|
|
62
45
|
}
|
|
63
|
-
|
|
64
|
-
// In case rootSpan is created slightly after setup -> schedule microtask to re-check and notify.
|
|
65
46
|
WINDOW.setTimeout(() => {
|
|
66
47
|
const laterActiveSpan = getActiveSpan();
|
|
67
48
|
const laterRootSpan = laterActiveSpan && getRootSpan(laterActiveSpan);
|
|
@@ -71,81 +52,66 @@ const _browserProfilingIntegration = (() => {
|
|
|
71
52
|
}, 0);
|
|
72
53
|
}
|
|
73
54
|
} else {
|
|
74
|
-
// LEGACY PROFILING (v1)
|
|
75
55
|
if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {
|
|
76
56
|
if (shouldProfileSpanLegacy(rootSpan)) {
|
|
77
57
|
startProfileForSpan(rootSpan);
|
|
78
58
|
}
|
|
79
59
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (span === rootSpan) {
|
|
60
|
+
client.on("spanStart", (span) => {
|
|
61
|
+
const rootSpan2 = getRootSpan(span);
|
|
62
|
+
if (span === rootSpan2) {
|
|
84
63
|
if (shouldProfileSpanLegacy(span)) {
|
|
85
64
|
startProfileForSpan(span);
|
|
86
65
|
}
|
|
87
|
-
} else if (PROFILED_ROOT_SPANS.has(
|
|
66
|
+
} else if (PROFILED_ROOT_SPANS.has(rootSpan2)) {
|
|
88
67
|
setThreadAttributes(span);
|
|
89
68
|
}
|
|
90
69
|
});
|
|
91
|
-
|
|
92
|
-
client.on('beforeEnvelope', (envelope) => {
|
|
93
|
-
// if not profiles are in queue, there is nothing to add to the envelope.
|
|
70
|
+
client.on("beforeEnvelope", (envelope) => {
|
|
94
71
|
if (!getActiveProfilesCount()) {
|
|
95
72
|
return;
|
|
96
73
|
}
|
|
97
|
-
|
|
98
74
|
const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);
|
|
99
75
|
if (!profiledTransactionEvents.length) {
|
|
100
76
|
return;
|
|
101
77
|
}
|
|
102
|
-
|
|
103
78
|
const profilesToAddToEnvelope = [];
|
|
104
|
-
|
|
105
79
|
for (const profiledTransaction of profiledTransactionEvents) {
|
|
106
80
|
const context = profiledTransaction?.contexts;
|
|
107
|
-
const profile_id = context?.profile?.[
|
|
108
|
-
const start_timestamp = context?.profile?.[
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');
|
|
81
|
+
const profile_id = context?.profile?.["profile_id"];
|
|
82
|
+
const start_timestamp = context?.profile?.["start_timestamp"];
|
|
83
|
+
if (typeof profile_id !== "string") {
|
|
84
|
+
DEBUG_BUILD && debug.log("[Profiling] cannot find profile for a span without a profile context");
|
|
112
85
|
continue;
|
|
113
86
|
}
|
|
114
|
-
|
|
115
87
|
if (!profile_id) {
|
|
116
|
-
DEBUG_BUILD && debug.log(
|
|
88
|
+
DEBUG_BUILD && debug.log("[Profiling] cannot find profile for a span without a profile context");
|
|
117
89
|
continue;
|
|
118
90
|
}
|
|
119
|
-
|
|
120
|
-
// Remove the profile from the span context before sending, relay will take care of the rest.
|
|
121
91
|
if (context?.profile) {
|
|
122
92
|
delete context.profile;
|
|
123
93
|
}
|
|
124
|
-
|
|
125
94
|
const profile = takeProfileFromGlobalCache(profile_id);
|
|
126
95
|
if (!profile) {
|
|
127
96
|
DEBUG_BUILD && debug.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);
|
|
128
97
|
continue;
|
|
129
98
|
}
|
|
130
|
-
|
|
131
99
|
const profileEvent = createProfilingEvent(
|
|
132
100
|
profile_id,
|
|
133
|
-
start_timestamp
|
|
101
|
+
start_timestamp,
|
|
134
102
|
profile,
|
|
135
|
-
profiledTransaction
|
|
103
|
+
profiledTransaction
|
|
136
104
|
);
|
|
137
105
|
if (profileEvent) {
|
|
138
106
|
profilesToAddToEnvelope.push(profileEvent);
|
|
139
107
|
}
|
|
140
108
|
}
|
|
141
|
-
|
|
142
|
-
addProfilesToEnvelope(envelope , profilesToAddToEnvelope);
|
|
109
|
+
addProfilesToEnvelope(envelope, profilesToAddToEnvelope);
|
|
143
110
|
});
|
|
144
111
|
}
|
|
145
|
-
}
|
|
112
|
+
}
|
|
146
113
|
};
|
|
147
|
-
})
|
|
148
|
-
|
|
114
|
+
});
|
|
149
115
|
const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);
|
|
150
116
|
|
|
151
117
|
export { browserProfilingIntegration };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.js","sources":["../../../../../src/profiling/integration.ts"],"sourcesContent":["import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core/browser';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core/browser';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { startProfileForSpan } from './startProfileForSpan';\nimport { UIProfiler } from './UIProfiler';\nimport type { ProfiledEvent } from './utils';\nimport {\n addProfilesToEnvelope,\n createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\n shouldProfileSpanLegacy,\n takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling';\n\nconst _browserProfilingIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const options = client.getOptions() as BrowserOptions;\n const profiler = new UIProfiler();\n\n if (!hasLegacyProfiling(options) && !options.profileLifecycle) {\n // Set default lifecycle mode\n options.profileLifecycle = 'manual';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n if (hasLegacyProfiling(options) && !options.profilesSampleRate) {\n DEBUG_BUILD && debug.log('[Profiling] Profiling disabled, no profiling options found.');\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (hasLegacyProfiling(options) && options.profileSessionSampleRate !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled.',\n );\n }\n\n // UI PROFILING (Profiling V2)\n if (!hasLegacyProfiling(options)) {\n const lifecycleMode = options.profileLifecycle;\n\n // Registering hooks in all lifecycle modes to be able to notify users in case they want to start/stop the profiler manually in `trace` mode\n client.on('startUIProfiler', () => profiler.start());\n client.on('stopUIProfiler', () => profiler.stop());\n\n if (lifecycleMode === 'manual') {\n profiler.initialize(client);\n } else if (lifecycleMode === 'trace') {\n if (!hasSpansEnabled(options)) {\n DEBUG_BUILD &&\n debug.warn(\n \"[Profiling] `profileLifecycle` is 'trace' but tracing is disabled. Set a `tracesSampleRate` or `tracesSampler` to enable span tracing.\",\n );\n return;\n }\n\n profiler.initialize(client);\n\n // If there is an active, sampled root span already, notify the profiler\n if (rootSpan) {\n profiler.notifyRootSpanActive(rootSpan);\n }\n\n // In case rootSpan is created slightly after setup -> schedule microtask to re-check and notify.\n WINDOW.setTimeout(() => {\n const laterActiveSpan = getActiveSpan();\n const laterRootSpan = laterActiveSpan && getRootSpan(laterActiveSpan);\n if (laterRootSpan) {\n profiler.notifyRootSpanActive(laterRootSpan);\n }\n }, 0);\n }\n } else {\n // LEGACY PROFILING (v1)\n if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {\n if (shouldProfileSpanLegacy(rootSpan)) {\n startProfileForSpan(rootSpan);\n }\n }\n\n client.on('spanStart', (span: Span) => {\n const rootSpan = getRootSpan(span);\n if (span === rootSpan) {\n if (shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n } else if (PROFILED_ROOT_SPANS.has(rootSpan)) {\n setThreadAttributes(span);\n }\n });\n\n client.on('beforeEnvelope', (envelope): void => {\n // if not profiles are in queue, there is nothing to add to the envelope.\n if (!getActiveProfilesCount()) {\n return;\n }\n\n const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactionEvents.length) {\n return;\n }\n\n const profilesToAddToEnvelope: Profile[] = [];\n\n for (const profiledTransaction of profiledTransactionEvents) {\n const context = profiledTransaction?.contexts;\n const profile_id = context?.profile?.['profile_id'];\n const start_timestamp = context?.profile?.['start_timestamp'];\n\n if (typeof profile_id !== 'string') {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n if (!profile_id) {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n // Remove the profile from the span context before sending, relay will take care of the rest.\n if (context?.profile) {\n delete context.profile;\n }\n\n const profile = takeProfileFromGlobalCache(profile_id);\n if (!profile) {\n DEBUG_BUILD && debug.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);\n continue;\n }\n\n const profileEvent = createProfilingEvent(\n profile_id,\n start_timestamp as number | undefined,\n profile,\n profiledTransaction as ProfiledEvent,\n );\n if (profileEvent) {\n profilesToAddToEnvelope.push(profileEvent);\n }\n }\n\n addProfilesToEnvelope(envelope as EventEnvelope, profilesToAddToEnvelope);\n });\n }\n },\n };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":[],"mappings":";;;;;;;AAqBA,MAAM,gBAAA,GAAmB,
|
|
1
|
+
{"version":3,"file":"integration.js","sources":["../../../../../src/profiling/integration.ts"],"sourcesContent":["import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core/browser';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core/browser';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { startProfileForSpan } from './startProfileForSpan';\nimport { UIProfiler } from './UIProfiler';\nimport type { ProfiledEvent } from './utils';\nimport {\n addProfilesToEnvelope,\n createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\n shouldProfileSpanLegacy,\n takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling';\n\nconst _browserProfilingIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const options = client.getOptions() as BrowserOptions;\n const profiler = new UIProfiler();\n\n if (!hasLegacyProfiling(options) && !options.profileLifecycle) {\n // Set default lifecycle mode\n options.profileLifecycle = 'manual';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n if (hasLegacyProfiling(options) && !options.profilesSampleRate) {\n DEBUG_BUILD && debug.log('[Profiling] Profiling disabled, no profiling options found.');\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (hasLegacyProfiling(options) && options.profileSessionSampleRate !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled.',\n );\n }\n\n // UI PROFILING (Profiling V2)\n if (!hasLegacyProfiling(options)) {\n const lifecycleMode = options.profileLifecycle;\n\n // Registering hooks in all lifecycle modes to be able to notify users in case they want to start/stop the profiler manually in `trace` mode\n client.on('startUIProfiler', () => profiler.start());\n client.on('stopUIProfiler', () => profiler.stop());\n\n if (lifecycleMode === 'manual') {\n profiler.initialize(client);\n } else if (lifecycleMode === 'trace') {\n if (!hasSpansEnabled(options)) {\n DEBUG_BUILD &&\n debug.warn(\n \"[Profiling] `profileLifecycle` is 'trace' but tracing is disabled. Set a `tracesSampleRate` or `tracesSampler` to enable span tracing.\",\n );\n return;\n }\n\n profiler.initialize(client);\n\n // If there is an active, sampled root span already, notify the profiler\n if (rootSpan) {\n profiler.notifyRootSpanActive(rootSpan);\n }\n\n // In case rootSpan is created slightly after setup -> schedule microtask to re-check and notify.\n WINDOW.setTimeout(() => {\n const laterActiveSpan = getActiveSpan();\n const laterRootSpan = laterActiveSpan && getRootSpan(laterActiveSpan);\n if (laterRootSpan) {\n profiler.notifyRootSpanActive(laterRootSpan);\n }\n }, 0);\n }\n } else {\n // LEGACY PROFILING (v1)\n if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {\n if (shouldProfileSpanLegacy(rootSpan)) {\n startProfileForSpan(rootSpan);\n }\n }\n\n client.on('spanStart', (span: Span) => {\n const rootSpan = getRootSpan(span);\n if (span === rootSpan) {\n if (shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n } else if (PROFILED_ROOT_SPANS.has(rootSpan)) {\n setThreadAttributes(span);\n }\n });\n\n client.on('beforeEnvelope', (envelope): void => {\n // if not profiles are in queue, there is nothing to add to the envelope.\n if (!getActiveProfilesCount()) {\n return;\n }\n\n const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactionEvents.length) {\n return;\n }\n\n const profilesToAddToEnvelope: Profile[] = [];\n\n for (const profiledTransaction of profiledTransactionEvents) {\n const context = profiledTransaction?.contexts;\n const profile_id = context?.profile?.['profile_id'];\n const start_timestamp = context?.profile?.['start_timestamp'];\n\n if (typeof profile_id !== 'string') {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n if (!profile_id) {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n // Remove the profile from the span context before sending, relay will take care of the rest.\n if (context?.profile) {\n delete context.profile;\n }\n\n const profile = takeProfileFromGlobalCache(profile_id);\n if (!profile) {\n DEBUG_BUILD && debug.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);\n continue;\n }\n\n const profileEvent = createProfilingEvent(\n profile_id,\n start_timestamp as number | undefined,\n profile,\n profiledTransaction as ProfiledEvent,\n );\n if (profileEvent) {\n profilesToAddToEnvelope.push(profileEvent);\n }\n }\n\n addProfilesToEnvelope(envelope as EventEnvelope, profilesToAddToEnvelope);\n });\n }\n },\n };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":["rootSpan"],"mappings":"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"}
|
|
@@ -3,141 +3,85 @@ import { DEBUG_BUILD } from '../debug-build.js';
|
|
|
3
3
|
import { WINDOW } from '../helpers.js';
|
|
4
4
|
import { isAutomatedPageLoadSpan, startJSSelfProfile, PROFILED_ROOT_SPANS, setThreadAttributes, MAX_PROFILE_DURATION_MS, addProfileToGlobalCache } from './utils.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Wraps startTransaction and stopTransaction with profiling related logic.
|
|
8
|
-
* startProfileForTransaction is called after the call to startTransaction in order to avoid our own code from
|
|
9
|
-
* being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.
|
|
10
|
-
*/
|
|
11
6
|
function startProfileForSpan(span) {
|
|
12
|
-
// Start the profiler and get the profiler instance.
|
|
13
7
|
let startTimestamp;
|
|
14
8
|
if (isAutomatedPageLoadSpan(span)) {
|
|
15
|
-
startTimestamp = timestampInSeconds() *
|
|
9
|
+
startTimestamp = timestampInSeconds() * 1e3;
|
|
16
10
|
}
|
|
17
|
-
|
|
18
11
|
const profiler = startJSSelfProfile();
|
|
19
|
-
|
|
20
|
-
// We failed to construct the profiler, so we skip.
|
|
21
|
-
// No need to log anything as this has already been logged in startProfile.
|
|
22
12
|
if (!profiler) {
|
|
23
13
|
return;
|
|
24
14
|
}
|
|
25
|
-
|
|
26
15
|
if (DEBUG_BUILD) {
|
|
27
16
|
debug.log(`[Profiling] started profiling span: ${spanToJSON(span).description}`);
|
|
28
17
|
}
|
|
29
|
-
|
|
30
|
-
// We create "unique" span names to avoid concurrent spans with same names
|
|
31
|
-
// from being ignored by the profiler. From here on, only this span name should be used when
|
|
32
|
-
// calling the profiler methods. Note: we log the original name to the user to avoid confusion.
|
|
33
18
|
const profileId = uuid4();
|
|
34
|
-
|
|
35
|
-
// A couple of important things to note here:
|
|
36
|
-
// `CpuProfilerBindings.stopProfiling` will be scheduled to run in 30seconds in order to exceed max profile duration.
|
|
37
|
-
// Whichever of the two (span.finish/timeout) is first to run, the profiling will be stopped and the gathered profile
|
|
38
|
-
// will be processed when the original span is finished. Since onProfileHandler can be invoked multiple times in the
|
|
39
|
-
// event of an error or user mistake (calling span.finish multiple times), it is important that the behavior of onProfileHandler
|
|
40
|
-
// is idempotent as we do not want any timings or profiles to be overridden by the last call to onProfileHandler.
|
|
41
|
-
// After the original finish method is called, the event will be reported through the integration and delegated to transport.
|
|
42
19
|
let processedProfile = null;
|
|
43
|
-
|
|
44
|
-
getCurrentScope().setContext('profile', {
|
|
20
|
+
getCurrentScope().setContext("profile", {
|
|
45
21
|
profile_id: profileId,
|
|
46
|
-
start_timestamp: startTimestamp
|
|
22
|
+
start_timestamp: startTimestamp
|
|
47
23
|
});
|
|
48
|
-
|
|
49
24
|
PROFILED_ROOT_SPANS.add(span);
|
|
50
25
|
setThreadAttributes(span);
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Idempotent handler for profile stop
|
|
54
|
-
*/
|
|
55
26
|
async function onProfileHandler() {
|
|
56
|
-
// Check if the profile exists and return it the behavior has to be idempotent as users may call span.finish multiple times.
|
|
57
27
|
if (!span) {
|
|
58
28
|
return;
|
|
59
29
|
}
|
|
60
|
-
// Satisfy the type checker, but profiler will always be defined here.
|
|
61
30
|
if (!profiler) {
|
|
62
31
|
return;
|
|
63
32
|
}
|
|
64
33
|
if (processedProfile) {
|
|
65
34
|
if (DEBUG_BUILD) {
|
|
66
|
-
debug.log(
|
|
35
|
+
debug.log("[Profiling] profile for:", spanToJSON(span).description, "already exists, returning early");
|
|
67
36
|
}
|
|
68
37
|
return;
|
|
69
38
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (DEBUG_BUILD) {
|
|
80
|
-
debug.log(`[Profiling] stopped profiling of span: ${spanToJSON(span).description}`);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// In case of an overlapping span, stopProfiling may return null and silently ignore the overlapping profile.
|
|
84
|
-
if (!profile) {
|
|
85
|
-
if (DEBUG_BUILD) {
|
|
86
|
-
debug.log(
|
|
87
|
-
`[Profiling] profiler returned null profile for: ${spanToJSON(span).description}`,
|
|
88
|
-
'this may indicate an overlapping span or a call to stopProfiling with a profile title that was never started',
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
processedProfile = profile;
|
|
95
|
-
addProfileToGlobalCache(profileId, profile);
|
|
96
|
-
})
|
|
97
|
-
.catch(error => {
|
|
39
|
+
return profiler.stop().then((profile) => {
|
|
40
|
+
if (maxDurationTimeoutID) {
|
|
41
|
+
WINDOW.clearTimeout(maxDurationTimeoutID);
|
|
42
|
+
maxDurationTimeoutID = void 0;
|
|
43
|
+
}
|
|
44
|
+
if (DEBUG_BUILD) {
|
|
45
|
+
debug.log(`[Profiling] stopped profiling of span: ${spanToJSON(span).description}`);
|
|
46
|
+
}
|
|
47
|
+
if (!profile) {
|
|
98
48
|
if (DEBUG_BUILD) {
|
|
99
|
-
debug.log(
|
|
49
|
+
debug.log(
|
|
50
|
+
`[Profiling] profiler returned null profile for: ${spanToJSON(span).description}`,
|
|
51
|
+
"this may indicate an overlapping span or a call to stopProfiling with a profile title that was never started"
|
|
52
|
+
);
|
|
100
53
|
}
|
|
101
|
-
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
processedProfile = profile;
|
|
57
|
+
addProfileToGlobalCache(profileId, profile);
|
|
58
|
+
}).catch((error) => {
|
|
59
|
+
if (DEBUG_BUILD) {
|
|
60
|
+
debug.log("[Profiling] error while stopping profiler:", error);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
102
63
|
}
|
|
103
|
-
|
|
104
|
-
// Enqueue a timeout to prevent profiles from running over max duration.
|
|
105
64
|
let maxDurationTimeoutID = WINDOW.setTimeout(() => {
|
|
106
65
|
if (DEBUG_BUILD) {
|
|
107
|
-
debug.log(
|
|
66
|
+
debug.log("[Profiling] max profile duration elapsed, stopping profiling for:", spanToJSON(span).description);
|
|
108
67
|
}
|
|
109
|
-
// If the timeout exceeds, we want to stop profiling, but not finish the span
|
|
110
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
111
68
|
onProfileHandler();
|
|
112
69
|
}, MAX_PROFILE_DURATION_MS);
|
|
113
|
-
|
|
114
|
-
// We need to reference the original end call to avoid creating an infinite loop
|
|
115
70
|
const originalEnd = span.end.bind(span);
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Wraps span `end()` with profiling related logic.
|
|
119
|
-
* startProfiling is called after the call to spanStart in order to avoid our own code from
|
|
120
|
-
* being profiled. Because of that same reason, stopProfiling is called before the call to spanEnd.
|
|
121
|
-
*/
|
|
122
71
|
function profilingWrappedSpanEnd() {
|
|
123
72
|
if (!span) {
|
|
124
73
|
return originalEnd();
|
|
125
74
|
}
|
|
126
|
-
// onProfileHandler should always return the same profile even if this is called multiple times.
|
|
127
|
-
// Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared.
|
|
128
75
|
void onProfileHandler().then(
|
|
129
76
|
() => {
|
|
130
77
|
originalEnd();
|
|
131
78
|
},
|
|
132
79
|
() => {
|
|
133
|
-
// If onProfileHandler fails, we still want to call the original finish method.
|
|
134
80
|
originalEnd();
|
|
135
|
-
}
|
|
81
|
+
}
|
|
136
82
|
);
|
|
137
|
-
|
|
138
83
|
return span;
|
|
139
84
|
}
|
|
140
|
-
|
|
141
85
|
span.end = profilingWrappedSpanEnd;
|
|
142
86
|
}
|
|
143
87
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startProfileForSpan.js","sources":["../../../../../src/profiling/startProfileForSpan.ts"],"sourcesContent":["import type { Span } from '@sentry/core/browser';\nimport { debug, getCurrentScope, spanToJSON, timestampInSeconds, uuid4 } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport type { JSSelfProfile } from './jsSelfProfiling';\nimport {\n addProfileToGlobalCache,\n isAutomatedPageLoadSpan,\n MAX_PROFILE_DURATION_MS,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\n startJSSelfProfile,\n} from './utils';\n\n/**\n * Wraps startTransaction and stopTransaction with profiling related logic.\n * startProfileForTransaction is called after the call to startTransaction in order to avoid our own code from\n * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.\n */\nexport function startProfileForSpan(span: Span): void {\n // Start the profiler and get the profiler instance.\n let startTimestamp: number | undefined;\n if (isAutomatedPageLoadSpan(span)) {\n startTimestamp = timestampInSeconds() * 1000;\n }\n\n const profiler = startJSSelfProfile();\n\n // We failed to construct the profiler, so we skip.\n // No need to log anything as this has already been logged in startProfile.\n if (!profiler) {\n return;\n }\n\n if (DEBUG_BUILD) {\n debug.log(`[Profiling] started profiling span: ${spanToJSON(span).description}`);\n }\n\n // We create \"unique\" span names to avoid concurrent spans with same names\n // from being ignored by the profiler. From here on, only this span name should be used when\n // calling the profiler methods. Note: we log the original name to the user to avoid confusion.\n const profileId = uuid4();\n\n // A couple of important things to note here:\n // `CpuProfilerBindings.stopProfiling` will be scheduled to run in 30seconds in order to exceed max profile duration.\n // Whichever of the two (span.finish/timeout) is first to run, the profiling will be stopped and the gathered profile\n // will be processed when the original span is finished. Since onProfileHandler can be invoked multiple times in the\n // event of an error or user mistake (calling span.finish multiple times), it is important that the behavior of onProfileHandler\n // is idempotent as we do not want any timings or profiles to be overridden by the last call to onProfileHandler.\n // After the original finish method is called, the event will be reported through the integration and delegated to transport.\n let processedProfile: JSSelfProfile | null = null;\n\n getCurrentScope().setContext('profile', {\n profile_id: profileId,\n start_timestamp: startTimestamp,\n });\n\n PROFILED_ROOT_SPANS.add(span);\n setThreadAttributes(span);\n\n /**\n * Idempotent handler for profile stop\n */\n async function onProfileHandler(): Promise<void> {\n // Check if the profile exists and return it the behavior has to be idempotent as users may call span.finish multiple times.\n if (!span) {\n return;\n }\n // Satisfy the type checker, but profiler will always be defined here.\n if (!profiler) {\n return;\n }\n if (processedProfile) {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] profile for:', spanToJSON(span).description, 'already exists, returning early');\n }\n return;\n }\n\n return profiler\n .stop()\n .then((profile: JSSelfProfile): void => {\n if (maxDurationTimeoutID) {\n WINDOW.clearTimeout(maxDurationTimeoutID);\n maxDurationTimeoutID = undefined;\n }\n\n if (DEBUG_BUILD) {\n debug.log(`[Profiling] stopped profiling of span: ${spanToJSON(span).description}`);\n }\n\n // In case of an overlapping span, stopProfiling may return null and silently ignore the overlapping profile.\n if (!profile) {\n if (DEBUG_BUILD) {\n debug.log(\n `[Profiling] profiler returned null profile for: ${spanToJSON(span).description}`,\n 'this may indicate an overlapping span or a call to stopProfiling with a profile title that was never started',\n );\n }\n return;\n }\n\n processedProfile = profile;\n addProfileToGlobalCache(profileId, profile);\n })\n .catch(error => {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] error while stopping profiler:', error);\n }\n });\n }\n\n // Enqueue a timeout to prevent profiles from running over max duration.\n let maxDurationTimeoutID: number | undefined = WINDOW.setTimeout(() => {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] max profile duration elapsed, stopping profiling for:', spanToJSON(span).description);\n }\n // If the timeout exceeds, we want to stop profiling, but not finish the span\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n onProfileHandler();\n }, MAX_PROFILE_DURATION_MS);\n\n // We need to reference the original end call to avoid creating an infinite loop\n const originalEnd = span.end.bind(span);\n\n /**\n * Wraps span `end()` with profiling related logic.\n * startProfiling is called after the call to spanStart in order to avoid our own code from\n * being profiled. Because of that same reason, stopProfiling is called before the call to spanEnd.\n */\n function profilingWrappedSpanEnd(): Span {\n if (!span) {\n return originalEnd();\n }\n // onProfileHandler should always return the same profile even if this is called multiple times.\n // Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared.\n void onProfileHandler().then(\n () => {\n originalEnd();\n },\n () => {\n // If onProfileHandler fails, we still want to call the original finish method.\n originalEnd();\n },\n );\n\n return span;\n }\n\n span.end = profilingWrappedSpanEnd;\n}\n"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"startProfileForSpan.js","sources":["../../../../../src/profiling/startProfileForSpan.ts"],"sourcesContent":["import type { Span } from '@sentry/core/browser';\nimport { debug, getCurrentScope, spanToJSON, timestampInSeconds, uuid4 } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport type { JSSelfProfile } from './jsSelfProfiling';\nimport {\n addProfileToGlobalCache,\n isAutomatedPageLoadSpan,\n MAX_PROFILE_DURATION_MS,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\n startJSSelfProfile,\n} from './utils';\n\n/**\n * Wraps startTransaction and stopTransaction with profiling related logic.\n * startProfileForTransaction is called after the call to startTransaction in order to avoid our own code from\n * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.\n */\nexport function startProfileForSpan(span: Span): void {\n // Start the profiler and get the profiler instance.\n let startTimestamp: number | undefined;\n if (isAutomatedPageLoadSpan(span)) {\n startTimestamp = timestampInSeconds() * 1000;\n }\n\n const profiler = startJSSelfProfile();\n\n // We failed to construct the profiler, so we skip.\n // No need to log anything as this has already been logged in startProfile.\n if (!profiler) {\n return;\n }\n\n if (DEBUG_BUILD) {\n debug.log(`[Profiling] started profiling span: ${spanToJSON(span).description}`);\n }\n\n // We create \"unique\" span names to avoid concurrent spans with same names\n // from being ignored by the profiler. From here on, only this span name should be used when\n // calling the profiler methods. Note: we log the original name to the user to avoid confusion.\n const profileId = uuid4();\n\n // A couple of important things to note here:\n // `CpuProfilerBindings.stopProfiling` will be scheduled to run in 30seconds in order to exceed max profile duration.\n // Whichever of the two (span.finish/timeout) is first to run, the profiling will be stopped and the gathered profile\n // will be processed when the original span is finished. Since onProfileHandler can be invoked multiple times in the\n // event of an error or user mistake (calling span.finish multiple times), it is important that the behavior of onProfileHandler\n // is idempotent as we do not want any timings or profiles to be overridden by the last call to onProfileHandler.\n // After the original finish method is called, the event will be reported through the integration and delegated to transport.\n let processedProfile: JSSelfProfile | null = null;\n\n getCurrentScope().setContext('profile', {\n profile_id: profileId,\n start_timestamp: startTimestamp,\n });\n\n PROFILED_ROOT_SPANS.add(span);\n setThreadAttributes(span);\n\n /**\n * Idempotent handler for profile stop\n */\n async function onProfileHandler(): Promise<void> {\n // Check if the profile exists and return it the behavior has to be idempotent as users may call span.finish multiple times.\n if (!span) {\n return;\n }\n // Satisfy the type checker, but profiler will always be defined here.\n if (!profiler) {\n return;\n }\n if (processedProfile) {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] profile for:', spanToJSON(span).description, 'already exists, returning early');\n }\n return;\n }\n\n return profiler\n .stop()\n .then((profile: JSSelfProfile): void => {\n if (maxDurationTimeoutID) {\n WINDOW.clearTimeout(maxDurationTimeoutID);\n maxDurationTimeoutID = undefined;\n }\n\n if (DEBUG_BUILD) {\n debug.log(`[Profiling] stopped profiling of span: ${spanToJSON(span).description}`);\n }\n\n // In case of an overlapping span, stopProfiling may return null and silently ignore the overlapping profile.\n if (!profile) {\n if (DEBUG_BUILD) {\n debug.log(\n `[Profiling] profiler returned null profile for: ${spanToJSON(span).description}`,\n 'this may indicate an overlapping span or a call to stopProfiling with a profile title that was never started',\n );\n }\n return;\n }\n\n processedProfile = profile;\n addProfileToGlobalCache(profileId, profile);\n })\n .catch(error => {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] error while stopping profiler:', error);\n }\n });\n }\n\n // Enqueue a timeout to prevent profiles from running over max duration.\n let maxDurationTimeoutID: number | undefined = WINDOW.setTimeout(() => {\n if (DEBUG_BUILD) {\n debug.log('[Profiling] max profile duration elapsed, stopping profiling for:', spanToJSON(span).description);\n }\n // If the timeout exceeds, we want to stop profiling, but not finish the span\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n onProfileHandler();\n }, MAX_PROFILE_DURATION_MS);\n\n // We need to reference the original end call to avoid creating an infinite loop\n const originalEnd = span.end.bind(span);\n\n /**\n * Wraps span `end()` with profiling related logic.\n * startProfiling is called after the call to spanStart in order to avoid our own code from\n * being profiled. Because of that same reason, stopProfiling is called before the call to spanEnd.\n */\n function profilingWrappedSpanEnd(): Span {\n if (!span) {\n return originalEnd();\n }\n // onProfileHandler should always return the same profile even if this is called multiple times.\n // Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared.\n void onProfileHandler().then(\n () => {\n originalEnd();\n },\n () => {\n // If onProfileHandler fails, we still want to call the original finish method.\n originalEnd();\n },\n );\n\n return span;\n }\n\n span.end = profilingWrappedSpanEnd;\n}\n"],"names":[],"mappings":"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"}
|