Skip to content

Commit 0a37791

Browse files
committed
feat: attach sdk info to chunks
1 parent 945cdbc commit 0a37791

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

packages/profiling-node/src/integration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class ContinuousProfiler {
231231
}
232232

233233
DEBUG_BUILD && logger.log(`[Profiling] Profile chunk ${this._chunkData.id} sent to Sentry.`);
234-
const chunk = createProfilingChunkEvent(this._client, this._client.getOptions(), profile, {
234+
const chunk = createProfilingChunkEvent(this._client, this._client.getOptions(), profile, this._client.getSdkMetadata()?.sdk, {
235235
chunk_id: this._chunkData.id,
236236
trace_id: this._chunkData.startTraceID,
237237
profiler_id: this._profilerId,

packages/profiling-node/src/utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,14 @@ function createProfileChunkPayload(
194194
trace_id,
195195
profiler_id,
196196
chunk_id,
197+
sdk,
197198
}: {
198199
release: string;
199200
environment: string;
200201
trace_id: string | undefined;
201202
chunk_id: string;
202203
profiler_id: string;
204+
sdk: SdkInfo | undefined;
203205
},
204206
): ProfileChunk {
205207
// Log a warning if the profile has an invalid traceId (should be uuidv4).
@@ -213,6 +215,10 @@ function createProfileChunkPayload(
213215

214216
const profile: ProfileChunk = {
215217
chunk_id: chunk_id,
218+
client_sdk: {
219+
name: sdk?.name ?? 'unknown',
220+
version: sdk?.version ?? 'unknown',
221+
},
216222
profiler_id: profiler_id,
217223
platform: 'node',
218224
version: CONTINUOUS_FORMAT_VERSION,
@@ -235,6 +241,7 @@ export function createProfilingChunkEvent(
235241
client: Client,
236242
options: { release?: string; environment?: string },
237243
profile: RawChunkCpuProfile,
244+
sdk: SdkInfo | undefined,
238245
identifiers: { trace_id: string | undefined; chunk_id: string; profiler_id: string },
239246
): ProfileChunk | null {
240247
if (!isValidProfileChunk(profile)) {
@@ -247,6 +254,7 @@ export function createProfilingChunkEvent(
247254
trace_id: identifiers.trace_id ?? '',
248255
chunk_id: identifiers.chunk_id,
249256
profiler_id: identifiers.profiler_id,
257+
sdk
250258
});
251259
}
252260

packages/profiling-node/test/spanProfileUtils.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Sentry from '@sentry/node';
22

33
import { getMainCarrier } from '@sentry/core';
44
import type { NodeClientOptions } from '@sentry/node/build/types/types';
5-
import type { Transport } from '@sentry/types';
5+
import type { ProfileChunk, Transport } from '@sentry/types';
66
import { GLOBAL_OBJ, createEnvelope, logger } from '@sentry/utils';
77
import { CpuProfilerBindings } from '../src/cpu_profiler';
88
import { type ProfilingIntegration, _nodeProfilingIntegration } from '../src/integration';
@@ -402,6 +402,51 @@ describe('continuous profiling', () => {
402402
delete getMainCarrier().__SENTRY__;
403403
});
404404

405+
it('attaches sdk metadata to chunks', () => {
406+
// @ts-expect-error we just mock the return type and ignore the signature
407+
jest.spyOn(CpuProfilerBindings, 'stopProfiling').mockImplementation(() => {
408+
return {
409+
samples: [
410+
{
411+
stack_id: 0,
412+
thread_id: '0',
413+
elapsed_since_start_ns: '10',
414+
},
415+
{
416+
stack_id: 0,
417+
thread_id: '0',
418+
elapsed_since_start_ns: '10',
419+
},
420+
],
421+
measurements: {},
422+
stacks: [[0]],
423+
frames: [],
424+
resources: [],
425+
profiler_logging_mode: 'lazy',
426+
};
427+
});
428+
429+
const [client, transport] = makeContinuousProfilingClient();
430+
Sentry.setCurrentClient(client);
431+
client.init();
432+
433+
const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({}));
434+
435+
const integration = client.getIntegrationByName<ProfilingIntegration>('ProfilingIntegration');
436+
if (!integration) {
437+
throw new Error('Profiling integration not found');
438+
}
439+
integration._profiler.start();
440+
jest.advanceTimersByTime(1000);
441+
integration._profiler.stop();
442+
jest.advanceTimersByTime(1000);
443+
444+
const profile = transportSpy.mock.calls?.[0]?.[0]?.[1]?.[0]?.[1] as ProfileChunk;
445+
expect(profile.client_sdk.name).toBe('sentry.javascript.node');
446+
expect(profile.client_sdk.version).toEqual(expect.stringMatching(/\d+\.\d+\.\d+/));
447+
});
448+
449+
405450
it('initializes the continuous profiler and binds the sentry client', () => {
406451
const startProfilingSpy = jest.spyOn(CpuProfilerBindings, 'startProfiling');
407452

packages/types/src/profiling.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,8 @@ export interface Profile extends BaseProfile<ThreadCpuProfile> {
126126
export interface ProfileChunk extends BaseProfile<ContinuousThreadCpuProfile> {
127127
chunk_id: string;
128128
profiler_id: string;
129+
client_sdk: {
130+
name: string;
131+
version: string;
132+
};
129133
}

0 commit comments

Comments
 (0)