Skip to content

Commit a249200

Browse files
authored
feat(opentelemetry): Remove hub from context (#10983)
We no longer need it, so we don't need to keep this manually around anymore 🎉 This is WIP on top of #10982
1 parent 18bc035 commit a249200

File tree

9 files changed

+40
-103
lines changed

9 files changed

+40
-103
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ function getCjsOnlyIntegrations(isCjs = typeof require !== 'undefined'): Integra
4545

4646
/** Get the default integrations for the Node Experimental SDK. */
4747
export function getDefaultIntegrations(options: Options): Integration[] {
48-
// TODO
4948
return [
5049
// Common
5150
inboundFiltersIntegration(),

packages/opentelemetry/src/constants.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ export const SENTRY_BAGGAGE_HEADER = 'baggage';
55
export const SENTRY_TRACE_STATE_DSC = 'sentry.trace';
66
export const SENTRY_TRACE_STATE_PARENT_SPAN_ID = 'sentry.parent_span_id';
77

8-
/** Context Key to hold a Hub. */
9-
export const SENTRY_HUB_CONTEXT_KEY = createContextKey('sentry_hub');
10-
118
export const SENTRY_SCOPES_CONTEXT_KEY = createContextKey('sentry_scopes');
129

1310
export const SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY = createContextKey('sentry_fork_isolation_scope');

packages/opentelemetry/src/contextManager.ts

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY,
88
SENTRY_FORK_SET_SCOPE_CONTEXT_KEY,
99
} from './constants';
10-
import { getCurrentHub } from './custom/getCurrentHub';
11-
import { getScopesFromContext, setContextOnScope, setHubOnContext, setScopesOnContext } from './utils/contextData';
10+
import { getScopesFromContext, setContextOnScope, setScopesOnContext } from './utils/contextData';
1211
import { setIsSetup } from './utils/setupCheck';
1312

1413
/**
@@ -59,25 +58,17 @@ export function wrapContextManagerClass<ContextManagerInstance extends ContextMa
5958
isolationScope || (shouldForkIsolationScope ? currentIsolationScope.clone() : currentIsolationScope);
6059
const scopes = { scope: newCurrentScope, isolationScope: newIsolationScope };
6160

62-
const mockHub = {
63-
// eslint-disable-next-line deprecation/deprecation
64-
...getCurrentHub(),
65-
getScope: () => newCurrentScope,
66-
getIsolationScope: () => newIsolationScope,
67-
};
68-
69-
const ctx1 = setHubOnContext(context, mockHub);
70-
const ctx2 = setScopesOnContext(ctx1, scopes);
61+
const ctx1 = setScopesOnContext(context, scopes);
7162

7263
// Remove the unneeded values again
73-
const ctx3 = ctx2
64+
const ctx2 = ctx1
7465
.deleteValue(SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY)
7566
.deleteValue(SENTRY_FORK_SET_SCOPE_CONTEXT_KEY)
7667
.deleteValue(SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY);
7768

78-
setContextOnScope(newCurrentScope, ctx3);
69+
setContextOnScope(newCurrentScope, ctx2);
7970

80-
return super.with(ctx3, fn, thisArg, ...args);
71+
return super.with(ctx2, fn, thisArg, ...args);
8172
}
8273
}
8374

packages/opentelemetry/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export { wrapClientClass } from './custom/client';
77

88
export { getSpanKind } from './utils/getSpanKind';
99
export {
10-
getSpanHub,
1110
getSpanMetadata,
1211
getSpanParent,
1312
setSpanMetadata,

packages/opentelemetry/src/spanProcessor.ts

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,39 @@ import type { Context } from '@opentelemetry/api';
22
import { ROOT_CONTEXT, trace } from '@opentelemetry/api';
33
import type { Span, SpanProcessor as SpanProcessorInterface } from '@opentelemetry/sdk-trace-base';
44
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
5-
import { getClient, getCurrentHub } from '@sentry/core';
5+
import { getClient, getDefaultCurrentScope, getDefaultIsolationScope } from '@sentry/core';
66
import { logger } from '@sentry/utils';
77

88
import { DEBUG_BUILD } from './debug-build';
99
import { SentrySpanExporter } from './spanExporter';
1010
import { maybeCaptureExceptionForTimedEvent } from './utils/captureExceptionForTimedEvent';
11-
import { getHubFromContext } from './utils/contextData';
11+
import { getScopesFromContext } from './utils/contextData';
1212
import { setIsSetup } from './utils/setupCheck';
13-
import { getSpanHub, setSpanHub, setSpanParent, setSpanScopes } from './utils/spanData';
13+
import { setSpanParent, setSpanScopes } from './utils/spanData';
1414

1515
function onSpanStart(span: Span, parentContext: Context): 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
1717
const parentSpan = trace.getSpan(parentContext);
18-
const hub = getHubFromContext(parentContext);
18+
19+
let scopes = getScopesFromContext(parentContext);
1920

2021
// We need access to the parent span in order to be able to move up the span tree for breadcrumbs
2122
if (parentSpan) {
2223
setSpanParent(span, parentSpan);
2324
}
2425

25-
// The root context does not have a hub stored, so we check for this specifically
26-
// We do this instead of just falling back to `getCurrentHub` to avoid attaching the wrong hub
27-
let actualHub = hub;
26+
// The root context does not have scopes stored, so we check for this specifically
27+
// As fallback we attach the global scopes
2828
if (parentContext === ROOT_CONTEXT) {
29-
// eslint-disable-next-line deprecation/deprecation
30-
actualHub = getCurrentHub();
29+
scopes = {
30+
scope: getDefaultCurrentScope(),
31+
isolationScope: getDefaultIsolationScope(),
32+
};
3133
}
3234

3335
// We need the scope at time of span creation in order to apply it to the event when the span is finished
34-
if (actualHub) {
35-
// eslint-disable-next-line deprecation/deprecation
36-
const scope = actualHub.getScope();
37-
// eslint-disable-next-line deprecation/deprecation
38-
const isolationScope = actualHub.getIsolationScope();
39-
setSpanHub(span, actualHub);
40-
setSpanScopes(span, { scope, isolationScope });
36+
if (scopes) {
37+
setSpanScopes(span, scopes);
4138
}
4239

4340
const client = getClient();
@@ -46,10 +43,8 @@ function onSpanStart(span: Span, parentContext: Context): void {
4643

4744
function onSpanEnd(span: Span): void {
4845
// Capture exceptions as events
49-
// eslint-disable-next-line deprecation/deprecation
50-
const hub = getSpanHub(span) || getCurrentHub();
5146
span.events.forEach(event => {
52-
maybeCaptureExceptionForTimedEvent(hub, event, span);
47+
maybeCaptureExceptionForTimedEvent(event, span);
5348
});
5449

5550
const client = getClient();

packages/opentelemetry/src/utils/captureExceptionForTimedEvent.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { Span as OtelSpan, TimedEvent } from '@opentelemetry/sdk-trace-base';
22
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
3-
import type { Hub } from '@sentry/types';
3+
import { captureException } from '@sentry/core';
44
import { isString } from '@sentry/utils';
55

66
/**
77
* Maybe capture a Sentry exception for an OTEL timed event.
88
* This will check if the event is exception-like and in that case capture it as an exception.
99
*/
10-
export function maybeCaptureExceptionForTimedEvent(hub: Hub, event: TimedEvent, otelSpan?: OtelSpan): void {
10+
export function maybeCaptureExceptionForTimedEvent(event: TimedEvent, otelSpan?: OtelSpan): void {
1111
if (event.name !== 'exception') {
1212
return;
1313
}
@@ -35,8 +35,7 @@ export function maybeCaptureExceptionForTimedEvent(hub: Hub, event: TimedEvent,
3535
syntheticError.name = type;
3636
}
3737

38-
// eslint-disable-next-line deprecation/deprecation
39-
hub.captureException(syntheticError, {
38+
captureException(syntheticError, {
4039
captureContext: otelSpan
4140
? {
4241
contexts: {

packages/opentelemetry/src/utils/contextData.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
import type { Context } from '@opentelemetry/api';
2-
import type { Hub, Scope } from '@sentry/types';
2+
import type { Scope } from '@sentry/types';
33

4-
import { SENTRY_HUB_CONTEXT_KEY, SENTRY_SCOPES_CONTEXT_KEY } from '../constants';
4+
import { SENTRY_SCOPES_CONTEXT_KEY } from '../constants';
55
import type { CurrentScopes } from '../types';
66

77
const SCOPE_CONTEXT_MAP = new WeakMap<Scope, Context>();
88

9-
/**
10-
* Try to get the Hub from the given OTEL context.
11-
* This requires a Context Manager that was wrapped with getWrappedContextManager.
12-
*/
13-
export function getHubFromContext(context: Context): Hub | undefined {
14-
return context.getValue(SENTRY_HUB_CONTEXT_KEY) as Hub | undefined;
15-
}
16-
17-
/**
18-
* Set a Hub on an OTEL context..
19-
* This will return a forked context with the Propagation Context set.
20-
*/
21-
export function setHubOnContext(context: Context, hub: Hub): Context {
22-
return context.setValue(SENTRY_HUB_CONTEXT_KEY, hub);
23-
}
24-
259
/**
2610
* Try to get the current scopes from the given OTEL context.
2711
* This requires a Context Manager that was wrapped with getWrappedContextManager.

packages/opentelemetry/src/utils/spanData.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Span } from '@opentelemetry/api';
2-
import type { Hub, Scope, TransactionMetadata } from '@sentry/types';
2+
import type { Scope, TransactionMetadata } from '@sentry/types';
33

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

@@ -13,20 +13,9 @@ const SpanScopes = new WeakMap<
1313
isolationScope: Scope;
1414
}
1515
>();
16-
const SpanHub = new WeakMap<AbstractSpan, Hub>();
1716
const SpanParent = new WeakMap<AbstractSpan, Span>();
1817
const SpanMetadata = new WeakMap<AbstractSpan, Partial<TransactionMetadata>>();
1918

20-
/** Set the Sentry hub on an OTEL span. */
21-
export function setSpanHub(span: AbstractSpan, hub: Hub): void {
22-
SpanHub.set(span, hub);
23-
}
24-
25-
/** Get the Sentry hub of an OTEL span. */
26-
export function getSpanHub(span: AbstractSpan): Hub | undefined {
27-
return SpanHub.get(span);
28-
}
29-
3019
/** Set the parent OTEL span on an OTEL span. */
3120
export function setSpanParent(span: AbstractSpan, parentSpan: Span): void {
3221
SpanParent.set(span, parentSpan);

packages/opentelemetry/test/utils/captureExceptionForTimedEvent.test.ts

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import type { Span as OtelSpan, TimedEvent } from '@opentelemetry/sdk-trace-base';
22
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
3-
import type { Hub } from '@sentry/types';
3+
import * as SentryCore from '@sentry/core';
44

55
import { maybeCaptureExceptionForTimedEvent } from '../../src/utils/captureExceptionForTimedEvent';
66

77
describe('maybeCaptureExceptionForTimedEvent', () => {
8+
afterEach(() => {
9+
jest.clearAllMocks();
10+
});
11+
812
it('ignores non-exception events', async () => {
913
const event: TimedEvent = {
1014
time: [12345, 0],
1115
name: 'test event',
1216
};
1317

14-
const captureException = jest.fn();
15-
const hub = {
16-
captureException,
17-
} as unknown as Hub;
18-
19-
maybeCaptureExceptionForTimedEvent(hub, event);
18+
const captureException = jest.spyOn(SentryCore, 'captureException');
19+
maybeCaptureExceptionForTimedEvent(event);
2020

2121
expect(captureException).not.toHaveBeenCalled();
2222
});
@@ -27,12 +27,8 @@ describe('maybeCaptureExceptionForTimedEvent', () => {
2727
name: 'exception',
2828
};
2929

30-
const captureException = jest.fn();
31-
const hub = {
32-
captureException,
33-
} as unknown as Hub;
34-
35-
maybeCaptureExceptionForTimedEvent(hub, event);
30+
const captureException = jest.spyOn(SentryCore, 'captureException');
31+
maybeCaptureExceptionForTimedEvent(event);
3632

3733
expect(captureException).not.toHaveBeenCalled();
3834
});
@@ -46,12 +42,8 @@ describe('maybeCaptureExceptionForTimedEvent', () => {
4642
},
4743
};
4844

49-
const captureException = jest.fn();
50-
const hub = {
51-
captureException,
52-
} as unknown as Hub;
53-
54-
maybeCaptureExceptionForTimedEvent(hub, event);
45+
const captureException = jest.spyOn(SentryCore, 'captureException');
46+
maybeCaptureExceptionForTimedEvent(event);
5547

5648
expect(captureException).toHaveBeenCalledTimes(1);
5749
expect(captureException).toHaveBeenCalledWith(expect.objectContaining({ message: 'test-message' }), {
@@ -73,12 +65,8 @@ describe('maybeCaptureExceptionForTimedEvent', () => {
7365
},
7466
};
7567

76-
const captureException = jest.fn();
77-
const hub = {
78-
captureException,
79-
} as unknown as Hub;
80-
81-
maybeCaptureExceptionForTimedEvent(hub, event);
68+
const captureException = jest.spyOn(SentryCore, 'captureException');
69+
maybeCaptureExceptionForTimedEvent(event);
8270

8371
expect(captureException).toHaveBeenCalledTimes(1);
8472
expect(captureException).toHaveBeenCalledWith(
@@ -116,12 +104,8 @@ describe('maybeCaptureExceptionForTimedEvent', () => {
116104
},
117105
} as unknown as OtelSpan;
118106

119-
const captureException = jest.fn();
120-
const hub = {
121-
captureException,
122-
} as unknown as Hub;
123-
124-
maybeCaptureExceptionForTimedEvent(hub, event, span);
107+
const captureException = jest.spyOn(SentryCore, 'captureException');
108+
maybeCaptureExceptionForTimedEvent(event, span);
125109

126110
expect(captureException).toHaveBeenCalledTimes(1);
127111
expect(captureException).toHaveBeenCalledWith(expect.objectContaining({ message: 'test-message' }), {

0 commit comments

Comments
 (0)