diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_tracing.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_tracing.py index f9ab0ff60750..b580ac2504a6 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_tracing.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_tracing.py @@ -294,14 +294,24 @@ async def __call__(self, scope: Any, receive: Any, send: Any) -> None: "x_request_id", x_request_id, context=ctx, ) + # Create a NonRecordingSpan with the extracted trace context so that + # get_current_span() returns a span carrying the correct trace_id. + # Without this, the OTel LogRecord processor sees no active span and + # sets trace_id=0, causing zeroed operation_Id in Application Insights + # for logs emitted by Hypercorn's access logger. + span = trace.get_current_span(ctx) + span_ctx = span.get_span_context() + if span_ctx and span_ctx.is_valid: + non_recording = trace.NonRecordingSpan(span_ctx) + ctx = trace.set_span_in_context(non_recording, ctx) + + # Attach request context for app execution and detach in the same + # Task/context to avoid leaking contextvars across requests. token = _otel_context.attach(ctx) try: await self.app(scope, receive, send) finally: - try: - _otel_context.detach(token) - except ValueError: - pass + detach_context(token) def end_span(span: Any, exc: Optional[BaseException] = None) -> None: