From 51d787541966e362d18a3e258ac3b3d98945863b Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Tue, 29 Mar 2022 11:43:30 +0530 Subject: [PATCH 01/11] Capture request/response headers for Pyramid --- .../instrumentation/pyramid/callbacks.py | 6 + .../tests/pyramid_base_test.py | 17 ++ .../tests/test_automatic.py | 149 ++++++++++++++++++ 3 files changed, 172 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index cc424eb0d9..071c387b6c 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -104,6 +104,8 @@ def _before_traversal(event): ] = request.matched_route.pattern for key, value in attributes.items(): span.set_attribute(key, value) + if span.kind == trace.SpanKind.SERVER: + otel_wsgi.add_custom_request_headers(span, request_environ) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 @@ -163,6 +165,10 @@ def trace_tween(request): response_or_exception.status, response_or_exception.headerlist, ) + if span.is_recording() and span.kind == trace.SpanKind.SERVER: + otel_wsgi.add_custom_response_headers( + span, response_or_exception.headerlist + ) propagator = get_global_response_propagator() if propagator: diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py index 70ab268c23..8c47388f52 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py @@ -26,6 +26,16 @@ def _hello_endpoint(request): raise exc.HTTPInternalServerError() return Response("Hello: " + str(helloid)) + @staticmethod + def _custom_response_header_endpoint(request): + headers = { + "content-type": "text/plain; charset=utf-8", + "content-length": "7", + "my-custom-header": "my-custom-value-1,my-custom-header-2", + "dont-capture-me": "test-value", + } + return Response("Testing", headers=headers) + def _common_initialization(self, config): # pylint: disable=unused-argument def excluded_endpoint(request): @@ -43,6 +53,13 @@ def excluded2_endpoint(request): config.add_view(excluded_endpoint, route_name="excluded") config.add_route("excluded2", "/excluded_noarg2") config.add_view(excluded2_endpoint, route_name="excluded2") + config.add_route( + "custom_response_headers", "/test_custom_response_headers" + ) + config.add_view( + self._custom_response_header_endpoint, + route_name="custom_response_headers", + ) # pylint: disable=attribute-defined-outside-init self.client = Client(config.make_wsgi_app(), BaseResponse) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py index 37b2be4c76..a571d17f3b 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py @@ -12,12 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import patch + from pyramid.config import Configurator +from opentelemetry import trace from opentelemetry.instrumentation.pyramid import PyramidInstrumentor +from opentelemetry.test.globals_test import reset_trace_globals from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace import SpanKind +from opentelemetry.util.http import ( + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, +) # pylint: disable=import-error from .pyramid_base_test import InstrumentationTest @@ -109,3 +117,144 @@ def test_with_existing_span(self): parent_span.get_span_context().span_id, span_list[0].parent.span_id, ) + + +class TestCustomRequestResponseHeaders( + InstrumentationTest, TestBase, WsgiTestBase +): + def setUp(self): + super().setUp() + PyramidInstrumentor().instrument() + self.config = Configurator() + self._common_initialization(self.config) + self.env_patch = patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,invalid-header", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "content-type,content-length,my-custom-header,invalid-header", + }, + ) + self.env_patch.start() + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + PyramidInstrumentor().uninstrument() + + def test_custom_request_header_added_in_server_span(self): + headers = { + "Custom-Test-Header-1": "Test Value 1", + "Custom-Test-Header-2": "TestValue2,TestValue3", + "Custom-Test-Header-3": "TestValue4", + } + resp = self.client.get("/hello/123", headers=headers) + self.assertEqual(200, resp.status_code) + span = self.memory_exporter.get_finished_spans()[0] + expected = { + "http.request.header.custom_test_header_1": ("Test Value 1",), + "http.request.header.custom_test_header_2": ( + "TestValue2,TestValue3", + ), + } + not_expected = { + "http.request.header.custom_test_header_3": ("TestValue4",), + } + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes(span, expected) + for key, _ in not_expected.items(): + self.assertNotIn(key, span.attributes) + + def test_custom_request_header_not_added_in_internal_span(self): + tracer = trace.get_tracer(__name__) + with tracer.start_as_current_span("test", kind=SpanKind.SERVER): + headers = { + "Custom-Test-Header-1": "Test Value 1", + "Custom-Test-Header-2": "TestValue2,TestValue3", + } + resp = self.client.get("/hello/123", headers=headers) + self.assertEqual(200, resp.status_code) + span = self.memory_exporter.get_finished_spans()[0] + not_expected = { + "http.request.header.custom_test_header_1": ("Test Value 1",), + "http.request.header.custom_test_header_2": ( + "TestValue2,TestValue3", + ), + } + self.assertEqual(span.kind, SpanKind.INTERNAL) + for key, _ in not_expected.items(): + self.assertNotIn(key, span.attributes) + + def test_custom_response_header_added_in_server_span(self): + resp = self.client.get("/test_custom_response_headers") + self.assertEqual(200, resp.status_code) + span = self.memory_exporter.get_finished_spans()[0] + expected = { + "http.response.header.content_type": ( + "text/plain; charset=utf-8", + ), + "http.response.header.content_length": ("7",), + "http.response.header.my_custom_header": ( + "my-custom-value-1,my-custom-header-2", + ), + } + not_expected = { + "http.response.header.dont_capture_me": ("test-value",) + } + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes(span, expected) + for key, _ in not_expected.items(): + self.assertNotIn(key, span.attributes) + + def test_custom_response_header_not_added_in_internal_span(self): + tracer = trace.get_tracer(__name__) + with tracer.start_as_current_span("test", kind=SpanKind.SERVER): + resp = self.client.get("/test_custom_response_headers") + self.assertEqual(200, resp.status_code) + span = self.memory_exporter.get_finished_spans()[0] + not_expected = { + "http.response.header.content_type": ( + "text/plain; charset=utf-8", + ), + "http.response.header.content_length": ("7",), + "http.response.header.my_custom_header": ( + "my-custom-value-1,my-custom-header-2", + ), + } + self.assertEqual(span.kind, SpanKind.INTERNAL) + for key, _ in not_expected.items(): + self.assertNotIn(key, span.attributes) + + +class TestCustomHeadersNonRecordingSpan( + InstrumentationTest, TestBase, WsgiTestBase +): + def setUp(self): + super().setUp() + # This is done because set_tracer_provider cannot override the + # current tracer provider. + reset_trace_globals() + tracer_provider = trace.NoOpTracerProvider() + trace.set_tracer_provider(tracer_provider) + PyramidInstrumentor().instrument() + self.config = Configurator() + self._common_initialization(self.config) + self.env_patch = patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,invalid-header", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "content-type,content-length,my-custom-header,invalid-header", + }, + ) + self.env_patch.start() + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + PyramidInstrumentor().uninstrument() + + def test_custom_header_non_recording_span(self): + try: + resp = self.client.get("/hello/123") + self.assertEqual(200, resp.status_code) + except Exception as exc: # pylint: disable=W0703 + self.fail(f"Exception raised with NonRecordingSpan {exc}") From de5115e67e9e08189143a5f435598d62c38bd563 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Tue, 29 Mar 2022 11:56:10 +0530 Subject: [PATCH 02/11] Adding entry to Changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62122d051..57f2e03458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1003])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1003) - `opentelemetry-instrumentation-elasticsearch` no longer creates unique span names by including search target, replaces them with `` and puts the value in attribute `elasticsearch.target` ([#1018](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1018)) +- `opentelemetry-instrumentation-pyramid` Pyramid: Capture custom request/response headers in span attributes + ([#1022])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1022) ## [1.10.0-0.29b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.10.0-0.29b0) - 2022-03-10 From 53467066d1c8925c01222507ef4342f88d843255 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Tue, 29 Mar 2022 12:18:08 +0530 Subject: [PATCH 03/11] Fixing pytest failures --- .../tests/test_automatic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py index a571d17f3b..0a839c60a2 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py @@ -138,6 +138,7 @@ def setUp(self): def tearDown(self) -> None: super().tearDown() + self.env_patch.stop() with self.disable_logging(): PyramidInstrumentor().uninstrument() @@ -249,6 +250,7 @@ def setUp(self): def tearDown(self) -> None: super().tearDown() + self.env_patch.stop() with self.disable_logging(): PyramidInstrumentor().uninstrument() From c12eea6ec43c573d5b867ac199aab6f39ba614e5 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Wed, 30 Mar 2022 19:00:28 +0530 Subject: [PATCH 04/11] Adding docstring for usage --- .../instrumentation/pyramid/__init__.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index bcde7eda74..9ed05181a7 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -90,6 +90,50 @@ will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. +Capture HTTP request and response headers +***************************************** +You can configure the agent to capture predefined HTTP headers as span attributes, according to the `semantic convention `_. + +Request headers +*************** +To capture predefined HTTP request headers as span attributes, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST`` +to a comma-separated list of HTTP header names. + +For example, + +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST="content_type,custom_request_header" + +will extract content_type and custom_request_header from request headers and add them as span attributes. + +Name of the added span attribute will follow the format ``http.request.header.`` +where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +Value of the attribute will be single item list containing all the header values. + +Example of the added span attribute, +``http.request.header.custom_request_header = [","]`` + +Response headers +**************** +To capture predefined HTTP response headers as span attributes, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE`` +to a comma-separated list of HTTP header names. + +For example, + +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE="content_type,custom_response_header" + +will extract content_type and custom_response_header from response headers and add them as span attributes. + +Name of the added span attribute will follow the format ``http.response.header.`` +where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +Value of the attribute will be single item list containing all the header values. + +Example of the added span attribute, +``http.response.header.custom_response_header = [","]`` + API --- """ From 24f48d213c7ae059c6c78da5aa00691d4de633e7 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Wed, 30 Mar 2022 20:23:56 +0530 Subject: [PATCH 05/11] Fixing lint error --- .../src/opentelemetry/instrumentation/pyramid/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 9ed05181a7..36b78807ae 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -107,8 +107,7 @@ will extract content_type and custom_request_header from request headers and add them as span attributes. -Name of the added span attribute will follow the format ``http.request.header.`` -where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +Name of the added span attribute will follow the format ``http.request.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). Value of the attribute will be single item list containing all the header values. Example of the added span attribute, @@ -127,8 +126,7 @@ will extract content_type and custom_response_header from response headers and add them as span attributes. -Name of the added span attribute will follow the format ``http.response.header.`` -where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +Name of the added span attribute will follow the format ``http.response.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). Value of the attribute will be single item list containing all the header values. Example of the added span attribute, From 639d8169d393ecce48d477f49f25548df6a744d6 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Thu, 31 Mar 2022 00:03:07 +0530 Subject: [PATCH 06/11] Adding suggested changes --- .../src/opentelemetry/instrumentation/pyramid/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 36b78807ae..766c909802 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -107,8 +107,8 @@ will extract content_type and custom_request_header from request headers and add them as span attributes. -Name of the added span attribute will follow the format ``http.request.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). -Value of the attribute will be single item list containing all the header values. +The name of the added span attribute will follow the format ``http.request.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +The value of the attribute will be single item list containing all the header values. Example of the added span attribute, ``http.request.header.custom_request_header = [","]`` @@ -126,8 +126,8 @@ will extract content_type and custom_response_header from response headers and add them as span attributes. -Name of the added span attribute will follow the format ``http.response.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). -Value of the attribute will be single item list containing all the header values. +The name of the added span attribute will follow the format ``http.response.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). +The value of the attribute will be single item list containing all the header values. Example of the added span attribute, ``http.response.header.custom_response_header = [","]`` From b0629d9204e607838d072e232c8b0f4331ca807b Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Thu, 31 Mar 2022 19:22:10 +0530 Subject: [PATCH 07/11] Adding note: Env vars names are experimental --- .../src/opentelemetry/instrumentation/pyramid/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 766c909802..41e9511149 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -132,6 +132,9 @@ Example of the added span attribute, ``http.response.header.custom_response_header = [","]`` +Note: + Environment variable names to caputre http headers are still experimental, and thus are subject to change. + API --- """ From cfc339a423489afe1658f557c4997f9beaac7b0f Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Fri, 1 Apr 2022 11:33:40 +0530 Subject: [PATCH 08/11] Adding recommended way and behaviour when capturing request/response headers --- .../instrumentation/pyramid/__init__.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 41e9511149..dbc8842473 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -103,9 +103,12 @@ :: - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST="content_type,custom_request_header" + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST="content-type,custom_request_header" -will extract content_type and custom_request_header from request headers and add them as span attributes. +will extract ``content-type`` and ``custom_request_header`` from request headers and add them as span attributes. + +It is recommended that you should give the correct names of the headers to be captured in the environment variable. +Request header names in pyramid are case insensitive and - characters are replaced by _. So, giving header name as ``CUStom_Header`` in environment variable will be able capture header with name ``custom-header``. The name of the added span attribute will follow the format ``http.request.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). The value of the attribute will be single item list containing all the header values. @@ -122,9 +125,12 @@ :: - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE="content_type,custom_response_header" + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE="content-type,custom_response_header" + +will extract ``content-type`` and ``custom_response_header`` from response headers and add them as span attributes. -will extract content_type and custom_response_header from response headers and add them as span attributes. +It is recommended that you should give the correct names of the headers to be captured in the environment variable. +Response header names captured in pyramid are case insensitive. So, giving header name as ``CUStomHeader`` in environment variable will be able capture header with name ``customheader``. The name of the added span attribute will follow the format ``http.response.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). The value of the attribute will be single item list containing all the header values. From 96c3ac1924643b1906bc9ecdd4201b4db24d3c88 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Fri, 1 Apr 2022 11:42:36 +0530 Subject: [PATCH 09/11] Lint: Removing trailing whitespaces --- .../src/opentelemetry/instrumentation/pyramid/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index dbc8842473..c92f9b0dc5 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -107,8 +107,8 @@ will extract ``content-type`` and ``custom_request_header`` from request headers and add them as span attributes. -It is recommended that you should give the correct names of the headers to be captured in the environment variable. -Request header names in pyramid are case insensitive and - characters are replaced by _. So, giving header name as ``CUStom_Header`` in environment variable will be able capture header with name ``custom-header``. +It is recommended that you should give the correct names of the headers to be captured in the environment variable. +Request header names in pyramid are case insensitive and - characters are replaced by _. So, giving header name as ``CUStom_Header`` in environment variable will be able capture header with name ``custom-header``. The name of the added span attribute will follow the format ``http.request.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). The value of the attribute will be single item list containing all the header values. @@ -129,8 +129,8 @@ will extract ``content-type`` and ``custom_response_header`` from response headers and add them as span attributes. -It is recommended that you should give the correct names of the headers to be captured in the environment variable. -Response header names captured in pyramid are case insensitive. So, giving header name as ``CUStomHeader`` in environment variable will be able capture header with name ``customheader``. +It is recommended that you should give the correct names of the headers to be captured in the environment variable. +Response header names captured in pyramid are case insensitive. So, giving header name as ``CUStomHeader`` in environment variable will be able capture header with name ``customheader``. The name of the added span attribute will follow the format ``http.response.header.`` where ```` being the normalized HTTP header name (lowercase, with - characters replaced by _ ). The value of the attribute will be single item list containing all the header values. From 7154db5c46a833e9d305d3d8465324e67666cf2f Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Tue, 5 Apr 2022 10:53:56 +0530 Subject: [PATCH 10/11] Changing headerList to headerList for response object pyramid --- .../src/opentelemetry/instrumentation/pyramid/callbacks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 6ff47911c2..c83e7bff6e 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -173,12 +173,12 @@ def trace_tween(request): otel_wsgi.add_response_attributes( span, status, - getattr(response, "headerList", None), + getattr(response, "headerlist", None), ) if span.is_recording() and span.kind == trace.SpanKind.SERVER: otel_wsgi.add_custom_response_headers( - span, getattr(response, "headerList", None) + span, getattr(response, "headerlist", None) ) propagator = get_global_response_propagator() From 6d3077bc8ddfaf788c71986f2dea38f27bd25087 Mon Sep 17 00:00:00 2001 From: Ashutosh Goel Date: Wed, 6 Apr 2022 11:52:58 +0530 Subject: [PATCH 11/11] fixing lint errors --- .../src/opentelemetry/instrumentation/pyramid/callbacks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index c83e7bff6e..680ecf1c84 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -129,6 +129,7 @@ def disabled_tween(request): return disabled_tween # make a request tracing function + # pylint: disable=too-many-branches def trace_tween(request): # pylint: disable=E1101 if _excluded_urls.url_disabled(request.url):