Repository navigation
fix(http): isolate parent span per request, extend user agent span over transport, and record telemetry errors - #827
Conversation
…er transport, and record telemetry errors
|
Following up on our middleware work in kiota_http, this PR addresses OpenTelemetry span lifecycle and isolation:
All new unit tests and the full HTTP test suite (pytest packages/http/httpx/tests) pass cleanly locally (205 passed in 68.90s). Whenever convenient, please take a look. |
| parent_span = self.parent_span | ||
| if options and (req_parent_span := options.get("parent_span", None)): | ||
| parent_span = req_parent_span | ||
| if parent_span is None: |
There was a problem hiding this comment.
Addressed in commit 230b0fd.
We now preserve the explicit request parent span in request-local state (
equest.extensions[PARENT_SPAN_KEY]) during both initial span creation and transport cleanup (BaseMiddleware.send / MiddlewarePipeline.send). When REQUEST_OPTIONS_KEY is popped prior to transport dispatch, subsequent retry attempt spans and rerun downstream middleware handlers reliably retrieve the explicit parent without falling back to ambient context or mutating shared middleware instances.
Added:
- A 503 -> 200 regression test in est_retry_handler.py verifying that attempt spans and downstream handler spans on retries inherit the explicit request parent span ID.
- A unit test in est_base_middleware.py confirming PARENT_SPAN_KEY retention across transport cleanup.
…cleanup Preserve explicit parent_span in request.extensions[PARENT_SPAN_KEY] across transport cleanup so RetryHandler attempts and downstream middleware reruns retain trace context without mutating shared middleware instances. Add 503->200 regression test in test_retry_handler.py verifying attempt and downstream span parent IDs match the explicit parent, and unit test in test_base_middleware.py.
|
I have updated the PR to ensure trace parent continuity across request retries:
All code checks and tests (yapf, mypy, pylint 10/10, and all 207 kiota_http tests) pass cleanly. Whenever convenient, please take another look. |
|




Summary
Addresses OpenTelemetry span lifecycle and isolation in
kiota_http:UserAgentHandlerwithin the handler span lifecycle (try...finally: _span.end()) and records downstream pipeline errors via_span.record_exception(exc).parent_spanoptions from mutatingBaseMiddleware.parent_spanon the middleware instance, isolating trace contexts between requests.UrlReplaceHandlerandUserAgentHandler.Fix
middleware.py(BaseMiddleware._create_observability_span):parent_spanlocally instead of mutatingself.parent_span. Subsequent requests processed by the same middleware instance without aparent_spanoption no longer inherit earlier trace spans.user_agent_handler.py(UserAgentHandler.send):if request is None: raise TypeError("request cannot be null")._span.end()into afinallyblock enclosingawait super().send(request, transport)so the span accurately measures full execution and downstream spans remain properly nested._span.record_exception(exc)).url_replace_handler.py(UrlReplaceHandler.send):if request is None: raise TypeError("request cannot be null")._enable_span.record_exception(exc)).test_base_middleware.py: Addedtest_parent_span_option_does_not_mutate_middleware_instanceverifying request options do not leak parent spans across requests.test_user_agent_handler.py: Added tests verifying null request rejection, span enclosing transport, and exception recording on transport failure.test_url_replace_handler.py: Added tests verifying null request rejection and exception recording on transport failure.Testing
cc Vincent Biret (@baywet)