Skip to content

Commit 38677d9

Browse files
committed
get rid of setSpanScope
1 parent 822ec12 commit 38677d9

File tree

8 files changed

+39
-33
lines changed

8 files changed

+39
-33
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getCurrentScope, setGlobalScope } from '@sentry/core';
2-
import { getClient, getSpanScope } from '@sentry/opentelemetry';
2+
import { getClient, getSpanScopes } from '@sentry/opentelemetry';
33

44
import * as Sentry from '../../src/';
55
import type { NodeExperimentalClient } from '../../src/types';
@@ -41,7 +41,11 @@ describe('Integration | Scope', () => {
4141
scope2.setTag('tag3', 'val3');
4242

4343
Sentry.startSpan({ name: 'outer' }, span => {
44-
expect(getSpanScope(span)).toBe(enableTracing ? scope2 : undefined);
44+
// TODO: This is "incorrect" until we stop cloning the current scope for setSpanScopes
45+
// Once we change this, the scopes _should_ be the same again
46+
if (enableTracing) {
47+
expect(getSpanScopes(span)?.scope).not.toBe(scope2);
48+
}
4549

4650
spanId = span.spanContext().spanId;
4751
traceId = span.spanContext().traceId;

packages/opentelemetry/src/asyncContextStrategy.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export function setOpenTelemetryContextAsyncContextStrategy(): void {
3131
const ctx = api.context.active();
3232

3333
// We depend on the otelContextManager to handle the context/hub
34+
// We set the `SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY` context value, which is picked up by
35+
// the OTEL context manager, which uses the presence of this key to determine if it should
36+
// fork the isolation scope, or not
37+
// as by default, we don't want to fork this, unless triggered explicitly by `runWithAsyncContext`
3438
return api.context.with(ctx.setValue(SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY, true), () => {
3539
return callback();
3640
});

packages/opentelemetry/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ export {
1010
getSpanHub,
1111
getSpanMetadata,
1212
getSpanParent,
13-
getSpanScope,
1413
setSpanMetadata,
15-
getSpanFinishScopes,
14+
getSpanScopes,
1615
} from './utils/spanData';
1716

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

packages/opentelemetry/src/propagator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { SENTRY_BAGGAGE_KEY_PREFIX, generateSentryTraceHeader, propagationContex
77

88
import { SENTRY_BAGGAGE_HEADER, SENTRY_TRACE_HEADER } from './constants';
99
import { getPropagationContextFromContext, setPropagationContextOnContext } from './utils/contextData';
10-
import { getSpanScope } from './utils/spanData';
10+
import { getSpanScopes } from './utils/spanData';
1111

1212
/**
1313
* Injects and extracts `sentry-trace` and `baggage` headers from carriers.
@@ -91,7 +91,7 @@ function getDsc(
9191
// Else, we try to generate a new one
9292
const client = getClient();
9393
const activeSpan = trace.getSpan(context);
94-
const scope = activeSpan ? getSpanScope(activeSpan) : undefined;
94+
const { scope } = (activeSpan && getSpanScopes(activeSpan)) || {};
9595

9696
if (client) {
9797
return getDynamicSamplingContextFromClient(traceId || propagationContext.traceId, client, scope);

packages/opentelemetry/src/spanExporter.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { SpanNode } from './utils/groupSpansWithParents';
2424
import { groupSpansWithParents } from './utils/groupSpansWithParents';
2525
import { mapStatus } from './utils/mapStatus';
2626
import { parseSpanDescription } from './utils/parseSpanDescription';
27-
import { getSpanFinishScopes, getSpanHub, getSpanMetadata, getSpanScope } from './utils/spanData';
27+
import { getSpanHub, getSpanMetadata, getSpanScopes } from './utils/spanData';
2828

2929
type SpanNodeCompleted = SpanNode & { span: ReadableSpan };
3030

@@ -130,7 +130,7 @@ function maybeSend(spans: ReadableSpan[]): ReadableSpan[] {
130130
function getScopesForTransactionFinish(span: ReadableSpan): { scope: Scope; isolationScope: Scope } {
131131
// The finish scope should normally always be there (and it is already a clone),
132132
// but for the sake of type safety we fall back to a clone of the current scope
133-
const scopes = getSpanFinishScopes(span);
133+
const scopes = getSpanScopes(span);
134134
const scope = scopes?.scope || getCurrentScope().clone();
135135
const isolationScope = scopes?.isolationScope || getIsolationScope();
136136

@@ -162,7 +162,7 @@ function parseSpan(span: ReadableSpan): { op?: string; origin?: SpanOrigin; sour
162162
}
163163

164164
function createTransactionForOtelSpan(span: ReadableSpan): Transaction {
165-
const scope = getSpanScope(span);
165+
const { scope } = getSpanScopes(span) || {};
166166
// eslint-disable-next-line deprecation/deprecation
167167
const hub = getSpanHub(span) || getCurrentHub();
168168
const spanContext = span.spanContext();

packages/opentelemetry/src/spanProcessor.ts

Lines changed: 5 additions & 3 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, setSpanFinishScopes, setSpanHub, setSpanParent, setSpanScope } from './utils/spanData';
13+
import { getSpanHub, setSpanHub, setSpanParent, setSpanScopes } 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
@@ -36,14 +36,16 @@ function onSpanStart(span: Span, parentContext: Context, _ScopeClass: typeof Ope
3636
const scope = actualHub.getScope();
3737
// eslint-disable-next-line deprecation/deprecation
3838
const isolationScope = actualHub.getIsolationScope();
39-
setSpanScope(span, scope);
4039
setSpanHub(span, actualHub);
4140

4241
// Use this scope for finishing the span
42+
// TODO: For now we need to clone this, as we need to store the `activeSpan` on it
43+
// Once we can get rid of this (when we move breadcrumbs to the isolation scope),
44+
// we can stop cloning this here
4345
const finishScope = (scope as OpenTelemetryScope).clone();
4446
// this is needed for breadcrumbs, for now, as they are stored on the span currently
4547
finishScope.activeSpan = span;
46-
setSpanFinishScopes(span, { scope: finishScope, isolationScope });
48+
setSpanScopes(span, { scope: finishScope, isolationScope });
4749
}
4850
}
4951

packages/opentelemetry/src/utils/spanData.ts

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type { Hub, Scope, TransactionMetadata } from '@sentry/types';
33

44
import type { AbstractSpan } from '../types';
55

6-
// We store the parent span, scope & metadata in separate weakmaps, so we can access them for a given span
6+
// We store the parent span, scopes & metadata in separate weakmaps, so we can access them for a given span
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
9-
const SpanScope = new WeakMap<AbstractSpan, Scope>();
10-
const SpanFinishScopes = new WeakMap<
9+
const SpanScopes = new WeakMap<
1110
AbstractSpan,
1211
{
1312
scope: Scope;
@@ -18,16 +17,6 @@ const SpanHub = new WeakMap<AbstractSpan, Hub>();
1817
const SpanParent = new WeakMap<AbstractSpan, Span>();
1918
const SpanMetadata = new WeakMap<AbstractSpan, Partial<TransactionMetadata>>();
2019

21-
/** Set the Sentry scope on an OTEL span. */
22-
export function setSpanScope(span: AbstractSpan, scope: Scope): void {
23-
SpanScope.set(span, scope);
24-
}
25-
26-
/** Get the Sentry scope of an OTEL span. */
27-
export function getSpanScope(span: AbstractSpan): Scope | undefined {
28-
return SpanScope.get(span);
29-
}
30-
3120
/** Set the Sentry hub on an OTEL span. */
3221
export function setSpanHub(span: AbstractSpan, hub: Hub): void {
3322
SpanHub.set(span, hub);
@@ -58,23 +47,27 @@ export function getSpanMetadata(span: AbstractSpan): Partial<TransactionMetadata
5847
return SpanMetadata.get(span);
5948
}
6049

61-
/** Set the Sentry scope to be used for finishing a given OTEL span. */
62-
export function setSpanFinishScopes(
50+
/**
51+
* Set the Sentry scope to be used for finishing a given OTEL span.
52+
* This is different from `setCapturedScopesOnSpan`, as that works on _sentry_ spans,
53+
* while here we are basically "caching" this on the otel spans.
54+
*/
55+
export function setSpanScopes(
6356
span: AbstractSpan,
6457
scopes: {
6558
scope: Scope;
6659
isolationScope: Scope;
6760
},
6861
): void {
69-
SpanFinishScopes.set(span, scopes);
62+
SpanScopes.set(span, scopes);
7063
}
7164

72-
/** Get the Sentry scope to use for finishing an OTEL span. */
73-
export function getSpanFinishScopes(span: AbstractSpan):
65+
/** Get the Sentry scopes to use for finishing an OTEL span. */
66+
export function getSpanScopes(span: AbstractSpan):
7467
| {
7568
scope: Scope;
7669
isolationScope: Scope;
7770
}
7871
| undefined {
79-
return SpanFinishScopes.get(span);
72+
return SpanScopes.get(span);
8073
}

packages/opentelemetry/test/integration/scope.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { OpenTelemetryHub } from '../../src/custom/hub';
1313
import { OpenTelemetryScope } from '../../src/custom/scope';
1414
import { startSpan } from '../../src/trace';
15-
import { getSpanScope } from '../../src/utils/spanData';
15+
import { getSpanScopes } from '../../src/utils/spanData';
1616
import type { TestClientInterface } from '../helpers/TestClient';
1717
import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit';
1818

@@ -57,7 +57,11 @@ describe('Integration | Scope', () => {
5757
scope2.setTag('tag3', 'val3');
5858

5959
startSpan({ name: 'outer' }, span => {
60-
expect(getSpanScope(span)).toBe(enableTracing ? scope2 : undefined);
60+
// TODO: This is "incorrect" until we stop cloning the current scope for setSpanScopes
61+
// Once we change this, the scopes _should_ be the same again
62+
if (enableTracing) {
63+
expect(getSpanScopes(span)?.scope).not.toBe(scope2);
64+
}
6165

6266
spanId = span.spanContext().spanId;
6367
traceId = span.spanContext().traceId;

0 commit comments

Comments
 (0)