Skip to content

Commit dad76f8

Browse files
committed
further fix isolation scopes
1 parent 8eccfe9 commit dad76f8

File tree

6 files changed

+51
-16
lines changed

6 files changed

+51
-16
lines changed

packages/core/src/tracing/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export {
2222
startActiveSpan,
2323
startSpanManual,
2424
continueTrace,
25+
setCapturedScopesOnSpan,
2526
} from './trace';
2627
export { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext';
2728
export { setMeasurement } from './measurement';

packages/core/src/tracing/trace.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,8 @@ type SpanWithScopes = Span & {
399399
[ISOLATION_SCOPE_ON_START_SPAN_FIELD]?: Scope;
400400
};
401401

402-
function setCapturedScopesOnSpan(span: Span | undefined, scope: Scope, isolationScope: Scope): void {
402+
/** Store the scope & isolation scope for a span, which can the be used when it is finished. */
403+
export function setCapturedScopesOnSpan(span: Span | undefined, scope: Scope, isolationScope: Scope): void {
403404
if (span) {
404405
addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope);
405406
addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope);

packages/opentelemetry/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export {
1212
getSpanParent,
1313
getSpanScope,
1414
setSpanMetadata,
15-
getSpanFinishScope,
15+
getSpanFinishScopes,
1616
} from './utils/spanData';
1717

1818
export { getPropagationContextFromContext, setPropagationContextOnContext, setHubOnContext } from './utils/contextData';

packages/opentelemetry/src/spanExporter.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import type { ExportResult } from '@opentelemetry/core';
33
import { ExportResultCode } from '@opentelemetry/core';
44
import type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base';
55
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
6-
import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, flush, getCurrentHub, getCurrentScope } from '@sentry/core';
6+
import {
7+
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
8+
flush,
9+
getCurrentHub,
10+
getCurrentScope,
11+
getIsolationScope,
12+
setCapturedScopesOnSpan,
13+
} from '@sentry/core';
714
import type { Scope, Span as SentrySpan, SpanOrigin, TransactionSource } from '@sentry/types';
815
import { logger } from '@sentry/utils';
916

@@ -17,7 +24,7 @@ import type { SpanNode } from './utils/groupSpansWithParents';
1724
import { groupSpansWithParents } from './utils/groupSpansWithParents';
1825
import { mapStatus } from './utils/mapStatus';
1926
import { parseSpanDescription } from './utils/parseSpanDescription';
20-
import { getSpanFinishScope, getSpanHub, getSpanMetadata, getSpanScope } from './utils/spanData';
27+
import { getSpanFinishScopes, getSpanHub, getSpanMetadata, getSpanScope } from './utils/spanData';
2128

2229
type SpanNodeCompleted = SpanNode & { span: ReadableSpan };
2330

@@ -109,24 +116,30 @@ function maybeSend(spans: ReadableSpan[]): ReadableSpan[] {
109116

110117
// Now finish the transaction, which will send it together with all the spans
111118
// We make sure to use the finish scope
112-
const scope = getScopeForTransactionFinish(span);
113-
transaction.finishWithScope(convertOtelTimeToSeconds(span.endTime), scope);
119+
const { scope, isolationScope } = getScopesForTransactionFinish(span);
120+
setCapturedScopesOnSpan(transaction, scope, isolationScope);
121+
122+
transaction.end(span.endTime);
114123
});
115124

116125
return Array.from(remaining)
117126
.map(node => node.span)
118127
.filter((span): span is ReadableSpan => !!span);
119128
}
120129

