From 2b3713655c458ca9f9c42bebf7eb1738d4595b4f Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 22 Sep 2020 10:30:39 -0700 Subject: [PATCH] Use is_recording flag in asgi, pyramid, aiohttp instrumentation (#1142) --- .../aiohttp_client/__init__.py | 63 ++++++++++--------- .../tests/test_aiohttp_client_integration.py | 17 +++++ 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index 397d5dc80..5c48bbd58 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -133,16 +133,19 @@ def create_trace_config( request_span_name = str(trace_config_ctx.span_name) trace_config_ctx.span = trace_config_ctx.tracer.start_span( - request_span_name, - kind=SpanKind.CLIENT, - attributes={ + request_span_name, kind=SpanKind.CLIENT, + ) + + if trace_config_ctx.span.is_recording(): + attributes = { "component": "http", "http.method": http_method, "http.url": trace_config_ctx.url_filter(params.url) if callable(trace_config_ctx.url_filter) else str(params.url), - }, - ) + } + for key, value in attributes.items(): + trace_config_ctx.span.set_attribute(key, value) trace_config_ctx.token = context_api.attach( trace.set_span_in_context(trace_config_ctx.span) @@ -155,15 +158,18 @@ def create_trace_config( trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestEndParams, ): - trace_config_ctx.span.set_status( - Status(http_status_to_canonical_code(int(params.response.status))) - ) - trace_config_ctx.span.set_attribute( - "http.status_code", params.response.status - ) - trace_config_ctx.span.set_attribute( - "http.status_text", params.response.reason - ) + if trace_config_ctx.span.is_recording(): + trace_config_ctx.span.set_status( + Status( + http_status_to_canonical_code(int(params.response.status)) + ) + ) + trace_config_ctx.span.set_attribute( + "http.status_code", params.response.status + ) + trace_config_ctx.span.set_attribute( + "http.status_text", params.response.reason + ) _end_trace(trace_config_ctx) async def on_request_exception( @@ -171,21 +177,22 @@ def create_trace_config( trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestExceptionParams, ): - if isinstance( - params.exception, - (aiohttp.ServerTimeoutError, aiohttp.TooManyRedirects), - ): - status = StatusCanonicalCode.DEADLINE_EXCEEDED - # Assume any getaddrinfo error is a DNS failure. - elif isinstance( - params.exception, aiohttp.ClientConnectorError - ) and isinstance(params.exception.os_error, socket.gaierror): - # DNS resolution failed - status = StatusCanonicalCode.UNKNOWN - else: - status = StatusCanonicalCode.UNAVAILABLE + if trace_config_ctx.span.is_recording(): + if isinstance( + params.exception, + (aiohttp.ServerTimeoutError, aiohttp.TooManyRedirects), + ): + status = StatusCanonicalCode.DEADLINE_EXCEEDED + # Assume any getaddrinfo error is a DNS failure. + elif isinstance( + params.exception, aiohttp.ClientConnectorError + ) and isinstance(params.exception.os_error, socket.gaierror): + # DNS resolution failed + status = StatusCanonicalCode.UNKNOWN + else: + status = StatusCanonicalCode.UNAVAILABLE - trace_config_ctx.span.set_status(Status(status)) + trace_config_ctx.span.set_status(Status(status)) _end_trace(trace_config_ctx) def _trace_config_ctx_factory(**kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 4a48c38ff..90af17f9e 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -17,6 +17,7 @@ import contextlib import typing import urllib.parse from http import HTTPStatus +from unittest import mock import aiohttp import aiohttp.test_utils @@ -135,6 +136,22 @@ class TestAioHttpIntegration(TestBase): self.memory_exporter.clear() + def test_not_recording(self): + mock_tracer = mock.Mock() + mock_span = mock.Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_span.return_value = mock_span + with mock.patch("opentelemetry.trace.get_tracer"): + # pylint: disable=W0612 + host, port = self._http_request( + trace_config=opentelemetry.instrumentation.aiohttp_client.create_trace_config(), + url="/test-path?query=param#foobar", + ) + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + def test_span_name_option(self): for span_name, method, path, expected in ( ("static", "POST", "/static-span-name", "static"),