@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
|
@@ -4,227 +4,158 @@ const browser = require('@sentry/core/browser');
|
|
|
4
4
|
const debugBuild = require('../debug-build.js');
|
|
5
5
|
const utils = require('./utils.js');
|
|
6
6
|
|
|
7
|
-
const CHUNK_INTERVAL_MS =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* - 'trace': automatically runs while there are active sampled root spans
|
|
16
|
-
*
|
|
17
|
-
* Profiles are emitted as standalone `profile_chunk` envelopes either when:
|
|
18
|
-
* - there are no more sampled root spans, or
|
|
19
|
-
* - the 60s chunk timer elapses while profiling is running.
|
|
20
|
-
*/
|
|
21
|
-
class UIProfiler {
|
|
22
|
-
|
|
23
|
-
// Manual + Trace
|
|
24
|
-
// one per Profiler session
|
|
25
|
-
// current profiler instance active flag
|
|
26
|
-
// sampling decision for entire session
|
|
27
|
-
|
|
28
|
-
// Trace-only
|
|
29
|
-
|
|
30
|
-
constructor() {
|
|
31
|
-
this._client = undefined;
|
|
32
|
-
this._profiler = undefined;
|
|
33
|
-
this._chunkTimer = undefined;
|
|
34
|
-
|
|
35
|
-
this._profilerId = undefined;
|
|
7
|
+
const CHUNK_INTERVAL_MS = 6e4;
|
|
8
|
+
const MAX_ROOT_SPAN_PROFILE_MS = 3e5;
|
|
9
|
+
class UIProfiler {
|
|
10
|
+
constructor() {
|
|
11
|
+
this._client = void 0;
|
|
12
|
+
this._profiler = void 0;
|
|
13
|
+
this._chunkTimer = void 0;
|
|
14
|
+
this._profilerId = void 0;
|
|
36
15
|
this._isRunning = false;
|
|
37
16
|
this._sessionSampled = false;
|
|
38
|
-
this._lifecycleMode =
|
|
39
|
-
|
|
40
|
-
this.
|
|
41
|
-
this._rootSpanTimeouts = new Map();
|
|
17
|
+
this._lifecycleMode = void 0;
|
|
18
|
+
this._activeRootSpanIds = /* @__PURE__ */ new Set();
|
|
19
|
+
this._rootSpanTimeouts = /* @__PURE__ */ new Map();
|
|
42
20
|
}
|
|
43
|
-
|
|
44
21
|
/**
|
|
45
22
|
* Initialize the profiler with client, session sampling and lifecycle mode.
|
|
46
23
|
*/
|
|
47
|
-
|
|
48
|
-
const lifecycleMode =
|
|
24
|
+
initialize(client) {
|
|
25
|
+
const lifecycleMode = client.getOptions().profileLifecycle;
|
|
49
26
|
const sessionSampled = utils.shouldProfileSession(client.getOptions());
|
|
50
|
-
|
|
51
27
|
debugBuild.DEBUG_BUILD && browser.debug.log(`[Profiling] Initializing profiler (lifecycle='${lifecycleMode}').`);
|
|
52
|
-
|
|
53
28
|
if (!sessionSampled) {
|
|
54
|
-
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
29
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Session not sampled. Skipping lifecycle profiler initialization.");
|
|
55
30
|
}
|
|
56
|
-
|
|
57
|
-
// One Profiler ID per profiling session (user session)
|
|
58
31
|
this._profilerId = browser.uuid4();
|
|
59
32
|
this._client = client;
|
|
60
33
|
this._sessionSampled = sessionSampled;
|
|
61
34
|
this._lifecycleMode = lifecycleMode;
|
|
62
|
-
|
|
63
|
-
if (lifecycleMode === 'trace') {
|
|
35
|
+
if (lifecycleMode === "trace") {
|
|
64
36
|
this._setupTraceLifecycleListeners(client);
|
|
65
37
|
}
|
|
66
|
-
|
|
67
|
-
client.on('spanStart', span => {
|
|
38
|
+
client.on("spanStart", (span) => {
|
|
68
39
|
if (this._isRunning) {
|
|
69
40
|
utils.setThreadAttributes(span);
|
|
70
41
|
}
|
|
71
42
|
});
|
|
72
43
|
}
|
|
73
|
-
|
|
74
44
|
/** Starts UI profiling (only effective in 'manual' mode and when sampled). */
|
|
75
|
-
|
|
76
|
-
if (this._lifecycleMode ===
|
|
77
|
-
debugBuild.DEBUG_BUILD &&
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
);
|
|
45
|
+
start() {
|
|
46
|
+
if (this._lifecycleMode === "trace") {
|
|
47
|
+
debugBuild.DEBUG_BUILD && browser.debug.warn(
|
|
48
|
+
'[Profiling] `profileLifecycle` is set to "trace". Calls to `uiProfiler.start()` are ignored in trace mode.'
|
|
49
|
+
);
|
|
81
50
|
return;
|
|
82
51
|
}
|
|
83
|
-
|
|
84
52
|
if (this._isRunning) {
|
|
85
|
-
debugBuild.DEBUG_BUILD && browser.debug.warn(
|
|
53
|
+
debugBuild.DEBUG_BUILD && browser.debug.warn("[Profiling] Profile session is already running, `uiProfiler.start()` is a no-op.");
|
|
86
54
|
return;
|
|
87
55
|
}
|
|
88
|
-
|
|
89
56
|
if (!this._sessionSampled) {
|
|
90
|
-
debugBuild.DEBUG_BUILD && browser.debug.warn(
|
|
57
|
+
debugBuild.DEBUG_BUILD && browser.debug.warn("[Profiling] Session is not sampled, `uiProfiler.start()` is a no-op.");
|
|
91
58
|
return;
|
|
92
59
|
}
|
|
93
|
-
|
|
94
60
|
this._beginProfiling();
|
|
95
61
|
}
|
|
96
|
-
|
|
97
62
|
/** Stops UI profiling (only effective in 'manual' mode). */
|
|
98
|
-
|
|
99
|
-
if (this._lifecycleMode ===
|
|
100
|
-
debugBuild.DEBUG_BUILD &&
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
63
|
+
stop() {
|
|
64
|
+
if (this._lifecycleMode === "trace") {
|
|
65
|
+
debugBuild.DEBUG_BUILD && browser.debug.warn(
|
|
66
|
+
'[Profiling] `profileLifecycle` is set to "trace". Calls to `uiProfiler.stop()` are ignored in trace mode.'
|
|
67
|
+
);
|
|
104
68
|
return;
|
|
105
69
|
}
|
|
106
|
-
|
|
107
70
|
if (!this._isRunning) {
|
|
108
|
-
debugBuild.DEBUG_BUILD && browser.debug.warn(
|
|
71
|
+
debugBuild.DEBUG_BUILD && browser.debug.warn("[Profiling] Profiler is not running, `uiProfiler.stop()` is a no-op.");
|
|
109
72
|
return;
|
|
110
73
|
}
|
|
111
|
-
|
|
112
74
|
this._endProfiling();
|
|
113
75
|
}
|
|
114
|
-
|
|
115
76
|
/** Handle an already-active root span at integration setup time (used only in trace mode). */
|
|
116
|
-
|
|
117
|
-
if (this._lifecycleMode !==
|
|
77
|
+
notifyRootSpanActive(rootSpan) {
|
|
78
|
+
if (this._lifecycleMode !== "trace" || !this._sessionSampled) {
|
|
118
79
|
return;
|
|
119
80
|
}
|
|
120
|
-
|
|
121
81
|
const spanId = rootSpan.spanContext().spanId;
|
|
122
82
|
if (!spanId || this._activeRootSpanIds.has(spanId)) {
|
|
123
83
|
return;
|
|
124
84
|
}
|
|
125
|
-
|
|
126
85
|
this._registerTraceRootSpan(spanId);
|
|
127
|
-
|
|
128
86
|
const rootSpanCount = this._activeRootSpanIds.size;
|
|
129
|
-
|
|
130
87
|
if (rootSpanCount === 1) {
|
|
131
|
-
debugBuild.DEBUG_BUILD &&
|
|
132
|
-
browser.debug.log('[Profiling] Detected already active root span during setup. Active root spans now:', rootSpanCount);
|
|
133
|
-
|
|
88
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Detected already active root span during setup. Active root spans now:", rootSpanCount);
|
|
134
89
|
this._beginProfiling();
|
|
135
90
|
}
|
|
136
|
-
|
|
137
91
|
if (this._isRunning) {
|
|
138
92
|
utils.setThreadAttributes(rootSpan);
|
|
139
93
|
}
|
|
140
94
|
}
|
|
141
|
-
|
|
142
95
|
/**
|
|
143
96
|
* Begin profiling if not already running.
|
|
144
97
|
*/
|
|
145
|
-
|
|
98
|
+
_beginProfiling() {
|
|
146
99
|
if (this._isRunning) {
|
|
147
100
|
return;
|
|
148
101
|
}
|
|
149
102
|
this._isRunning = true;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// Expose profiler_id to match root spans with profiles
|
|
154
|
-
browser.getGlobalScope().setContext('profile', { profiler_id: this._profilerId });
|
|
155
|
-
|
|
103
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Started profiling with profiler ID:", this._profilerId);
|
|
104
|
+
browser.getGlobalScope().setContext("profile", { profiler_id: this._profilerId });
|
|
156
105
|
this._startProfilerInstance();
|
|
157
|
-
|
|
158
106
|
if (!this._profiler) {
|
|
159
|
-
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
107
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Failed to start JS Profiler; stopping.");
|
|
160
108
|
this._resetProfilerInfo();
|
|
161
109
|
return;
|
|
162
110
|
}
|
|
163
|
-
|
|
164
111
|
this._startPeriodicChunking();
|
|
165
112
|
}
|
|
166
|
-
|
|
167
113
|
/** End profiling session; final chunk will be collected and sent. */
|
|
168
|
-
|
|
114
|
+
_endProfiling() {
|
|
169
115
|
if (!this._isRunning) {
|
|
170
116
|
return;
|
|
171
117
|
}
|
|
172
118
|
this._isRunning = false;
|
|
173
|
-
|
|
174
119
|
if (this._chunkTimer) {
|
|
175
120
|
clearTimeout(this._chunkTimer);
|
|
176
|
-
this._chunkTimer =
|
|
121
|
+
this._chunkTimer = void 0;
|
|
177
122
|
}
|
|
178
|
-
|
|
179
123
|
this._clearAllRootSpanTimeouts();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
this._collectCurrentChunk().catch(e => {
|
|
183
|
-
debugBuild.DEBUG_BUILD && browser.debug.error('[Profiling] Failed to collect current profile chunk on `stop()`:', e);
|
|
124
|
+
this._collectCurrentChunk().catch((e) => {
|
|
125
|
+
debugBuild.DEBUG_BUILD && browser.debug.error("[Profiling] Failed to collect current profile chunk on `stop()`:", e);
|
|
184
126
|
});
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Trace: Profile context is kept for the whole session duration
|
|
188
|
-
if (this._lifecycleMode === 'manual') {
|
|
189
|
-
browser.getGlobalScope().setContext('profile', {});
|
|
127
|
+
if (this._lifecycleMode === "manual") {
|
|
128
|
+
browser.getGlobalScope().setContext("profile", {});
|
|
190
129
|
}
|
|
191
130
|
}
|
|
192
|
-
|
|
193
131
|
/** Trace-mode: attach spanStart/spanEnd listeners. */
|
|
194
|
-
|
|
195
|
-
client.on(
|
|
132
|
+
_setupTraceLifecycleListeners(client) {
|
|
133
|
+
client.on("spanStart", (span) => {
|
|
196
134
|
if (!this._sessionSampled) {
|
|
197
|
-
debugBuild.DEBUG_BUILD &&
|
|
198
|
-
browser.debug.log('[Profiling] Span not profiled because of negative sampling decision for user session.');
|
|
135
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Span not profiled because of negative sampling decision for user session.");
|
|
199
136
|
return;
|
|
200
137
|
}
|
|
201
138
|
if (span !== browser.getRootSpan(span)) {
|
|
202
|
-
return;
|
|
139
|
+
return;
|
|
203
140
|
}
|
|
204
|
-
// Only count sampled root spans
|
|
205
141
|
if (!span.isRecording()) {
|
|
206
|
-
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
142
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Discarding profile because root span was not sampled.");
|
|
207
143
|
return;
|
|
208
144
|
}
|
|
209
|
-
|
|
210
145
|
const spanId = span.spanContext().spanId;
|
|
211
146
|
if (!spanId || this._activeRootSpanIds.has(spanId)) {
|
|
212
147
|
return;
|
|
213
148
|
}
|
|
214
|
-
|
|
215
149
|
this._registerTraceRootSpan(spanId);
|
|
216
|
-
|
|
217
150
|
const rootSpanCount = this._activeRootSpanIds.size;
|
|
218
151
|
if (rootSpanCount === 1) {
|
|
219
|
-
debugBuild.DEBUG_BUILD &&
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
);
|
|
152
|
+
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
153
|
+
`[Profiling] Root span ${spanId} started. Profiling active while there are active root spans (count=${rootSpanCount}).`
|
|
154
|
+
);
|
|
223
155
|
this._beginProfiling();
|
|
224
156
|
}
|
|
225
157
|
});
|
|
226
|
-
|
|
227
|
-
client.on('spanEnd', span => {
|
|
158
|
+
client.on("spanEnd", (span) => {
|
|
228
159
|
if (!this._sessionSampled) {
|
|
229
160
|
return;
|
|
230
161
|
}
|
|
@@ -234,173 +165,139 @@ class UIProfiler {
|
|
|
234
165
|
}
|
|
235
166
|
this._activeRootSpanIds.delete(spanId);
|
|
236
167
|
const rootSpanCount = this._activeRootSpanIds.size;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
`[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`,
|
|
241
|
-
);
|
|
168
|
+
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
169
|
+
`[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`
|
|
170
|
+
);
|
|
242
171
|
if (rootSpanCount === 0) {
|
|
243
|
-
this._collectCurrentChunk().catch(e => {
|
|
244
|
-
debugBuild.DEBUG_BUILD && browser.debug.error(
|
|
172
|
+
this._collectCurrentChunk().catch((e) => {
|
|
173
|
+
debugBuild.DEBUG_BUILD && browser.debug.error("[Profiling] Failed to collect current profile chunk on last `spanEnd`:", e);
|
|
245
174
|
});
|
|
246
175
|
this._endProfiling();
|
|
247
176
|
}
|
|
248
177
|
});
|
|
249
178
|
}
|
|
250
|
-
|
|
251
179
|
/**
|
|
252
180
|
* Resets profiling information from scope and resets running state (used on failure)
|
|
253
181
|
*/
|
|
254
|
-
|
|
182
|
+
_resetProfilerInfo() {
|
|
255
183
|
this._isRunning = false;
|
|
256
|
-
browser.getGlobalScope().setContext(
|
|
184
|
+
browser.getGlobalScope().setContext("profile", {});
|
|
257
185
|
}
|
|
258
|
-
|
|
259
186
|
/**
|
|
260
187
|
* Clear and reset all per-root-span timeouts.
|
|
261
188
|
*/
|
|
262
|
-
|
|
263
|
-
this._rootSpanTimeouts.forEach(timeout => clearTimeout(timeout));
|
|
189
|
+
_clearAllRootSpanTimeouts() {
|
|
190
|
+
this._rootSpanTimeouts.forEach((timeout) => clearTimeout(timeout));
|
|
264
191
|
this._rootSpanTimeouts.clear();
|
|
265
192
|
}
|
|
266
|
-
|
|
267
193
|
/** Keep track of root spans and schedule safeguard timeout (trace mode). */
|
|
268
|
-
|
|
194
|
+
_registerTraceRootSpan(spanId) {
|
|
269
195
|
this._activeRootSpanIds.add(spanId);
|
|
270
196
|
const timeout = setTimeout(() => this._onRootSpanTimeout(spanId), MAX_ROOT_SPAN_PROFILE_MS);
|
|
271
197
|
this._rootSpanTimeouts.set(spanId, timeout);
|
|
272
198
|
}
|
|
273
|
-
|
|
274
199
|
/**
|
|
275
200
|
* Start a profiler instance if needed.
|
|
276
201
|
*/
|
|
277
|
-
|
|
202
|
+
_startProfilerInstance() {
|
|
278
203
|
if (this._profiler?.stopped === false) {
|
|
279
|
-
return;
|
|
204
|
+
return;
|
|
280
205
|
}
|
|
281
206
|
const profiler = utils.startJSSelfProfile();
|
|
282
207
|
if (!profiler) {
|
|
283
|
-
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
208
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Failed to start JS Profiler.");
|
|
284
209
|
return;
|
|
285
210
|
}
|
|
286
211
|
this._profiler = profiler;
|
|
287
212
|
}
|
|
288
|
-
|
|
289
213
|
/**
|
|
290
214
|
* Schedule the next 60s chunk while running.
|
|
291
215
|
* Each tick collects a chunk and restarts the profiler.
|
|
292
216
|
* A chunk should be closed when there are no active root spans anymore OR when the maximum chunk interval is reached.
|
|
293
217
|
*/
|
|
294
|
-
|
|
218
|
+
_startPeriodicChunking() {
|
|
295
219
|
if (!this._isRunning) {
|
|
296
220
|
return;
|
|
297
221
|
}
|
|
298
|
-
|
|
299
222
|
this._chunkTimer = setTimeout(() => {
|
|
300
|
-
this._collectCurrentChunk().catch(e => {
|
|
301
|
-
debugBuild.DEBUG_BUILD && browser.debug.error(
|
|
223
|
+
this._collectCurrentChunk().catch((e) => {
|
|
224
|
+
debugBuild.DEBUG_BUILD && browser.debug.error("[Profiling] Failed to collect current profile chunk during periodic chunking:", e);
|
|
302
225
|
});
|
|
303
|
-
|
|
304
226
|
if (this._isRunning) {
|
|
305
227
|
this._startProfilerInstance();
|
|
306
|
-
|
|
307
228
|
if (!this._profiler) {
|
|
308
|
-
// If restart failed, stop scheduling further chunks and reset context.
|
|
309
229
|
this._resetProfilerInfo();
|
|
310
230
|
return;
|
|
311
231
|
}
|
|
312
|
-
|
|
313
232
|
this._startPeriodicChunking();
|
|
314
233
|
}
|
|
315
234
|
}, CHUNK_INTERVAL_MS);
|
|
316
235
|
}
|
|
317
|
-
|
|
318
236
|
/**
|
|
319
237
|
* Handle timeout for a specific root span ID to avoid indefinitely running profiler if `spanEnd` never fires.
|
|
320
238
|
* If this was the last active root span, collect the current chunk and stop profiling.
|
|
321
239
|
*/
|
|
322
|
-
|
|
323
|
-
// If span already ended, ignore
|
|
240
|
+
_onRootSpanTimeout(rootSpanId) {
|
|
324
241
|
if (!this._rootSpanTimeouts.has(rootSpanId)) {
|
|
325
242
|
return;
|
|
326
243
|
}
|
|
327
244
|
this._rootSpanTimeouts.delete(rootSpanId);
|
|
328
|
-
|
|
329
245
|
if (!this._activeRootSpanIds.has(rootSpanId)) {
|
|
330
246
|
return;
|
|
331
247
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
`[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \`.end()\`.`,
|
|
336
|
-
);
|
|
337
|
-
|
|
248
|
+
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
249
|
+
`[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \`.end()\`.`
|
|
250
|
+
);
|
|
338
251
|
this._activeRootSpanIds.delete(rootSpanId);
|
|
339
|
-
|
|
340
252
|
if (this._activeRootSpanIds.size === 0) {
|
|
341
253
|
this._endProfiling();
|
|
342
254
|
}
|
|
343
255
|
}
|
|
344
|
-
|
|
345
256
|
/**
|
|
346
257
|
* Stop current profiler instance, convert profile to chunk & send.
|
|
347
258
|
*/
|
|
348
|
-
|
|
259
|
+
async _collectCurrentChunk() {
|
|
349
260
|
const prevProfiler = this._profiler;
|
|
350
|
-
this._profiler =
|
|
351
|
-
|
|
261
|
+
this._profiler = void 0;
|
|
352
262
|
if (!prevProfiler) {
|
|
353
263
|
return;
|
|
354
264
|
}
|
|
355
|
-
|
|
356
265
|
try {
|
|
357
266
|
const profile = await prevProfiler.stop();
|
|
358
|
-
|
|
359
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
360
267
|
const chunk = utils.createProfileChunkPayload(profile, this._client, this._profilerId);
|
|
361
|
-
|
|
362
|
-
// Validate chunk before sending
|
|
363
268
|
const validationReturn = utils.validateProfileChunk(chunk);
|
|
364
|
-
if (
|
|
365
|
-
debugBuild.DEBUG_BUILD &&
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
);
|
|
269
|
+
if ("reason" in validationReturn) {
|
|
270
|
+
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
271
|
+
"[Profiling] Discarding invalid profile chunk (this is probably a bug in the SDK):",
|
|
272
|
+
validationReturn.reason
|
|
273
|
+
);
|
|
370
274
|
return;
|
|
371
275
|
}
|
|
372
|
-
|
|
373
276
|
this._sendProfileChunk(chunk);
|
|
374
|
-
|
|
375
|
-
debugBuild.DEBUG_BUILD && browser.debug.log('[Profiling] Collected browser profile chunk.');
|
|
277
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Collected browser profile chunk.");
|
|
376
278
|
} catch (e) {
|
|
377
|
-
debugBuild.DEBUG_BUILD && browser.debug.log(
|
|
279
|
+
debugBuild.DEBUG_BUILD && browser.debug.log("[Profiling] Error while stopping JS Profiler for chunk:", e);
|
|
378
280
|
}
|
|
379
281
|
}
|
|
380
|
-
|
|
381
282
|
/**
|
|
382
283
|
* Send a profile chunk as a standalone envelope.
|
|
383
284
|
*/
|
|
384
|
-
|
|
385
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
285
|
+
_sendProfileChunk(chunk) {
|
|
386
286
|
const client = this._client;
|
|
387
|
-
|
|
388
287
|
const sdkInfo = browser.getSdkMetadataForEnvelopeHeader(client.getSdkMetadata?.());
|
|
389
288
|
const dsn = client.getDsn();
|
|
390
289
|
const tunnel = client.getOptions().tunnel;
|
|
391
|
-
|
|
392
290
|
const envelope = browser.createEnvelope(
|
|
393
291
|
{
|
|
394
292
|
event_id: browser.uuid4(),
|
|
395
|
-
sent_at: new Date().toISOString(),
|
|
396
|
-
...
|
|
397
|
-
|
|
293
|
+
sent_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
294
|
+
...sdkInfo && { sdk: sdkInfo },
|
|
295
|
+
...!!tunnel && dsn && { dsn: browser.dsnToString(dsn) }
|
|
398
296
|
},
|
|
399
|
-
[[{ type:
|
|
297
|
+
[[{ type: "profile_chunk", platform: "javascript" }, chunk]]
|
|
400
298
|
);
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
debugBuild.DEBUG_BUILD && browser.debug.error('Error while sending profile chunk envelope:', reason);
|
|
299
|
+
client.sendEnvelope(envelope).then(null, (reason) => {
|
|
300
|
+
debugBuild.DEBUG_BUILD && browser.debug.error("Error while sending profile chunk envelope:", reason);
|
|
404
301
|
});
|
|
405
302
|
}
|
|
406
303
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIProfiler.js","sources":["../../../../../src/profiling/UIProfiler.ts"],"sourcesContent":["import type { Client, ContinuousProfiler, ProfileChunk, ProfileChunkEnvelope, Span } from '@sentry/core/browser';\nimport {\n createEnvelope,\n debug,\n dsnToString,\n getGlobalScope,\n getRootSpan,\n getSdkMetadataForEnvelopeHeader,\n uuid4,\n} from '@sentry/core/browser';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from './../debug-build';\nimport type { JSSelfProfiler } from './jsSelfProfiling';\nimport {\n createProfileChunkPayload,\n setThreadAttributes,\n shouldProfileSession,\n startJSSelfProfile,\n validateProfileChunk,\n} from './utils';\n\nconst CHUNK_INTERVAL_MS = 60_000; // 1 minute\n// Maximum length for trace lifecycle profiling per root span (e.g. if spanEnd never fires)\nconst MAX_ROOT_SPAN_PROFILE_MS = 300_000; // 5 minutes max per root span in trace mode\n\n/**\n * UIProfiler (Profiling V2):\n * Supports two lifecycle modes:\n * - 'manual': controlled explicitly via start()/stop()\n * - 'trace': automatically runs while there are active sampled root spans\n *\n * Profiles are emitted as standalone `profile_chunk` envelopes either when:\n * - there are no more sampled root spans, or\n * - the 60s chunk timer elapses while profiling is running.\n */\nexport class UIProfiler implements ContinuousProfiler<Client> {\n private _client: Client | undefined;\n private _profiler: JSSelfProfiler | undefined;\n private _chunkTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Manual + Trace\n private _profilerId: string | undefined; // one per Profiler session\n private _isRunning: boolean; // current profiler instance active flag\n private _sessionSampled: boolean; // sampling decision for entire session\n private _lifecycleMode: 'manual' | 'trace' | undefined;\n\n // Trace-only\n private _activeRootSpanIds: Set<string>;\n private _rootSpanTimeouts: Map<string, ReturnType<typeof setTimeout>>;\n\n public constructor() {\n this._client = undefined;\n this._profiler = undefined;\n this._chunkTimer = undefined;\n\n this._profilerId = undefined;\n this._isRunning = false;\n this._sessionSampled = false;\n this._lifecycleMode = undefined;\n\n this._activeRootSpanIds = new Set();\n this._rootSpanTimeouts = new Map();\n }\n\n /**\n * Initialize the profiler with client, session sampling and lifecycle mode.\n */\n public initialize(client: Client): void {\n const lifecycleMode = (client.getOptions() as BrowserOptions).profileLifecycle;\n const sessionSampled = shouldProfileSession(client.getOptions());\n\n DEBUG_BUILD && debug.log(`[Profiling] Initializing profiler (lifecycle='${lifecycleMode}').`);\n\n if (!sessionSampled) {\n DEBUG_BUILD && debug.log('[Profiling] Session not sampled. Skipping lifecycle profiler initialization.');\n }\n\n // One Profiler ID per profiling session (user session)\n this._profilerId = uuid4();\n this._client = client;\n this._sessionSampled = sessionSampled;\n this._lifecycleMode = lifecycleMode;\n\n if (lifecycleMode === 'trace') {\n this._setupTraceLifecycleListeners(client);\n }\n\n client.on('spanStart', span => {\n if (this._isRunning) {\n setThreadAttributes(span);\n }\n });\n }\n\n /** Starts UI profiling (only effective in 'manual' mode and when sampled). */\n public start(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.start()` are ignored in trace mode.',\n );\n return;\n }\n\n if (this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profile session is already running, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n if (!this._sessionSampled) {\n DEBUG_BUILD && debug.warn('[Profiling] Session is not sampled, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n this._beginProfiling();\n }\n\n /** Stops UI profiling (only effective in 'manual' mode). */\n public stop(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.stop()` are ignored in trace mode.',\n );\n return;\n }\n\n if (!this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profiler is not running, `uiProfiler.stop()` is a no-op.');\n return;\n }\n\n this._endProfiling();\n }\n\n /** Handle an already-active root span at integration setup time (used only in trace mode). */\n public notifyRootSpanActive(rootSpan: Span): void {\n if (this._lifecycleMode !== 'trace' || !this._sessionSampled) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Detected already active root span during setup. Active root spans now:', rootSpanCount);\n\n this._beginProfiling();\n }\n\n if (this._isRunning) {\n setThreadAttributes(rootSpan);\n }\n }\n\n /**\n * Begin profiling if not already running.\n */\n private _beginProfiling(): void {\n if (this._isRunning) {\n return;\n }\n this._isRunning = true;\n\n DEBUG_BUILD && debug.log('[Profiling] Started profiling with profiler ID:', this._profilerId);\n\n // Expose profiler_id to match root spans with profiles\n getGlobalScope().setContext('profile', { profiler_id: this._profilerId });\n\n this._startProfilerInstance();\n\n if (!this._profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler; stopping.');\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n\n /** End profiling session; final chunk will be collected and sent. */\n private _endProfiling(): void {\n if (!this._isRunning) {\n return;\n }\n this._isRunning = false;\n\n if (this._chunkTimer) {\n clearTimeout(this._chunkTimer);\n this._chunkTimer = undefined;\n }\n\n this._clearAllRootSpanTimeouts();\n\n // Collect whatever was currently recording\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on `stop()`:', e);\n });\n\n // Manual: Clear profiling context so spans outside start()/stop() aren't marked as profiled\n // Trace: Profile context is kept for the whole session duration\n if (this._lifecycleMode === 'manual') {\n getGlobalScope().setContext('profile', {});\n }\n }\n\n /** Trace-mode: attach spanStart/spanEnd listeners. */\n private _setupTraceLifecycleListeners(client: Client): void {\n client.on('spanStart', span => {\n if (!this._sessionSampled) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Span not profiled because of negative sampling decision for user session.');\n return;\n }\n if (span !== getRootSpan(span)) {\n return; // only care about root spans\n }\n // Only count sampled root spans\n if (!span.isRecording()) {\n DEBUG_BUILD && debug.log('[Profiling] Discarding profile because root span was not sampled.');\n return;\n }\n\n const spanId = span.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span ${spanId} started. Profiling active while there are active root spans (count=${rootSpanCount}).`,\n );\n this._beginProfiling();\n }\n });\n\n client.on('spanEnd', span => {\n if (!this._sessionSampled) {\n return;\n }\n const spanId = span.spanContext().spanId;\n if (!spanId || !this._activeRootSpanIds.has(spanId)) {\n return;\n }\n this._activeRootSpanIds.delete(spanId);\n const rootSpanCount = this._activeRootSpanIds.size;\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`,\n );\n if (rootSpanCount === 0) {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on last `spanEnd`:', e);\n });\n this._endProfiling();\n }\n });\n }\n\n /**\n * Resets profiling information from scope and resets running state (used on failure)\n */\n private _resetProfilerInfo(): void {\n this._isRunning = false;\n getGlobalScope().setContext('profile', {});\n }\n\n /**\n * Clear and reset all per-root-span timeouts.\n */\n private _clearAllRootSpanTimeouts(): void {\n this._rootSpanTimeouts.forEach(timeout => clearTimeout(timeout));\n this._rootSpanTimeouts.clear();\n }\n\n /** Keep track of root spans and schedule safeguard timeout (trace mode). */\n private _registerTraceRootSpan(spanId: string): void {\n this._activeRootSpanIds.add(spanId);\n const timeout = setTimeout(() => this._onRootSpanTimeout(spanId), MAX_ROOT_SPAN_PROFILE_MS);\n this._rootSpanTimeouts.set(spanId, timeout);\n }\n\n /**\n * Start a profiler instance if needed.\n */\n private _startProfilerInstance(): void {\n if (this._profiler?.stopped === false) {\n return; // already running\n }\n const profiler = startJSSelfProfile();\n if (!profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler.');\n return;\n }\n this._profiler = profiler;\n }\n\n /**\n * Schedule the next 60s chunk while running.\n * Each tick collects a chunk and restarts the profiler.\n * A chunk should be closed when there are no active root spans anymore OR when the maximum chunk interval is reached.\n */\n private _startPeriodicChunking(): void {\n if (!this._isRunning) {\n return;\n }\n\n this._chunkTimer = setTimeout(() => {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk during periodic chunking:', e);\n });\n\n if (this._isRunning) {\n this._startProfilerInstance();\n\n if (!this._profiler) {\n // If restart failed, stop scheduling further chunks and reset context.\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n }, CHUNK_INTERVAL_MS);\n }\n\n /**\n * Handle timeout for a specific root span ID to avoid indefinitely running profiler if `spanEnd` never fires.\n * If this was the last active root span, collect the current chunk and stop profiling.\n */\n private _onRootSpanTimeout(rootSpanId: string): void {\n // If span already ended, ignore\n if (!this._rootSpanTimeouts.has(rootSpanId)) {\n return;\n }\n this._rootSpanTimeouts.delete(rootSpanId);\n\n if (!this._activeRootSpanIds.has(rootSpanId)) {\n return;\n }\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \\`.end()\\`.`,\n );\n\n this._activeRootSpanIds.delete(rootSpanId);\n\n if (this._activeRootSpanIds.size === 0) {\n this._endProfiling();\n }\n }\n\n /**\n * Stop current profiler instance, convert profile to chunk & send.\n */\n private async _collectCurrentChunk(): Promise<void> {\n const prevProfiler = this._profiler;\n this._profiler = undefined;\n\n if (!prevProfiler) {\n return;\n }\n\n try {\n const profile = await prevProfiler.stop();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const chunk = createProfileChunkPayload(profile, this._client!, this._profilerId);\n\n // Validate chunk before sending\n const validationReturn = validateProfileChunk(chunk);\n if ('reason' in validationReturn) {\n DEBUG_BUILD &&\n debug.log(\n '[Profiling] Discarding invalid profile chunk (this is probably a bug in the SDK):',\n validationReturn.reason,\n );\n return;\n }\n\n this._sendProfileChunk(chunk);\n\n DEBUG_BUILD && debug.log('[Profiling] Collected browser profile chunk.');\n } catch (e) {\n DEBUG_BUILD && debug.log('[Profiling] Error while stopping JS Profiler for chunk:', e);\n }\n }\n\n /**\n * Send a profile chunk as a standalone envelope.\n */\n private _sendProfileChunk(chunk: ProfileChunk): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const client = this._client!;\n\n const sdkInfo = getSdkMetadataForEnvelopeHeader(client.getSdkMetadata?.());\n const dsn = client.getDsn();\n const tunnel = client.getOptions().tunnel;\n\n const envelope = createEnvelope<ProfileChunkEnvelope>(\n {\n event_id: uuid4(),\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n },\n [[{ type: 'profile_chunk', platform: 'javascript' }, chunk]],\n );\n\n client.sendEnvelope(envelope).then(null, reason => {\n DEBUG_BUILD && debug.error('Error while sending profile chunk envelope:', reason);\n });\n }\n}\n"],"names":["shouldProfileSession","DEBUG_BUILD","debug","uuid4","setThreadAttributes","getGlobalScope","getRootSpan","startJSSelfProfile","createProfileChunkPayload","validateProfileChunk","getSdkMetadataForEnvelopeHeader","createEnvelope","dsnToString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UIProfiler.js","sources":["../../../../../src/profiling/UIProfiler.ts"],"sourcesContent":["import type { Client, ContinuousProfiler, ProfileChunk, ProfileChunkEnvelope, Span } from '@sentry/core/browser';\nimport {\n createEnvelope,\n debug,\n dsnToString,\n getGlobalScope,\n getRootSpan,\n getSdkMetadataForEnvelopeHeader,\n uuid4,\n} from '@sentry/core/browser';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from './../debug-build';\nimport type { JSSelfProfiler } from './jsSelfProfiling';\nimport {\n createProfileChunkPayload,\n setThreadAttributes,\n shouldProfileSession,\n startJSSelfProfile,\n validateProfileChunk,\n} from './utils';\n\nconst CHUNK_INTERVAL_MS = 60_000; // 1 minute\n// Maximum length for trace lifecycle profiling per root span (e.g. if spanEnd never fires)\nconst MAX_ROOT_SPAN_PROFILE_MS = 300_000; // 5 minutes max per root span in trace mode\n\n/**\n * UIProfiler (Profiling V2):\n * Supports two lifecycle modes:\n * - 'manual': controlled explicitly via start()/stop()\n * - 'trace': automatically runs while there are active sampled root spans\n *\n * Profiles are emitted as standalone `profile_chunk` envelopes either when:\n * - there are no more sampled root spans, or\n * - the 60s chunk timer elapses while profiling is running.\n */\nexport class UIProfiler implements ContinuousProfiler<Client> {\n private _client: Client | undefined;\n private _profiler: JSSelfProfiler | undefined;\n private _chunkTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Manual + Trace\n private _profilerId: string | undefined; // one per Profiler session\n private _isRunning: boolean; // current profiler instance active flag\n private _sessionSampled: boolean; // sampling decision for entire session\n private _lifecycleMode: 'manual' | 'trace' | undefined;\n\n // Trace-only\n private _activeRootSpanIds: Set<string>;\n private _rootSpanTimeouts: Map<string, ReturnType<typeof setTimeout>>;\n\n public constructor() {\n this._client = undefined;\n this._profiler = undefined;\n this._chunkTimer = undefined;\n\n this._profilerId = undefined;\n this._isRunning = false;\n this._sessionSampled = false;\n this._lifecycleMode = undefined;\n\n this._activeRootSpanIds = new Set();\n this._rootSpanTimeouts = new Map();\n }\n\n /**\n * Initialize the profiler with client, session sampling and lifecycle mode.\n */\n public initialize(client: Client): void {\n const lifecycleMode = (client.getOptions() as BrowserOptions).profileLifecycle;\n const sessionSampled = shouldProfileSession(client.getOptions());\n\n DEBUG_BUILD && debug.log(`[Profiling] Initializing profiler (lifecycle='${lifecycleMode}').`);\n\n if (!sessionSampled) {\n DEBUG_BUILD && debug.log('[Profiling] Session not sampled. Skipping lifecycle profiler initialization.');\n }\n\n // One Profiler ID per profiling session (user session)\n this._profilerId = uuid4();\n this._client = client;\n this._sessionSampled = sessionSampled;\n this._lifecycleMode = lifecycleMode;\n\n if (lifecycleMode === 'trace') {\n this._setupTraceLifecycleListeners(client);\n }\n\n client.on('spanStart', span => {\n if (this._isRunning) {\n setThreadAttributes(span);\n }\n });\n }\n\n /** Starts UI profiling (only effective in 'manual' mode and when sampled). */\n public start(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.start()` are ignored in trace mode.',\n );\n return;\n }\n\n if (this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profile session is already running, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n if (!this._sessionSampled) {\n DEBUG_BUILD && debug.warn('[Profiling] Session is not sampled, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n this._beginProfiling();\n }\n\n /** Stops UI profiling (only effective in 'manual' mode). */\n public stop(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.stop()` are ignored in trace mode.',\n );\n return;\n }\n\n if (!this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profiler is not running, `uiProfiler.stop()` is a no-op.');\n return;\n }\n\n this._endProfiling();\n }\n\n /** Handle an already-active root span at integration setup time (used only in trace mode). */\n public notifyRootSpanActive(rootSpan: Span): void {\n if (this._lifecycleMode !== 'trace' || !this._sessionSampled) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Detected already active root span during setup. Active root spans now:', rootSpanCount);\n\n this._beginProfiling();\n }\n\n if (this._isRunning) {\n setThreadAttributes(rootSpan);\n }\n }\n\n /**\n * Begin profiling if not already running.\n */\n private _beginProfiling(): void {\n if (this._isRunning) {\n return;\n }\n this._isRunning = true;\n\n DEBUG_BUILD && debug.log('[Profiling] Started profiling with profiler ID:', this._profilerId);\n\n // Expose profiler_id to match root spans with profiles\n getGlobalScope().setContext('profile', { profiler_id: this._profilerId });\n\n this._startProfilerInstance();\n\n if (!this._profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler; stopping.');\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n\n /** End profiling session; final chunk will be collected and sent. */\n private _endProfiling(): void {\n if (!this._isRunning) {\n return;\n }\n this._isRunning = false;\n\n if (this._chunkTimer) {\n clearTimeout(this._chunkTimer);\n this._chunkTimer = undefined;\n }\n\n this._clearAllRootSpanTimeouts();\n\n // Collect whatever was currently recording\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on `stop()`:', e);\n });\n\n // Manual: Clear profiling context so spans outside start()/stop() aren't marked as profiled\n // Trace: Profile context is kept for the whole session duration\n if (this._lifecycleMode === 'manual') {\n getGlobalScope().setContext('profile', {});\n }\n }\n\n /** Trace-mode: attach spanStart/spanEnd listeners. */\n private _setupTraceLifecycleListeners(client: Client): void {\n client.on('spanStart', span => {\n if (!this._sessionSampled) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Span not profiled because of negative sampling decision for user session.');\n return;\n }\n if (span !== getRootSpan(span)) {\n return; // only care about root spans\n }\n // Only count sampled root spans\n if (!span.isRecording()) {\n DEBUG_BUILD && debug.log('[Profiling] Discarding profile because root span was not sampled.');\n return;\n }\n\n const spanId = span.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span ${spanId} started. Profiling active while there are active root spans (count=${rootSpanCount}).`,\n );\n this._beginProfiling();\n }\n });\n\n client.on('spanEnd', span => {\n if (!this._sessionSampled) {\n return;\n }\n const spanId = span.spanContext().spanId;\n if (!spanId || !this._activeRootSpanIds.has(spanId)) {\n return;\n }\n this._activeRootSpanIds.delete(spanId);\n const rootSpanCount = this._activeRootSpanIds.size;\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`,\n );\n if (rootSpanCount === 0) {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on last `spanEnd`:', e);\n });\n this._endProfiling();\n }\n });\n }\n\n /**\n * Resets profiling information from scope and resets running state (used on failure)\n */\n private _resetProfilerInfo(): void {\n this._isRunning = false;\n getGlobalScope().setContext('profile', {});\n }\n\n /**\n * Clear and reset all per-root-span timeouts.\n */\n private _clearAllRootSpanTimeouts(): void {\n this._rootSpanTimeouts.forEach(timeout => clearTimeout(timeout));\n this._rootSpanTimeouts.clear();\n }\n\n /** Keep track of root spans and schedule safeguard timeout (trace mode). */\n private _registerTraceRootSpan(spanId: string): void {\n this._activeRootSpanIds.add(spanId);\n const timeout = setTimeout(() => this._onRootSpanTimeout(spanId), MAX_ROOT_SPAN_PROFILE_MS);\n this._rootSpanTimeouts.set(spanId, timeout);\n }\n\n /**\n * Start a profiler instance if needed.\n */\n private _startProfilerInstance(): void {\n if (this._profiler?.stopped === false) {\n return; // already running\n }\n const profiler = startJSSelfProfile();\n if (!profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler.');\n return;\n }\n this._profiler = profiler;\n }\n\n /**\n * Schedule the next 60s chunk while running.\n * Each tick collects a chunk and restarts the profiler.\n * A chunk should be closed when there are no active root spans anymore OR when the maximum chunk interval is reached.\n */\n private _startPeriodicChunking(): void {\n if (!this._isRunning) {\n return;\n }\n\n this._chunkTimer = setTimeout(() => {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk during periodic chunking:', e);\n });\n\n if (this._isRunning) {\n this._startProfilerInstance();\n\n if (!this._profiler) {\n // If restart failed, stop scheduling further chunks and reset context.\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n }, CHUNK_INTERVAL_MS);\n }\n\n /**\n * Handle timeout for a specific root span ID to avoid indefinitely running profiler if `spanEnd` never fires.\n * If this was the last active root span, collect the current chunk and stop profiling.\n */\n private _onRootSpanTimeout(rootSpanId: string): void {\n // If span already ended, ignore\n if (!this._rootSpanTimeouts.has(rootSpanId)) {\n return;\n }\n this._rootSpanTimeouts.delete(rootSpanId);\n\n if (!this._activeRootSpanIds.has(rootSpanId)) {\n return;\n }\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \\`.end()\\`.`,\n );\n\n this._activeRootSpanIds.delete(rootSpanId);\n\n if (this._activeRootSpanIds.size === 0) {\n this._endProfiling();\n }\n }\n\n /**\n * Stop current profiler instance, convert profile to chunk & send.\n */\n private async _collectCurrentChunk(): Promise<void> {\n const prevProfiler = this._profiler;\n this._profiler = undefined;\n\n if (!prevProfiler) {\n return;\n }\n\n try {\n const profile = await prevProfiler.stop();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const chunk = createProfileChunkPayload(profile, this._client!, this._profilerId);\n\n // Validate chunk before sending\n const validationReturn = validateProfileChunk(chunk);\n if ('reason' in validationReturn) {\n DEBUG_BUILD &&\n debug.log(\n '[Profiling] Discarding invalid profile chunk (this is probably a bug in the SDK):',\n validationReturn.reason,\n );\n return;\n }\n\n this._sendProfileChunk(chunk);\n\n DEBUG_BUILD && debug.log('[Profiling] Collected browser profile chunk.');\n } catch (e) {\n DEBUG_BUILD && debug.log('[Profiling] Error while stopping JS Profiler for chunk:', e);\n }\n }\n\n /**\n * Send a profile chunk as a standalone envelope.\n */\n private _sendProfileChunk(chunk: ProfileChunk): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const client = this._client!;\n\n const sdkInfo = getSdkMetadataForEnvelopeHeader(client.getSdkMetadata?.());\n const dsn = client.getDsn();\n const tunnel = client.getOptions().tunnel;\n\n const envelope = createEnvelope<ProfileChunkEnvelope>(\n {\n event_id: uuid4(),\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n },\n [[{ type: 'profile_chunk', platform: 'javascript' }, chunk]],\n );\n\n client.sendEnvelope(envelope).then(null, reason => {\n DEBUG_BUILD && debug.error('Error while sending profile chunk envelope:', reason);\n });\n }\n}\n"],"names":["shouldProfileSession","DEBUG_BUILD","debug","uuid4","setThreadAttributes","getGlobalScope","getRootSpan","startJSSelfProfile","createProfileChunkPayload","validateProfileChunk","getSdkMetadataForEnvelopeHeader","createEnvelope","dsnToString"],"mappings":"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"}
|