1515
1616from ..sampling import should_sample
1717from ..trace_blocking_manager import TraceBlockingManager , should_block_span
18- from ..types import TD_INSTRUMENTATION_LIBRARY_NAME , TuskDriftMode
18+ from ..types import TD_INSTRUMENTATION_LIBRARY_NAME , TuskDriftMode , SpanKind as TdSpanKind , replay_trace_id_context
1919from .otel_converter import otel_span_to_clean_span_data
2020
2121if TYPE_CHECKING :
@@ -152,9 +152,17 @@ def on_end(self, span: ReadableSpan) -> None:
152152 return
153153
154154 # Handle REPLAY mode inbound spans
155- if self ._mode == TuskDriftMode .REPLAY and clean_span .kind . value == 2 : # SERVER
155+ if self ._mode == TuskDriftMode .REPLAY and clean_span .kind == TdSpanKind . SERVER :
156156 from ..drift_sdk import TuskDrift
157157
158+ # Set the trace ID to the replay trace ID, CLI will use this to match the trace test with the result
159+ replay_trace_id = replay_trace_id_context .get ()
160+ if replay_trace_id :
161+ clean_span .trace_id = replay_trace_id
162+ else :
163+ logger .error ("No replay trace ID found, cannot send inbound span for replay" )
164+ return
165+
158166 sdk = TuskDrift .get_instance ()
159167 # Check for running loop BEFORE creating the coroutine to avoid
160168 # "coroutine was never awaited" warnings. If we call the async
@@ -167,6 +175,13 @@ def on_end(self, span: ReadableSpan) -> None:
167175
168176 if loop is not None :
169177 loop .create_task (sdk .send_inbound_span_for_replay (clean_span ))
178+ else :
179+ # No running loop - run synchronously
180+ try :
181+ asyncio .run (sdk .send_inbound_span_for_replay (clean_span ))
182+ except RuntimeError :
183+ logger .error ("No running loop, cannot send inbound span for replay" )
184+ pass
170185
171186 # Export span via batch processor (RECORD mode)
172187 if self ._mode == TuskDriftMode .RECORD :
0 commit comments