121-
function getScopeForTransactionFinish(span: ReadableSpan): Scope {
130+
function getScopesForTransactionFinish(span: ReadableSpan): { scope: Scope; isolationScope: Scope } {
122131
// The finish scope should normally always be there (and it is already a clone),
123132
// but for the sake of type safety we fall back to a clone of the current scope
124-
const scope = getSpanFinishScope(span) || getCurrentScope().clone();
133+
const scopes = getSpanFinishScopes(span);
134+
const scope = scopes?.scope || getCurrentScope().clone();
135+
const isolationScope = scopes?.isolationScope || getIsolationScope();
136+
125137
scope.setContext('otel', {
126138
attributes: removeSentryAttributes(span.attributes),
127139
resource: span.resource.attributes,
128140
});
129-
return scope;
141+
142+
return { scope, isolationScope };
130143
}
131144

132145
function getCompletedRootNodes(nodes: SpanNode[]): SpanNodeCompleted[] {

packages/opentelemetry/src/spanProcessor.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { DEBUG_BUILD } from './debug-build';
1010
import { SentrySpanExporter } from './spanExporter';
1111
import { maybeCaptureExceptionForTimedEvent } from './utils/captureExceptionForTimedEvent';
1212
import { getHubFromContext } from './utils/contextData';
13-
import { getSpanHub, setSpanFinishScope, setSpanHub, setSpanParent, setSpanScope } from './utils/spanData';
13+
import { getSpanHub, setSpanFinishScopes, setSpanHub, setSpanParent, setSpanScope } from './utils/spanData';
1414

1515
function onSpanStart(span: Span, parentContext: Context, _ScopeClass: typeof OpenTelemetryScope): void {
1616
// This is a reliable way to get the parent span - because this is exactly how the parent is identified in the OTEL SDK
@@ -34,13 +34,16 @@ function onSpanStart(span: Span, parentContext: Context, _ScopeClass: typeof Ope
3434
if (actualHub) {
3535
// eslint-disable-next-line deprecation/deprecation
3636
const scope = actualHub.getScope();
37+
// eslint-disable-next-line deprecation/deprecation
38+
const isolationScope = actualHub.getIsolationScope();
3739
setSpanScope(span, scope);
3840
setSpanHub(span, actualHub);
3941

4042
// Use this scope for finishing the span
4143
const finishScope = (scope as OpenTelemetryScope).clone();
44+
// this is needed for breadcrumbs, for now, as they are stored on the span currently
4245
finishScope.activeSpan = span;
43-
setSpanFinishScope(span, finishScope);
46+
setSpanFinishScopes(span, { scope: finishScope, isolationScope });
4447
}
4548
}
4649

packages/opentelemetry/src/utils/spanData.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ import type { AbstractSpan } from '../types';
77
// This way we can enhance the data that an OTEL Span natively gives us
88
// and since we are using weakmaps, we do not need to clean up after ourselves
99
const SpanScope = new WeakMap<AbstractSpan, Scope>();
10-
const SpanFinishScope = new WeakMap<AbstractSpan, Scope>();
10+
const SpanFinishScopes = new WeakMap<
11+
AbstractSpan,
12+
{
13+
scope: Scope;
14+
isolationScope: Scope;
15+
}
16+
>();
1117
const SpanHub = new WeakMap<AbstractSpan, Hub>();
1218
const SpanParent = new WeakMap<AbstractSpan, Span>();
1319
const SpanMetadata = new WeakMap<AbstractSpan, Partial<TransactionMetadata>>();
@@ -53,11 +59,22 @@ export function getSpanMetadata(span: AbstractSpan): Partial<TransactionMetadata
5359
}
5460

5561
/** Set the Sentry scope to be used for finishing a given OTEL span. */
56-
export function setSpanFinishScope(span: AbstractSpan, scope: Scope): void {
57-
SpanFinishScope.set(span, scope);
62+
export function setSpanFinishScopes(
63+
span: AbstractSpan,
64+
scopes: {
65+
scope: Scope;
66+
isolationScope: Scope;
67+
},
68+
): void {
69+
SpanFinishScopes.set(span, scopes);
5870
}
5971

6072
/** Get the Sentry scope to use for finishing an OTEL span. */
61-
export function getSpanFinishScope(span: AbstractSpan): Scope | undefined {
62-
return SpanFinishScope.get(span);
73+
export function getSpanFinishScopes(span: AbstractSpan):
74+
| {
75+
scope: Scope;
76+
isolationScope: Scope;
77+
}
78+
| undefined {
79+
return SpanFinishScopes.get(span);
6380
}

0 commit comments

Comments
 (0)