diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ccc90d0c1..df68c6593d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#558](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/558)) - Change `opentelemetry-instrumentation-httpx` to replace `client` classes with instrumented versions. ([#577](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/577)) +- `opentelemetry-instrumentation-requests` Fix potential `AttributeError` when `requests` + is used with a custom transport adapter. + ([#562](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/562)) ### Added - `opentelemetry-instrumentation-httpx` Add `httpx` instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index b844264d85..73c81e1de5 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -131,10 +131,6 @@ def _instrumented_requests_call( url = remove_url_credentials(url) - labels = {} - labels[SpanAttributes.HTTP_METHOD] = method - labels[SpanAttributes.HTTP_URL] = url - with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT ) as span: @@ -165,15 +161,6 @@ def _instrumented_requests_call( span.set_status( Status(http_status_to_status_code(result.status_code)) ) - labels[SpanAttributes.HTTP_STATUS_CODE] = str( - result.status_code - ) - if result.raw and result.raw.version: - labels[SpanAttributes.HTTP_FLAVOR] = ( - str(result.raw.version)[:1] - + "." - + str(result.raw.version)[:-1] - ) if span_callback is not None: span_callback(span, result) diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index e00bd3bd4f..db9a5e7625 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -17,6 +17,8 @@ import httpretty import requests +from requests.adapters import BaseAdapter +from requests.models import Response import opentelemetry.instrumentation.requests from opentelemetry import context, trace @@ -30,6 +32,23 @@ from opentelemetry.trace import StatusCode +class TransportMock: + def read(self, *args, **kwargs): + pass + + +class MyAdapter(BaseAdapter): + def __init__(self, response): + super().__init__() + self._response = response + + def send(self, *args, **kwargs): # pylint:disable=signature-differs + return self._response + + def close(self): + pass + + class InvalidResponseObjectException(Exception): def __init__(self): super().__init__() @@ -38,6 +57,7 @@ def __init__(self): class RequestsIntegrationTestBase(abc.ABC): # pylint: disable=no-member + # pylint: disable=too-many-public-methods URL = "http://httpbin.org/status/200" @@ -335,6 +355,26 @@ def test_requests_timeout_exception(self, *_, **__): span = self.assert_span() self.assertEqual(span.status.status_code, StatusCode.ERROR) + def test_adapter_with_custom_response(self): + response = Response() + response.status_code = 210 + response.reason = "hello adapter" + response.raw = TransportMock() + + session = requests.Session() + session.mount(self.URL, MyAdapter(response)) + + self.perform_request(self.URL, session) + span = self.assert_span() + self.assertEqual( + span.attributes, + { + "http.method": "GET", + "http.url": self.URL, + "http.status_code": 210, + }, + ) + class TestRequestsIntegration(RequestsIntegrationTestBase, TestBase): @staticmethod