mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-29 13:12:39 +08:00
regression-fix: retain httpx.URL type on request.url (#2359)
* fix: retain httpx.URL type on request.url This fixes a regression caused in #2020 where request.url stopped being of `httpx.URL` type, causing issues with request/response hooks. * Update CHANGELOG.md * tests: adding assertions to verify request.url on hooks is a httpx.URL * fixup: adjust check to consider httpx < 0.20.0 * fixup: keep code dry --------- Co-authored-by: Diego Hurtado <ocelotl@users.noreply.github.com> Co-authored-by: Leighton Chen <lechen@microsoft.com> Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
([#2297](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2297))
|
([#2297](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2297))
|
||||||
- Ensure all http.server.duration metrics have the same description
|
- Ensure all http.server.duration metrics have the same description
|
||||||
([#2151](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2298))
|
([#2151](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2298))
|
||||||
|
- Fix regression in httpx `request.url` not being of type `httpx.URL` after `0.44b0`
|
||||||
|
([#2359](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2359))
|
||||||
- Avoid losing repeated HTTP headers
|
- Avoid losing repeated HTTP headers
|
||||||
([#2266](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2266))
|
([#2266](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2266))
|
||||||
- `opentelemetry-instrumentation-elasticsearch` Don't send bulk request body as db statement
|
- `opentelemetry-instrumentation-elasticsearch` Don't send bulk request body as db statement
|
||||||
|
@ -270,7 +270,7 @@ def _extract_parameters(args, kwargs):
|
|||||||
# In httpx >= 0.20.0, handle_request receives a Request object
|
# In httpx >= 0.20.0, handle_request receives a Request object
|
||||||
request: httpx.Request = args[0]
|
request: httpx.Request = args[0]
|
||||||
method = request.method.encode()
|
method = request.method.encode()
|
||||||
url = remove_url_credentials(str(request.url))
|
url = httpx.URL(remove_url_credentials(str(request.url)))
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
stream = request.stream
|
stream = request.stream
|
||||||
extensions = request.extensions
|
extensions = request.extensions
|
||||||
|
@ -51,12 +51,18 @@ if typing.TYPE_CHECKING:
|
|||||||
HTTP_RESPONSE_BODY = "http.response.body"
|
HTTP_RESPONSE_BODY = "http.response.body"
|
||||||
|
|
||||||
|
|
||||||
|
def _is_url_tuple(request: "RequestInfo"):
|
||||||
|
"""Determine if request url format is for httpx versions < 0.20.0."""
|
||||||
|
return isinstance(request[1], tuple) and len(request[1]) == 4
|
||||||
|
|
||||||
|
|
||||||
def _async_call(coro: typing.Coroutine) -> asyncio.Task:
|
def _async_call(coro: typing.Coroutine) -> asyncio.Task:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
return loop.run_until_complete(coro)
|
return loop.run_until_complete(coro)
|
||||||
|
|
||||||
|
|
||||||
def _response_hook(span, request: "RequestInfo", response: "ResponseInfo"):
|
def _response_hook(span, request: "RequestInfo", response: "ResponseInfo"):
|
||||||
|
assert _is_url_tuple(request) or isinstance(request.url, httpx.URL)
|
||||||
span.set_attribute(
|
span.set_attribute(
|
||||||
HTTP_RESPONSE_BODY,
|
HTTP_RESPONSE_BODY,
|
||||||
b"".join(response[2]),
|
b"".join(response[2]),
|
||||||
@ -66,6 +72,7 @@ def _response_hook(span, request: "RequestInfo", response: "ResponseInfo"):
|
|||||||
async def _async_response_hook(
|
async def _async_response_hook(
|
||||||
span: "Span", request: "RequestInfo", response: "ResponseInfo"
|
span: "Span", request: "RequestInfo", response: "ResponseInfo"
|
||||||
):
|
):
|
||||||
|
assert _is_url_tuple(request) or isinstance(request.url, httpx.URL)
|
||||||
span.set_attribute(
|
span.set_attribute(
|
||||||
HTTP_RESPONSE_BODY,
|
HTTP_RESPONSE_BODY,
|
||||||
b"".join([part async for part in response[2]]),
|
b"".join([part async for part in response[2]]),
|
||||||
@ -73,11 +80,13 @@ async def _async_response_hook(
|
|||||||
|
|
||||||
|
|
||||||
def _request_hook(span: "Span", request: "RequestInfo"):
|
def _request_hook(span: "Span", request: "RequestInfo"):
|
||||||
|
assert _is_url_tuple(request) or isinstance(request.url, httpx.URL)
|
||||||
url = httpx.URL(request[1])
|
url = httpx.URL(request[1])
|
||||||
span.update_name("GET" + str(url))
|
span.update_name("GET" + str(url))
|
||||||
|
|
||||||
|
|
||||||
async def _async_request_hook(span: "Span", request: "RequestInfo"):
|
async def _async_request_hook(span: "Span", request: "RequestInfo"):
|
||||||
|
assert _is_url_tuple(request) or isinstance(request.url, httpx.URL)
|
||||||
url = httpx.URL(request[1])
|
url = httpx.URL(request[1])
|
||||||
span.update_name("GET" + str(url))
|
span.update_name("GET" + str(url))
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user