diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 943ae5e35c7b..19644cf985e2 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -258,6 +258,12 @@ class ContinuousProfiler { * Starts trace lifecycle profiling. Profiling will remain active as long as there is an active span. */ private _startTraceLifecycleProfiling(): void { + if (!this._sampled) { + DEBUG_BUILD && + debug.log('[Profiling] Profile session not sampled, trace lifecycle profiling will not be started.'); + return; + } + if (!this._client) { DEBUG_BUILD && debug.log( diff --git a/packages/profiling-node/test/integration.test.ts b/packages/profiling-node/test/integration.test.ts index 17da13aba191..13da995f303d 100644 --- a/packages/profiling-node/test/integration.test.ts +++ b/packages/profiling-node/test/integration.test.ts @@ -861,9 +861,28 @@ describe('ProfilingIntegration', () => { expect(stopProfilingSpy).not.toHaveBeenCalled(); }); + it('does not start profiler when profile session is not sampled', () => { + const [client] = makeCurrentSpanProfilingClient({ + profileLifecycle: 'trace', + profileSessionSampleRate: 0, + }); + + Sentry.setCurrentClient(client); + client.init(); + + const startProfilingSpy = vi.spyOn(CpuProfilerBindings, 'startProfiling'); + + const span = Sentry.startInactiveSpan({ forceTransaction: true, name: 'test' }); + + expect(startProfilingSpy).not.toHaveBeenCalled(); + + span.end(); + }); + it('starts profiler when first span is created', () => { const [client] = makeCurrentSpanProfilingClient({ profileLifecycle: 'trace', + profileSessionSampleRate: 1, }); Sentry.setCurrentClient(client); @@ -884,6 +903,7 @@ describe('ProfilingIntegration', () => { it('waits for the tail span to end before stopping the profiler', () => { const [client] = makeCurrentSpanProfilingClient({ profileLifecycle: 'trace', + profileSessionSampleRate: 1, }); Sentry.setCurrentClient(client); @@ -908,6 +928,7 @@ describe('ProfilingIntegration', () => { it('ending last span does not stop the profiler if first span is not ended', () => { const [client] = makeCurrentSpanProfilingClient({ profileLifecycle: 'trace', + profileSessionSampleRate: 1, }); Sentry.setCurrentClient(client); @@ -930,6 +951,7 @@ describe('ProfilingIntegration', () => { it('multiple calls to span.end do not restart the profiler', () => { const [client] = makeCurrentSpanProfilingClient({ profileLifecycle: 'trace', + profileSessionSampleRate: 1, }); Sentry.setCurrentClient(client);