@@ -184,14 +184,21 @@ public function startSpan(): SpanInterface
184184 $ parentSpan = Span::fromContext ($ parentContext );
185185 $ parentSpanContext = $ parentSpan ->getContext ();
186186
187- $ span = $ parentSpanContext ->isValid () ? null : \DDTrace \start_trace_span ($ this ->startEpochNanos );
188- $ traceId = $ parentSpanContext ->isValid () ? $ parentSpanContext ->getTraceId () : \DDTrace \root_span ()->traceId ;
187+ $ behaviorExtract = \dd_trace_env_config ('DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT ' );
188+ $ restartOrIgnore = $ parentSpanContext ->isValid () && ($ behaviorExtract === 1 || $ behaviorExtract === 2 );
189+
190+ $ span = ($ parentSpanContext ->isValid () && !$ restartOrIgnore ) ? null : \DDTrace \start_trace_span ($ this ->startEpochNanos );
191+ $ traceId = ($ parentSpanContext ->isValid () && !$ restartOrIgnore )
192+ ? $ parentSpanContext ->getTraceId ()
193+ : \DDTrace \root_span ()->traceId ;
194+
195+ $ samplingContext = $ restartOrIgnore ? Context::getRoot () : $ parentContext ;
189196
190197 $ samplingResult = $ this
191198 ->tracerSharedState
192199 ->getSampler ()
193200 ->shouldSample (
194- $ parentContext ,
201+ $ samplingContext ,
195202 $ traceId ,
196203 $ this ->spanName ,
197204 $ this ->spanKind ,
@@ -205,7 +212,7 @@ public function startSpan(): SpanInterface
205212 $ sampled = SamplingResult::RECORD_AND_SAMPLE === $ samplingDecision ;
206213 $ samplingResultTraceState = $ samplingResult ->getTraceState ();
207214
208- if ($ parentSpanContext ->isValid ()) {
215+ if ($ parentSpanContext ->isValid () && ! $ restartOrIgnore ) {
209216 // Traceparent: {2:version}-{32:hex trace id}-{16:hex parent id}-{2:trace_flags}, version always being '00'
210217 // Since parentSpanContext is valid, the trace identifiers are guaranteed to be in hexadecimal format
211218 $ parentId = $ parentSpanContext ->getSpanId ();
@@ -215,6 +222,15 @@ public function startSpan(): SpanInterface
215222 'traceparent ' => $ traceParent ,
216223 'tracestate ' => (string ) $ samplingResultTraceState , // __toString() is implemented in TraceState
217224 ]);
225+ } elseif ($ parentSpanContext ->isValid () && $ behaviorExtract === 1 ) {
226+ // RESTART: pass upstream W3C context so C code creates a span link and starts fresh trace
227+ $ parentId = $ parentSpanContext ->getSpanId ();
228+ $ traceFlags = $ parentSpanContext ->isSampled () ? '01 ' : '00 ' ;
229+ $ traceParent = "00- {$ parentSpanContext ->getTraceId ()}- $ parentId- $ traceFlags " ;
230+ \DDTrace \consume_distributed_tracing_headers ([
231+ 'traceparent ' => $ traceParent ,
232+ 'tracestate ' => (string ) $ parentSpanContext ->getTraceState (),
233+ ]);
218234 } elseif ($ samplingResultTraceState ) {
219235 $ samplingResultTraceState = $ samplingResultTraceState ->without ('dd ' );
220236 \DDTrace \root_span ()->tracestate = (string ) $ samplingResultTraceState ;
@@ -234,10 +250,13 @@ public function startSpan(): SpanInterface
234250 $ this ->attributes [$ key ] = $ value ;
235251 }
236252
237- $ parentSpanContextBaggage = $ parentContext ->get (ContextKeys::baggage ());
238- if ($ parentSpanContextBaggage ) {
239- foreach ($ parentSpanContextBaggage ->getAll () as $ baggageKey => $ baggageEntry ) {
240- $ span ->baggage [$ baggageKey ] = $ baggageEntry ->getValue ();
253+ if ($ behaviorExtract !== 2 ) {
254+ // `restart` or `continue` : propagate baggage
255+ $ parentSpanContextBaggage = $ parentContext ->get (ContextKeys::baggage ());
256+ if ($ parentSpanContextBaggage ) {
257+ foreach ($ parentSpanContextBaggage ->getAll () as $ baggageKey => $ baggageEntry ) {
258+ $ span ->baggage [$ baggageKey ] = $ baggageEntry ->getValue ();
259+ }
241260 }
242261 }
243262
@@ -249,7 +268,7 @@ public function startSpan(): SpanInterface
249268 $ parentSpan ,
250269 $ parentContext ,
251270 $ this ->tracerSharedState ->getSpanProcessor (),
252- $ parentSpanContext ->isValid () ? ResourceInfoFactory::emptyResource () : $ this ->tracerSharedState ->getResource (),
271+ ( $ parentSpanContext ->isValid () && ! $ restartOrIgnore ) ? ResourceInfoFactory::emptyResource () : $ this ->tracerSharedState ->getResource (),
253272 $ this ->attributes ,
254273 $ this ->links ,
255274 $ this ->totalNumberOfLinksAdded ,
0 commit comments