Skip to content

Commit ab9a24b

Browse files
committed
fix it in node-experimental
1 parent 0661f49 commit ab9a24b

File tree

7 files changed

+159
-28
lines changed

7 files changed

+159
-28
lines changed

packages/node-experimental/src/sdk/client.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { trace } from '@opentelemetry/api';
55
import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
66
import { applySdkMetadata } from '@sentry/core';
77
import type { CaptureContext, Event, EventHint } from '@sentry/types';
8-
import { Scope, getIsolationScope } from './scope';
8+
import { Scope } from './scope';
99

1010
/** A client for using Sentry with Node & OpenTelemetry. */
1111
export class NodeExperimentalClient extends NodeClient {
@@ -54,7 +54,7 @@ export class NodeExperimentalClient extends NodeClient {
5454
event: Event,
5555
hint: EventHint,
5656
scope?: Scope,
57-
_isolationScope?: Scope,
57+
isolationScope?: Scope,
5858
): PromiseLike<Event | null> {
5959
let actualScope = scope;
6060

@@ -64,8 +64,6 @@ export class NodeExperimentalClient extends NodeClient {
6464
delete hint.captureContext;
6565
}
6666

67-
const isolationScope = _isolationScope || (scope && scope.isolationScope) || getIsolationScope();
68-
6967
return super._prepareEvent(event, hint, actualScope, isolationScope);
7068
}
7169
}

