11import * as api from '@opentelemetry/api' ;
2- import type { Scope , Span , withActiveSpan as defaultWithActiveSpan } from '@sentry/core' ;
3- import {
4- _INTERNAL_safeMathRandom ,
5- _INTERNAL_setSpanForScope ,
6- baggageHeaderToDynamicSamplingContext ,
7- getDefaultCurrentScope ,
8- getDefaultIsolationScope ,
9- setAsyncContextStrategy ,
10- } from '@sentry/core' ;
2+ import type { Scope , withActiveSpan as defaultWithActiveSpan } from '@sentry/core' ;
3+ import { getDefaultCurrentScope , getDefaultIsolationScope , setAsyncContextStrategy } from '@sentry/core' ;
114import {
125 SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY ,
136 SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY ,
147 SENTRY_FORK_SET_SCOPE_CONTEXT_KEY ,
15- SENTRY_TRACE_STATE_DSC ,
16- SENTRY_TRACE_STATE_SAMPLE_RAND ,
178} from './constants' ;
189import { continueTrace , startInactiveSpan , startNewTrace , startSpan , startSpanManual , withActiveSpan } from './trace' ;
1910import type { CurrentScopes } from './types' ;
2011import { getContextFromScope , getScopesFromContext } from './utils/contextData' ;
21- import { getSamplingDecision } from './utils/getSamplingDecision' ;
2212import { getActiveSpan } from './utils/getActiveSpan' ;
2313import { getTraceData } from './utils/getTraceData' ;
2414import { suppressTracing } from './utils/suppressTracing' ;
25- import { isSentryTraceProviderSpan } from './sentryTraceProvider' ;
2615
2716/**
2817 * Sets the async context strategy to use follow the OTEL context under the hood.
2918 * We handle forking a hub inside of our custom OTEL Context Manager (./otelContextManager.ts)
3019 */
31- export function setOpenTelemetryContextAsyncContextStrategy (
32- options : { useOpenTelemetrySpanCreation ?: boolean } = { } ,
33- ) : void {
34- const { useOpenTelemetrySpanCreation = true } = options ;
35-
20+ export function setOpenTelemetryContextAsyncContextStrategy ( ) : void {
3621 function getScopes ( ) : CurrentScopes {
3722 const ctx = api . context . active ( ) ;
3823 const scopes = getScopesFromContext ( ctx ) ;
@@ -52,11 +37,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(
5237 function withScope < T > ( callback : ( scope : Scope ) => T ) : T {
5338 const ctx = api . context . active ( ) ;
5439
55- // We depend on the otelContextManager to handle the context/hub
56- // We set the `SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY` context value, which is picked up by
57- // the OTEL context manager, which uses the presence of this key to determine if it should
58- // fork the isolation scope, or not
59- // as by default, we don't want to fork this, unless triggered explicitly by `withScope`
6040 return api . context . with ( ctx , ( ) => {
6141 return callback ( getCurrentScope ( ) ) ;
6242 } ) ;
@@ -65,9 +45,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(
6545 function withSetScope < T > ( scope : Scope , callback : ( scope : Scope ) => T ) : T {
6646 const ctx = getContextFromScope ( scope ) || api . context . active ( ) ;
6747
68- // We depend on the otelContextManager to handle the context/hub
69- // We set the `SENTRY_FORK_SET_SCOPE_CONTEXT_KEY` context value, which is picked up by
70- // the OTEL context manager, which picks up this scope as the current scope
7148 return api . context . with ( ctx . setValue ( SENTRY_FORK_SET_SCOPE_CONTEXT_KEY , scope ) , ( ) => {
7249 return callback ( scope ) ;
7350 } ) ;
@@ -76,10 +53,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(
7653 function withIsolationScope < T > ( callback : ( isolationScope : Scope ) => T ) : T {
7754 const ctx = api . context . active ( ) ;
7855
79- // We depend on the otelContextManager to handle the context/hub
80- // We set the `SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY` context value, which is picked up by
81- // the OTEL context manager, which uses the presence of this key to determine if it should
82- // fork the isolation scope, or not
8356 return api . context . with ( ctx . setValue ( SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY , true ) , ( ) => {
8457 return callback ( getIsolationScope ( ) ) ;
8558 } ) ;
@@ -88,102 +61,26 @@ export function setOpenTelemetryContextAsyncContextStrategy(
8861 function withSetIsolationScope < T > ( isolationScope : Scope , callback : ( isolationScope : Scope ) => T ) : T {
8962 const ctx = api . context . active ( ) ;
9063
91- // We depend on the otelContextManager to handle the context/hub
92- // We set the `SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY` context value, which is picked up by
93- // the OTEL context manager, which uses the presence of this key to determine if it should
94- // fork the isolation scope, or not
9564 return api . context . with ( ctx . setValue ( SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY , isolationScope ) , ( ) => {
9665 return callback ( getIsolationScope ( ) ) ;
9766 } ) ;
9867 }
9968
10069 function getCurrentScope ( ) : Scope {
101- const scope = getScopes ( ) . scope ;
102- if ( ! useOpenTelemetrySpanCreation ) {
103- syncOpenTelemetrySpanWithScope ( scope ) ;
104- }
105- return scope ;
70+ return getScopes ( ) . scope ;
10671 }
10772
10873 function getIsolationScope ( ) : Scope {
10974 return getScopes ( ) . isolationScope ;
11075 }
11176
112- function withActiveSpanContextOnly < T > ( span : Span | null , callback : ( scope : Scope ) => T ) : T {
113- const ctx = span
114- ? api . trace . setSpan ( api . context . active ( ) , span as api . Span )
115- : api . trace . deleteSpan ( api . context . active ( ) ) ;
116-
117- return api . context . with ( ctx , ( ) => {
118- const scope = getCurrentScope ( ) ;
119- _INTERNAL_setSpanForScope ( scope , span || undefined ) ;
120- return callback ( scope ) ;
121- } ) ;
122- }
123-
124- function syncOpenTelemetrySpanWithScope ( scope : Scope ) : void {
125- const activeSpan = api . trace . getSpan ( api . context . active ( ) ) as Span | undefined ;
126-
127- if ( ! activeSpan ) {
128- return ;
129- }
130-
131- const scopeSpan = scope . getScopeData ( ) . span ;
132- if ( scopeSpan === activeSpan ) {
133- return ;
134- }
135-
136- const activeSpanContext = activeSpan . spanContext ( ) ;
137- if ( activeSpanContext . isRemote ) {
138- if ( scopeSpan ) {
139- return ;
140- }
141-
142- // A remote OTel span context represents an incoming parent, not a local span
143- // we can finish and send. Store it as propagation context so the next core
144- // root span continues the trace and becomes the transaction segment.
145- const dsc =
146- baggageHeaderToDynamicSamplingContext ( activeSpanContext . traceState ?. get ( SENTRY_TRACE_STATE_DSC ) ) ?? { } ;
147- const sampleRandString = activeSpanContext . traceState ?. get ( SENTRY_TRACE_STATE_SAMPLE_RAND ) ?? dsc ?. sample_rand ;
148- const sampleRand = typeof sampleRandString === 'string' ? Number ( sampleRandString ) : undefined ;
149-
150- scope . setPropagationContext ( {
151- traceId : activeSpanContext . traceId ,
152- parentSpanId : activeSpanContext . spanId ,
153- sampled : getSamplingDecision ( activeSpanContext ) ,
154- dsc,
155- sampleRand :
156- typeof sampleRand === 'number' && ! Number . isNaN ( sampleRand ) ? sampleRand : _INTERNAL_safeMathRandom ( ) ,
157- } ) ;
158- return ;
159- }
160-
161- if ( scopeSpan && ! isSentryTraceProviderSpan ( scopeSpan ) ) {
162- return ;
163- }
164-
165- _INTERNAL_setSpanForScope ( scope , activeSpan ) ;
166- }
167-
168- const baseStrategy = {
77+ setAsyncContextStrategy ( {
16978 withScope,
17079 withSetScope,
17180 withSetIsolationScope,
17281 withIsolationScope,
17382 getCurrentScope,
17483 getIsolationScope,
175- } ;
176-
177- if ( ! useOpenTelemetrySpanCreation ) {
178- setAsyncContextStrategy ( {
179- ...baseStrategy ,
180- withActiveSpan : withActiveSpanContextOnly as typeof defaultWithActiveSpan ,
181- } ) ;
182- return ;
183- }
184-
185- setAsyncContextStrategy ( {
186- ...baseStrategy ,
18784 startSpan,
18885 startSpanManual,
18986 startInactiveSpan,
@@ -192,8 +89,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(
19289 getTraceData,
19390 continueTrace,
19491 startNewTrace,
195- // The types here don't fully align, because our own `Span` type is narrower
196- // than the OTEL one - but this is OK for here, as we now we'll only have OTEL spans passed around
19792 withActiveSpan : withActiveSpan as typeof defaultWithActiveSpan ,
19893 } ) ;
19994}
0 commit comments