From bef3900d064d5142e2d9993664fa623c1f68174e Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 6 Jun 2024 10:59:09 -0400 Subject: [PATCH 1/9] feat(profiling) add profile chunk data to global context --- packages/profiling-node/src/integration.ts | 46 +++++++++++++++++++++- packages/profiling-node/src/utils.ts | 10 ++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 6cba86fe4f8d..249f6cd6d5d4 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -8,8 +8,10 @@ import { CpuProfilerBindings } from './cpu_profiler'; import { DEBUG_BUILD } from './debug-build'; import { NODE_MAJOR, NODE_VERSION } from './nodeVersion'; import { MAX_PROFILE_DURATION_MS, maybeProfileSpan, stopSpanProfile } from './spanProfileUtils'; -import type { RawThreadCpuProfile } from './types'; +import type { RawChunkCpuProfile, RawThreadCpuProfile } from './types'; import { ProfileFormat } from './types'; +import { getGlobalScope } from '../../core/src/currentScopes'; +import { PROFILER_THREAD_NAME } from './utils'; import { addProfilesToEnvelope, @@ -17,6 +19,7 @@ import { createProfilingEvent, findProfiledTransactionsFromEnvelope, makeProfileChunkEnvelope, + PROFILER_THREAD_ID_STRING, } from './utils'; const CHUNK_INTERVAL_MS = 5000; @@ -211,7 +214,9 @@ class ContinuousProfiler { logger.log(`[Profiling] Failed to collect profile for: ${this._chunkData?.id}, the chunk_id is missing.`); return; } - const profile = CpuProfilerBindings.stopProfiling(this._chunkData.id, ProfileFormat.CHUNK); + + const profile = this._stopChunkProfiling(this._chunkData); + if (!profile || !this._chunkData.startTimestampMS) { DEBUG_BUILD && logger.log(`[Profiling] _chunkiledStartTraceID to collect profile for: ${this._chunkData.id}`); return; @@ -274,11 +279,21 @@ class ContinuousProfiler { }); } + /** + * Stops the profile and clears chunk instrumentation from global scope + * @returns void + */ + private _stopChunkProfiling(chunk: ChunkData): RawChunkCpuProfile | null { + this._teardownSpanChunkInstrumentation(); + return CpuProfilerBindings.stopProfiling(chunk.id, ProfileFormat.CHUNK); + } + /** * Starts the profiler and registers the flush timer for a given chunk. * @param chunk */ private _startChunkProfiling(chunk: ChunkData): void { + this._setupSpanChunkInstrumentation(); CpuProfilerBindings.startProfiling(chunk.id!); DEBUG_BUILD && logger.log(`[Profiling] starting profiling chunk: ${chunk.id}`); @@ -293,6 +308,33 @@ class ContinuousProfiler { chunk.timer.unref(); } + /** + * Attaches profiling information to spans that were started + * during a profiling session. + */ + private _setupSpanChunkInstrumentation(): void { + // Set context once when the profiler session starts and have the spans inherit from it + const globalScope = getGlobalScope(); + globalScope.setExtra('trace', { + data: { + ['thread.id']: PROFILER_THREAD_ID_STRING, + ['thread.name']: PROFILER_THREAD_NAME, + } + }); + globalScope.setExtra('profiler', { + profiler_id: this._profilerId, + }); + } + + /** + * Clear profiling information from global context when a profile is not running. + */ + private _teardownSpanChunkInstrumentation(): void { + const globalScope = getGlobalScope(); + globalScope.setExtra('trace', undefined); + globalScope.setExtra('profiler', undefined); + } + /** * Initializes new profile chunk metadata */ diff --git a/packages/profiling-node/src/utils.ts b/packages/profiling-node/src/utils.ts index 5661129791bb..3641ca9fbbe8 100644 --- a/packages/profiling-node/src/utils.ts +++ b/packages/profiling-node/src/utils.ts @@ -28,8 +28,8 @@ import type { RawChunkCpuProfile, RawThreadCpuProfile } from './types'; // We require the file because if we import it, it will be included in the bundle. // I guess tsc does not check file contents when it's imported. -const THREAD_ID_STRING = String(threadId); -const THREAD_NAME = isMainThread ? 'main' : 'worker'; +export const PROFILER_THREAD_ID_STRING = String(threadId); +export const PROFILER_THREAD_NAME = isMainThread ? 'main' : 'worker'; const FORMAT_VERSION = '1'; const CONTINUOUS_FORMAT_VERSION = '2'; @@ -75,8 +75,8 @@ export function enrichWithThreadInformation( frames: profile.frames, stacks: profile.stacks, thread_metadata: { - [THREAD_ID_STRING]: { - name: THREAD_NAME, + [PROFILER_THREAD_ID_STRING]: { + name: PROFILER_THREAD_NAME, }, }, } as ThreadCpuProfile | ContinuousThreadCpuProfile; @@ -172,7 +172,7 @@ function createProfilePayload( name: transaction, id: event_id, trace_id: trace_id || '', - active_thread_id: THREAD_ID_STRING, + active_thread_id: PROFILER_THREAD_ID_STRING, }, }; From 484dde77f172b6b25726e177c09cb0ddb583c82a Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 6 Jun 2024 14:05:33 -0400 Subject: [PATCH 2/9] feat(profiling) add profile context to global scope --- packages/profiling-node/src/integration.ts | 15 ++----- .../profiling-node/src/spanProfileUtils.ts | 1 - .../test/spanProfileUtils.test.ts | 42 ++++++++++++++++++- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 249f6cd6d5d4..1e228f6f776f 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -12,6 +12,7 @@ import type { RawChunkCpuProfile, RawThreadCpuProfile } from './types'; import { ProfileFormat } from './types'; import { getGlobalScope } from '../../core/src/currentScopes'; import { PROFILER_THREAD_NAME } from './utils'; +import { setContext } from '../../core/src/exports'; import { addProfilesToEnvelope, @@ -313,16 +314,10 @@ class ContinuousProfiler { * during a profiling session. */ private _setupSpanChunkInstrumentation(): void { - // Set context once when the profiler session starts and have the spans inherit from it - const globalScope = getGlobalScope(); - globalScope.setExtra('trace', { - data: { - ['thread.id']: PROFILER_THREAD_ID_STRING, - ['thread.name']: PROFILER_THREAD_NAME, - } - }); - globalScope.setExtra('profiler', { + getGlobalScope().setContext('profile', { profiler_id: this._profilerId, + ['thread.id']: PROFILER_THREAD_ID_STRING, + ['thread.name']: PROFILER_THREAD_NAME, }); } @@ -331,8 +326,6 @@ class ContinuousProfiler { */ private _teardownSpanChunkInstrumentation(): void { const globalScope = getGlobalScope(); - globalScope.setExtra('trace', undefined); - globalScope.setExtra('profiler', undefined); } /** diff --git a/packages/profiling-node/src/spanProfileUtils.ts b/packages/profiling-node/src/spanProfileUtils.ts index 1b347a61b741..ee6d29b8bb93 100644 --- a/packages/profiling-node/src/spanProfileUtils.ts +++ b/packages/profiling-node/src/spanProfileUtils.ts @@ -115,7 +115,6 @@ export function stopSpanProfile(span: Span, profile_id: string | undefined): Raw } const profile = CpuProfilerBindings.stopProfiling(profile_id, 0); - DEBUG_BUILD && logger.log(`[Profiling] stopped profiling of transaction: ${spanToJSON(span).description}`); // In case of an overlapping span, stopProfiling may return null and silently ignore the overlapping profile. diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index 9cc2ae58a972..5a143812269d 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -574,6 +574,47 @@ describe('continuous profiling', () => { expect(transportSpy.mock.calls?.[0]?.[0]?.[1]?.[0]?.[0].type).toBe('profile_chunk'); }); + + it('sets global profile context', async () => { + const [client, transport] = makeContinuousProfilingClient(); + Sentry.setCurrentClient(client); + client.init(); + + const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); + + const nonProfiledTransaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); + nonProfiledTransaction.end(); + + expect(transportSpy.mock.calls?.[0]?.[0]?.[1]?.[0]?.[1]).not.toMatchObject({ + contexts: { + profiler: { + profiler_id: expect.any(String), + ['thread.id']: expect.any(String), + ['thread.name']: expect.any(String), + }, + }, + }); + + const integration = client.getIntegrationByName('ProfilingIntegration'); + if (!integration) { + throw new Error('Profiling integration not found'); + } + + integration._profiler.start(); + const profiledTransaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); + profiledTransaction.end(); + integration._profiler.stop(); + + expect(transportSpy.mock.calls?.[1]?.[0]?.[1]?.[0]?.[1]).toMatchObject({ + contexts: { + profile: { + profiler_id: expect.any(String), + ['thread.id']: expect.any(String), + ['thread.name']: expect.any(String), + }, + }, + }); + }); }); describe('span profiling mode', () => { @@ -610,7 +651,6 @@ describe('span profiling mode', () => { Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); expect(startProfilingSpy).toHaveBeenCalled(); - const integration = client.getIntegrationByName('ProfilingIntegration'); if (!integration) { From 1fe34a74a2fe303661795428cf555ac33455a281 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 6 Jun 2024 14:39:58 -0400 Subject: [PATCH 3/9] feat(profiling) add profile context to global scope --- packages/profiling-node/src/integration.ts | 1 + packages/profiling-node/test/spanProfileUtils.test.ts | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 1e228f6f776f..461c323d8258 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -326,6 +326,7 @@ class ContinuousProfiler { */ private _teardownSpanChunkInstrumentation(): void { const globalScope = getGlobalScope(); + globalScope.setContext('profile', {}); } /** diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index 5a143812269d..1f058fb426a6 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -587,11 +587,7 @@ describe('continuous profiling', () => { expect(transportSpy.mock.calls?.[0]?.[0]?.[1]?.[0]?.[1]).not.toMatchObject({ contexts: { - profiler: { - profiler_id: expect.any(String), - ['thread.id']: expect.any(String), - ['thread.name']: expect.any(String), - }, + profile: {}, }, }); From 58440889625d14173d98dec999feb1414558dbde Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 6 Jun 2024 15:24:02 -0400 Subject: [PATCH 4/9] lint --- packages/profiling-node/src/integration.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 461c323d8258..7a2e60b03849 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -12,7 +12,6 @@ import type { RawChunkCpuProfile, RawThreadCpuProfile } from './types'; import { ProfileFormat } from './types'; import { getGlobalScope } from '../../core/src/currentScopes'; import { PROFILER_THREAD_NAME } from './utils'; -import { setContext } from '../../core/src/exports'; import { addProfilesToEnvelope, @@ -295,7 +294,7 @@ class ContinuousProfiler { */ private _startChunkProfiling(chunk: ChunkData): void { this._setupSpanChunkInstrumentation(); - CpuProfilerBindings.startProfiling(chunk.id!); + CpuProfilerBindings.startProfiling(chunk.id); DEBUG_BUILD && logger.log(`[Profiling] starting profiling chunk: ${chunk.id}`); chunk.timer = global.setTimeout(() => { From cbb65fe3c3cbffd7e373f7d4a2847dd7e86c9f52 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Sun, 9 Jun 2024 17:50:54 -0400 Subject: [PATCH 5/9] fix(profiling) assign thread data on trace field --- packages/profiling-node/src/integration.ts | 32 +++++++++++++++++-- .../test/spanProfileUtils.test.ts | 9 ++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 7a2e60b03849..20c1473eef6a 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -313,11 +313,17 @@ class ContinuousProfiler { * during a profiling session. */ private _setupSpanChunkInstrumentation(): void { + if (!this._client) { + DEBUG_BUILD && + logger.log('[Profiling] Failed to collect profile, sentry client was never attached to the profiler.'); + return; + } + getGlobalScope().setContext('profile', { profiler_id: this._profilerId, - ['thread.id']: PROFILER_THREAD_ID_STRING, - ['thread.name']: PROFILER_THREAD_NAME, }); + + this._client.on('beforeSendEvent', this._assignThreadIdContext); } /** @@ -340,6 +346,28 @@ class ContinuousProfiler { }; } + /** + * Assigns thread_id and thread name context to a profiled event. + */ + private _assignThreadIdContext(event: any): any { + if (!event.contexts?.profile) { + return; + } + + if (!event.contexts) { + return; + } + + event.contexts.trace = { + ...(event.contexts.trace ?? {}), + data: { + ...event.contexts.trace?.data, + ['thread.id']: PROFILER_THREAD_ID_STRING, + ['thread.name']: PROFILER_THREAD_NAME, + }, + }; + } + /** * Resets the current chunk state. */ diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index 1f058fb426a6..213a920cbd34 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -322,7 +322,6 @@ describe('automated span instrumentation', () => { transaction.end(); expect(stopProfilingSpy).toHaveBeenCalledTimes(1); }); - it('enriches profile with debug_id', async () => { GLOBAL_OBJ._sentryDebugIds = { 'Error\n at filename.js (filename.js:36:15)': 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa', @@ -603,10 +602,14 @@ describe('continuous profiling', () => { expect(transportSpy.mock.calls?.[1]?.[0]?.[1]?.[0]?.[1]).toMatchObject({ contexts: { + trace: { + data: expect.objectContaining({ + ['thread.id']: expect.any(String), + ['thread.name']: expect.any(String), + }) + }, profile: { profiler_id: expect.any(String), - ['thread.id']: expect.any(String), - ['thread.name']: expect.any(String), }, }, }); From 8d8fbf32e3d35d5b93d1c9ed4a92827709103846 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Mon, 10 Jun 2024 09:31:17 -0400 Subject: [PATCH 6/9] lint --- packages/profiling-node/src/integration.ts | 4 ++-- packages/profiling-node/test/spanProfileUtils.test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 20c1473eef6a..39a419dfb869 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -4,22 +4,22 @@ import type { Integration, IntegrationFn, Profile, ProfileChunk, Span } from '@s import { LRUMap, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; +import { getGlobalScope } from '../../core/src/currentScopes'; import { CpuProfilerBindings } from './cpu_profiler'; import { DEBUG_BUILD } from './debug-build'; import { NODE_MAJOR, NODE_VERSION } from './nodeVersion'; import { MAX_PROFILE_DURATION_MS, maybeProfileSpan, stopSpanProfile } from './spanProfileUtils'; import type { RawChunkCpuProfile, RawThreadCpuProfile } from './types'; import { ProfileFormat } from './types'; -import { getGlobalScope } from '../../core/src/currentScopes'; import { PROFILER_THREAD_NAME } from './utils'; import { + PROFILER_THREAD_ID_STRING, addProfilesToEnvelope, createProfilingChunkEvent, createProfilingEvent, findProfiledTransactionsFromEnvelope, makeProfileChunkEnvelope, - PROFILER_THREAD_ID_STRING, } from './utils'; const CHUNK_INTERVAL_MS = 5000; diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index 213a920cbd34..21a166319778 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -606,7 +606,7 @@ describe('continuous profiling', () => { data: expect.objectContaining({ ['thread.id']: expect.any(String), ['thread.name']: expect.any(String), - }) + }), }, profile: { profiler_id: expect.any(String), From 82cc110a4853c8156dc337f33d827a0777ace438 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Mon, 10 Jun 2024 10:08:01 -0400 Subject: [PATCH 7/9] fix context access --- packages/profiling-node/src/integration.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 39a419dfb869..574c0250e76a 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -1,6 +1,6 @@ import { defineIntegration, getCurrentScope, getIsolationScope, getRootSpan, spanToJSON } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; -import type { Integration, IntegrationFn, Profile, ProfileChunk, Span } from '@sentry/types'; +import type { Event, Integration, IntegrationFn, Profile, ProfileChunk, Span } from '@sentry/types'; import { LRUMap, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; @@ -323,7 +323,7 @@ class ContinuousProfiler { profiler_id: this._profilerId, }); - this._client.on('beforeSendEvent', this._assignThreadIdContext); + this._client.on('beforeSendEvent', e => this._assignThreadIdContext(e)); } /** @@ -349,8 +349,8 @@ class ContinuousProfiler { /** * Assigns thread_id and thread name context to a profiled event. */ - private _assignThreadIdContext(event: any): any { - if (!event.contexts?.profile) { + private _assignThreadIdContext(event: Event): any { + if (!event?.['contexts']?.['profile']) { return; } @@ -358,10 +358,12 @@ class ContinuousProfiler { return; } - event.contexts.trace = { - ...(event.contexts.trace ?? {}), + // @ts-expect-error the trace fallback value is wrong, though it should never happen + // and in case it does, we dont want to override whatever was passed initially. + event.contexts['trace'] = { + ...(event.contexts?.['trace'] ?? {}), data: { - ...event.contexts.trace?.data, + ...(event.contexts?.['trace']?.['data'] ?? {}), ['thread.id']: PROFILER_THREAD_ID_STRING, ['thread.name']: PROFILER_THREAD_NAME, }, From 5092d74e04915488ad1cc62505680b9bb9c5b2cd Mon Sep 17 00:00:00 2001 From: JonasBa Date: Mon, 10 Jun 2024 15:56:21 -0400 Subject: [PATCH 8/9] add isolated worker test --- .../test/spanProfileUtils.test.ts | 2 - .../test/spanProfileUtils.worker.test.ts | 75 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 packages/profiling-node/test/spanProfileUtils.worker.test.ts diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index 21a166319778..f2ca1b932e12 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -7,8 +7,6 @@ import { GLOBAL_OBJ, createEnvelope, logger } from '@sentry/utils'; import { CpuProfilerBindings } from '../src/cpu_profiler'; import { type ProfilingIntegration, _nodeProfilingIntegration } from '../src/integration'; -jest.setTimeout(10000); - function makeClientWithHooks(): [Sentry.NodeClient, Transport] { const integration = _nodeProfilingIntegration(); const client = new Sentry.NodeClient({ diff --git a/packages/profiling-node/test/spanProfileUtils.worker.test.ts b/packages/profiling-node/test/spanProfileUtils.worker.test.ts new file mode 100644 index 000000000000..135f1cd5be66 --- /dev/null +++ b/packages/profiling-node/test/spanProfileUtils.worker.test.ts @@ -0,0 +1,75 @@ +// Mock the modules before the import, so that the value is initialized before the module is loaded +jest.mock('worker_threads', () => { + return { + isMainThread: false, + threadId: 9999, + } +}) +jest.setTimeout(10000); + +import * as Sentry from '@sentry/node'; +import type { Transport } from '@sentry/types'; +import { type ProfilingIntegration, _nodeProfilingIntegration } from '../src/integration'; + +function makeContinuousProfilingClient(): [Sentry.NodeClient, Transport] { + const integration = _nodeProfilingIntegration(); + const client = new Sentry.NodeClient({ + stackParser: Sentry.defaultStackParser, + tracesSampleRate: 1, + profilesSampleRate: undefined, + debug: true, + environment: 'test-environment', + dsn: 'https://7fa19397baaf433f919fbe02228d5470@o1137848.ingest.sentry.io/6625302', + integrations: [integration], + transport: _opts => + Sentry.makeNodeTransport({ + url: 'https://7fa19397baaf433f919fbe02228d5470@o1137848.ingest.sentry.io/6625302', + recordDroppedEvent: () => { + return undefined; + }, + }), + }); + + return [client, client.getTransport() as Transport]; +} + +it('worker threads context', () => { + const [client, transport] = makeContinuousProfilingClient(); + Sentry.setCurrentClient(client); + client.init(); + + const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); + + const nonProfiledTransaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); + nonProfiledTransaction.end(); + + expect(transportSpy.mock.calls?.[0]?.[0]?.[1]?.[0]?.[1]).not.toMatchObject({ + contexts: { + profile: {}, + }, + }); + + const integration = client.getIntegrationByName('ProfilingIntegration'); + if (!integration) { + throw new Error('Profiling integration not found'); + } + + integration._profiler.start(); + const profiledTransaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); + profiledTransaction.end(); + integration._profiler.stop(); + + expect(transportSpy.mock.calls?.[1]?.[0]?.[1]?.[0]?.[1]).toMatchObject({ + contexts: { + trace: { + data: expect.objectContaining({ + ['thread.id']: '9999', + ['thread.name']: 'worker', + }), + }, + profile: { + profiler_id: expect.any(String), + }, + }, + }); +}); From d2ccedf4e707875a9b28d46d54346e340b625b94 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Mon, 10 Jun 2024 16:01:01 -0400 Subject: [PATCH 9/9] lint --- packages/profiling-node/test/spanProfileUtils.worker.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/profiling-node/test/spanProfileUtils.worker.test.ts b/packages/profiling-node/test/spanProfileUtils.worker.test.ts index 135f1cd5be66..a119f80292d5 100644 --- a/packages/profiling-node/test/spanProfileUtils.worker.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.worker.test.ts @@ -3,8 +3,8 @@ jest.mock('worker_threads', () => { return { isMainThread: false, threadId: 9999, - } -}) + }; +}); jest.setTimeout(10000); import * as Sentry from '@sentry/node';