mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
httpx: fix handling of async hooks (#2823)
This commit is contained in:

committed by
GitHub

parent
19f8e775ce
commit
830397ecbf
12
CHANGELOG.md
12
CHANGELOG.md
@ -7,23 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
## Added
|
||||
### Added
|
||||
|
||||
- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng
|
||||
inside kafka-python's instrumentation
|
||||
([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537))
|
||||
|
||||
## Breaking changes
|
||||
### Breaking changes
|
||||
|
||||
- `opentelemetry-bootstrap` Remove `opentelemetry-instrumentation-aws-lambda` from the defaults instrumentations
|
||||
([#2786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2786))
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- `opentelemetry-instrumentation-httpx` fix handling of async hooks
|
||||
([#2823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2823))
|
||||
- `opentelemetry-instrumentation-system-metrics` fix `process.runtime.cpu.utilization` values to be shown in range of 0 to 1
|
||||
([2812](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2812))
|
||||
([#2812](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2812))
|
||||
- `opentelemetry-instrumentation-fastapi` fix `fastapi` auto-instrumentation by removing `fastapi-slim` support, `fastapi-slim` itself is discontinued from maintainers
|
||||
([2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783))
|
||||
([#2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783))
|
||||
- `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present.
|
||||
([#2750](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2750))
|
||||
- `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics
|
||||
|
@ -192,6 +192,7 @@ API
|
||||
"""
|
||||
import logging
|
||||
import typing
|
||||
from asyncio import iscoroutinefunction
|
||||
from types import TracebackType
|
||||
|
||||
import httpx
|
||||
@ -731,15 +732,19 @@ class HTTPXClientInstrumentor(BaseInstrumentor):
|
||||
self._original_async_client = httpx.AsyncClient
|
||||
request_hook = kwargs.get("request_hook")
|
||||
response_hook = kwargs.get("response_hook")
|
||||
async_request_hook = kwargs.get("async_request_hook", request_hook)
|
||||
async_response_hook = kwargs.get("async_response_hook", response_hook)
|
||||
async_request_hook = kwargs.get("async_request_hook")
|
||||
async_response_hook = kwargs.get("async_response_hook")
|
||||
if callable(request_hook):
|
||||
_InstrumentedClient._request_hook = request_hook
|
||||
if callable(async_request_hook):
|
||||
if callable(async_request_hook) and iscoroutinefunction(
|
||||
async_request_hook
|
||||
):
|
||||
_InstrumentedAsyncClient._request_hook = async_request_hook
|
||||
if callable(response_hook):
|
||||
_InstrumentedClient._response_hook = response_hook
|
||||
if callable(async_response_hook):
|
||||
if callable(async_response_hook) and iscoroutinefunction(
|
||||
async_response_hook
|
||||
):
|
||||
_InstrumentedAsyncClient._response_hook = async_response_hook
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
_InstrumentedClient._tracer_provider = tracer_provider
|
||||
|
@ -780,9 +780,15 @@ class BaseTestCases:
|
||||
HTTPXClientInstrumentor().uninstrument()
|
||||
|
||||
def test_response_hook(self):
|
||||
response_hook_key = (
|
||||
"async_response_hook"
|
||||
if asyncio.iscoroutinefunction(self.response_hook)
|
||||
else "response_hook"
|
||||
)
|
||||
response_hook_kwargs = {response_hook_key: self.response_hook}
|
||||
HTTPXClientInstrumentor().instrument(
|
||||
tracer_provider=self.tracer_provider,
|
||||
response_hook=self.response_hook,
|
||||
**response_hook_kwargs,
|
||||
)
|
||||
client = self.create_client()
|
||||
result = self.perform_request(self.URL, client=client)
|
||||
@ -823,9 +829,15 @@ class BaseTestCases:
|
||||
HTTPXClientInstrumentor().uninstrument()
|
||||
|
||||
def test_request_hook(self):
|
||||
request_hook_key = (
|
||||
"async_request_hook"
|
||||
if asyncio.iscoroutinefunction(self.request_hook)
|
||||
else "request_hook"
|
||||
)
|
||||
request_hook_kwargs = {request_hook_key: self.request_hook}
|
||||
HTTPXClientInstrumentor().instrument(
|
||||
tracer_provider=self.tracer_provider,
|
||||
request_hook=self.request_hook,
|
||||
**request_hook_kwargs,
|
||||
)
|
||||
client = self.create_client()
|
||||
result = self.perform_request(self.URL, client=client)
|
||||
@ -1214,3 +1226,36 @@ class TestAsyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest):
|
||||
self.perform_request(self.URL, client=self.client)
|
||||
self.perform_request(self.URL, client=self.client2)
|
||||
self.assert_span(num_spans=2)
|
||||
|
||||
def test_async_response_hook_does_nothing_if_not_coroutine(self):
|
||||
HTTPXClientInstrumentor().instrument(
|
||||
tracer_provider=self.tracer_provider,
|
||||
async_response_hook=_response_hook,
|
||||
)
|
||||
client = self.create_client()
|
||||
result = self.perform_request(self.URL, client=client)
|
||||
|
||||
self.assertEqual(result.text, "Hello!")
|
||||
span = self.assert_span()
|
||||
self.assertEqual(
|
||||
dict(span.attributes),
|
||||
{
|
||||
SpanAttributes.HTTP_METHOD: "GET",
|
||||
SpanAttributes.HTTP_URL: self.URL,
|
||||
SpanAttributes.HTTP_STATUS_CODE: 200,
|
||||
},
|
||||
)
|
||||
HTTPXClientInstrumentor().uninstrument()
|
||||
|
||||
def test_async_request_hook_does_nothing_if_not_coroutine(self):
|
||||
HTTPXClientInstrumentor().instrument(
|
||||
tracer_provider=self.tracer_provider,
|
||||
async_request_hook=_request_hook,
|
||||
)
|
||||
client = self.create_client()
|
||||
result = self.perform_request(self.URL, client=client)
|
||||
|
||||
self.assertEqual(result.text, "Hello!")
|
||||
span = self.assert_span()
|
||||
self.assertEqual(span.name, "GET")
|
||||
HTTPXClientInstrumentor().uninstrument()
|
||||
|
Reference in New Issue
Block a user