1- import type { Client , DynamicSamplingContext , Scope } from '@sentry/types' ;
1+ import type { Client , DynamicSamplingContext , Scope , Span } from '@sentry/types' ;
22import { dropUndefinedKeys } from '@sentry/utils' ;
33
44import { DEFAULT_ENVIRONMENT } from '../constants' ;
5+ import { getClient , getCurrentScope } from '../exports' ;
56
67/**
78 * Creates a dynamic sampling context from a client.
89 *
9- * Dispatchs the `createDsc` lifecycle hook as a side effect.
10+ * Dispatches the `createDsc` lifecycle hook as a side effect.
1011 */
1112export function getDynamicSamplingContextFromClient (
1213 trace_id : string ,
1314 client : Client ,
1415 scope ?: Scope ,
16+ emitHook : boolean = true ,
1517) : DynamicSamplingContext {
1618 const options = client . getOptions ( ) ;
1719
@@ -26,6 +28,64 @@ export function getDynamicSamplingContextFromClient(
2628 trace_id,
2729 } ) as DynamicSamplingContext ;
2830
31+ if ( emitHook ) {
32+ client . emit && client . emit ( 'createDsc' , dsc ) ;
33+ }
34+
35+ return dsc ;
36+ }
37+
38+ /**
39+ * A Span with a frozen dynamic sampling context.
40+ */
41+ type TransactionWithV7FrozenDsc = Span & { _frozenDynamicSamplingContext ?: DynamicSamplingContext } ;
42+
43+ /**
44+ * Creates a dynamic sampling context from a span (and client and scope)
45+ *
46+ * @param span the span from which a few values like the root span name and sample rate are extracted.
47+ *
48+ * @returns a dynamic sampling context
49+ */
50+ export function getDynamicSamplingContextFromSpan ( span : Span ) : Readonly < Partial < DynamicSamplingContext > > {
51+ // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
52+ // For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set.
53+ // @see Transaction class constructor
54+ const v7FrozenDsc = ( span as TransactionWithV7FrozenDsc ) . _frozenDynamicSamplingContext ;
55+ if ( v7FrozenDsc ) {
56+ return v7FrozenDsc ;
57+ }
58+
59+ const client = getClient ( ) ;
60+ if ( ! client ) {
61+ return { } ;
62+ }
63+
64+ // passing emit=false here to only emit later once the DSC is actually populated
65+ const dsc = getDynamicSamplingContextFromClient ( span . traceId , client , getCurrentScope ( ) , false ) ;
66+ const txn = span . transaction ;
67+ if ( ! txn ) {
68+ return dsc ;
69+ }
70+
71+ const maybeSampleRate = txn . metadata . sampleRate ;
72+ if ( maybeSampleRate !== undefined ) {
73+ dsc . sample_rate = `${ maybeSampleRate } ` ;
74+ }
75+
76+ // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
77+ const source = txn . metadata . source ;
78+ if ( source && source !== 'url' ) {
79+ dsc . transaction = txn . name ;
80+ }
81+
82+ // TODO: Switch to `spanIsSampled` once we have it
83+ // eslint-disable-next-line deprecation/deprecation
84+ if ( txn . sampled !== undefined ) {
85+ // eslint-disable-next-line deprecation/deprecation
86+ dsc . sampled = String ( txn . sampled ) ;
87+ }
88+
2989 client . emit && client . emit ( 'createDsc' , dsc ) ;
3090
3191 return dsc ;
0 commit comments