packages/node-experimental/src/sdk/scope.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ export function isInitialized(): boolean {
7272

7373
/** A fork of the classic scope with some otel specific stuff. */
7474
export class Scope extends OpenTelemetryScope implements ScopeInterface {
75-
// Overwrite this if you want to use a specific isolation scope here
76-
public isolationScope: Scope | undefined;
77-
7875
protected _client: Client | undefined;
7976

8077
protected _lastEventId: string | undefined;

packages/node-experimental/src/sdk/spanProcessor.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import type { Context } from '@opentelemetry/api';
21
import { SpanKind } from '@opentelemetry/api';
32
import type { Span } from '@opentelemetry/sdk-trace-base';
43
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
5-
import { SentrySpanProcessor, getClient, getSpanFinishScope } from '@sentry/opentelemetry';
4+
import { SentrySpanProcessor, getClient } from '@sentry/opentelemetry';
65

76
import type { Http } from '../integrations/http';
87
import type { NodeFetch } from '../integrations/node-fetch';
98
import type { NodeExperimentalClient } from '../types';
10-
import { getIsolationScope } from './api';
119
import { Scope } from './scope';
1210

1311
/**
@@ -18,18 +16,6 @@ export class NodeExperimentalSentrySpanProcessor extends SentrySpanProcessor {
1816
super({ scopeClass: Scope });
1917
}
2018

21-
/** @inheritDoc */
22-
public onStart(span: Span, parentContext: Context): void {
23-
super.onStart(span, parentContext);
24-
25-
// We need to make sure that we use the correct isolation scope when finishing the span
26-
// so we store it on the span finish scope for later use
27-
const scope = getSpanFinishScope(span) as Scope | undefined;
28-
if (scope) {
29-
scope.isolationScope = getIsolationScope();
30-
}
31-
}
32-
3319
/** @inheritDoc */
3420
protected _shouldSendSpanToSentry(span: Span): boolean {
3521
const client = getClient<NodeExperimentalClient>();

packages/node-experimental/src/sdk/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ export interface ScopeData {
2828
}
2929

3030
export interface Scope extends BaseScope {
31-
// @ts-expect-error typeof this is what we want here
32-
isolationScope: typeof this | undefined;
3331
// @ts-expect-error typeof this is what we want here
3432
clone(scope?: Scope): typeof this;
3533
/**

packages/node-experimental/test/integration/transactions.test.ts

Lines changed: 155 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ describe('Integration | Transactions', () => {
9999
environment: 'production',
100100
event_id: expect.any(String),
101101
platform: 'node',
102-
sdkProcessingMetadata: {
102+
sdkProcessingMetadata: expect.objectContaining({
103103
dynamicSamplingContext: expect.objectContaining({
104104
environment: 'production',
105105
public_key: expect.any(String),
@@ -112,7 +112,7 @@ describe('Integration | Transactions', () => {
112112
source: 'task',
113113
spanMetadata: expect.any(Object),
114114
requestPath: 'test-path',
115-
},
115+
}),
116116
server_name: expect.any(String),
117117
// spans are circular (they have a reference to the transaction), which leads to jest choking on this
118118
// instead we compare them in detail below
@@ -329,6 +329,159 @@ describe('Integration | Transactions', () => {
329329
);
330330
});
331331

332+
it('correctly creates concurrent transaction & spans when using native OTEL tracer', async () => {
333+
const beforeSendTransaction = jest.fn(() => null);
334+
335+
mockSdkInit({ enableTracing: true, beforeSendTransaction });
336+
337+
const client = Sentry.getClient<NodeExperimentalClient>();
338+
339+
Sentry.addBreadcrumb({ message: 'test breadcrumb 1', timestamp: 123456 });
340+
341+
Sentry.withIsolationScope(() => {
342+
client.tracer.startActiveSpan('test name', span => {
343+
Sentry.addBreadcrumb({ message: 'test breadcrumb 2', timestamp: 123456 });
344+
345+
span.setAttributes({
346+
'test.outer': 'test value',
347+
});
348+
349+
const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' });
350+
subSpan.end();
351+
352+
Sentry.setTag('test.tag', 'test value');
353+
354+
client.tracer.startActiveSpan('inner span 2', innerSpan => {
355+
Sentry.addBreadcrumb({ message: 'test breadcrumb 3', timestamp: 123456 });
356+
357+
innerSpan.setAttributes({
358+
'test.inner': 'test value',
359+
});
360+
361+
innerSpan.end();
362+
});
363+
364+
span.end();
365+
});
366+
});
367+
368+
Sentry.withIsolationScope(() => {
369+
client.tracer.startActiveSpan('test name b', span => {
370+
Sentry.addBreadcrumb({ message: 'test breadcrumb 2b', timestamp: 123456 });
371+
372+
span.setAttributes({
373+
'test.outer': 'test value b',
374+
});
375+
376+
const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1b' });
377+
subSpan.end();
378+
379+
Sentry.setTag('test.tag', 'test value b');
380+
381+
client.tracer.startActiveSpan('inner span 2b', innerSpan => {
382+
Sentry.addBreadcrumb({ message: 'test breadcrumb 3b', timestamp: 123456 });
383+
384+
innerSpan.setAttributes({
385+
'test.inner': 'test value b',
386+
});
387+
388+
innerSpan.end();
389+
});
390+
391+
span.end();
392+
});
393+
});
394+
395+
await client.flush();
396+
397+
expect(beforeSendTransaction).toHaveBeenCalledTimes(2);
398+
expect(beforeSendTransaction).toHaveBeenCalledWith(
399+
expect.objectContaining({
400+
breadcrumbs: [
401+
{ message: 'test breadcrumb 1', timestamp: 123456 },
402+
{ message: 'test breadcrumb 2', timestamp: 123456 },
403+
{ message: 'test breadcrumb 3', timestamp: 123456 },
404+
],
405+
contexts: expect.objectContaining({
406+
otel: expect.objectContaining({
407+
attributes: {
408+
'test.outer': 'test value',
409+
},
410+
}),
411+
trace: {
412+
data: {
413+
'otel.kind': 'INTERNAL',
414+
'sentry.origin': 'manual',
415+
},
416+
span_id: expect.any(String),
417+
status: 'ok',
418+
trace_id: expect.any(String),
419+
origin: 'manual',
420+
},
421+
}),
422+
spans: [
423+
expect.objectContaining({
424+
description: 'inner span 1',
425+
}),
426+
expect.objectContaining({
427+
description: 'inner span 2',
428+
}),
429+
],
430+
start_timestamp: expect.any(Number),
431+
tags: { 'test.tag': 'test value' },
432+
timestamp: expect.any(Number),
433+
transaction: 'test name',
434+
type: 'transaction',
435+
}),
436+
{
437+
event_id: expect.any(String),
438+
},
439+
);
440+
441+
expect(beforeSendTransaction).toHaveBeenCalledWith(
442+
expect.objectContaining({
443+
breadcrumbs: [
444+
{ message: 'test breadcrumb 1', timestamp: 123456 },
445+
{ message: 'test breadcrumb 2b', timestamp: 123456 },
446+
{ message: 'test breadcrumb 3b', timestamp: 123456 },
447+
],
448+
contexts: expect.objectContaining({
449+
otel: expect.objectContaining({
450+
attributes: {
451+
'test.outer': 'test value b',
452+
},
453+
}),
454+
trace: {
455+
data: {
456+
'otel.kind': 'INTERNAL',
457+
'sentry.origin': 'manual',
458+
},
459+
span_id: expect.any(String),
460+
status: 'ok',
461+
trace_id: expect.any(String),
462+
origin: 'manual',
463+
},
464+
}),
465+
spans: [
466+
expect.objectContaining({
467+
description: 'inner span 1b',
468+
}),
469+
expect.objectContaining({
470+
description: 'inner span 2b',
471+
}),
472+
],
473+
start_timestamp: expect.any(Number),
474+
tags: { 'test.tag': 'test value b' },
475+
timestamp: expect.any(Number),
476+
transaction: 'test name b',
477+
type: 'transaction',
478+
}),
479+
{
480+
event_id: expect.any(String),
481+
},
482+
);
483+
});
484+
332485
it('correctly creates transaction & spans with a trace header data', async () => {
333486
const beforeSendTransaction = jest.fn(() => null);
334487

packages/opentelemetry/src/custom/hub.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export class OpenTelemetryHub extends Hub {
1313
public constructor(client?: Client, scope: Scope = new OpenTelemetryScope(), isolationScope?: Scope) {
1414
super(client, scope, isolationScope);
1515
}
16-
1716
}
1817

1918
/**

packages/opentelemetry/test/integration/transactions.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { TraceFlags, context, trace } from '@opentelemetry/api';
22
import type { SpanProcessor } from '@opentelemetry/sdk-trace-base';
3-
import { addBreadcrumb, getClient, getIsolationScope, setTag, withIsolationScope } from '@sentry/core';
3+
import { addBreadcrumb, getClient, setTag, withIsolationScope } from '@sentry/core';
44
import type { PropagationContext, TransactionEvent } from '@sentry/types';
55
import { logger } from '@sentry/utils';
66

0 commit comments

Comments
 (0)