From 9181020eb66e011e1277af7432ff98483ba1728b Mon Sep 17 00:00:00 2001 From: Ed Dawley Date: Tue, 29 Jul 2025 09:59:01 -0400 Subject: [PATCH 1/5] Adding new optional `post_injection_hook` to `RequestsInstrumentor` The `tracestate` and `baggage` headers may contain sensitive information that is valuable to propagate to trusted systems but could pose concerns when sent to untrusted systems. Currently there is no way to support instrumenting these spans while ensuring these, or other, headers are conditionally propagated. This new option allows callers to define a callable to mutate the post-injection headers based on each request. --- CHANGELOG.md | 2 ++ .../instrumentation/requests/__init__.py | 34 +++++++++++++++++++ .../tests/test_requests_integration.py | 15 ++++++++ 3 files changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 831b8b50ef..4f5d7d5873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) - `opentelemetry-instrumentation-kafka-python` Utilize instruments-any functionality. ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) +- `opentelemetry-instrumentation-requests` Add support for post-injection-hook. + ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) ## Version 1.35.0/0.56b0 (2025-07-11) 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 7cfc3a4fee..5f46d9b3af 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -86,6 +86,31 @@ def response_hook(span, request_obj, response): will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. +Post Injection Hook +******************* +To customize headers after the current context is injected, you can provide a function that will be called with +both the headers and request object. + +For example, to avoid propagating `tracestate`/`baggage` to non-allowed hosts while still creating a span: + +.. code:: python + + allowed_hosts = frozenset(["my-company.com", "my-cloud-provider.com"]) + + def post_injection_hook(headers, request): + # Parse the domain from the request URL + parsed_url = urlparse(request.url) + request_host = parsed_url.hostname + + # Remove headers if the host is NOT in the allowed list + if request_host not in allowed_hosts: + headers.pop("tracestate", None) + headers.pop("baggage", None) + + RequestsInstrumentor().instrument( + post_injection_hook=post_injection_hook + ) + API --- """ @@ -156,6 +181,9 @@ def response_hook(span, request_obj, response): _RequestHookT = Optional[Callable[[Span, PreparedRequest], None]] _ResponseHookT = Optional[Callable[[Span, PreparedRequest, Response], None]] +_PostInjectionHookT = Optional[ + Callable[[CaseInsensitiveDict[str], PreparedRequest], None] +] def _set_http_status_code_attribute( @@ -194,6 +222,7 @@ def _instrument( response_hook: _ResponseHookT = None, excluded_urls: ExcludeList | None = None, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, + post_injection_hook: _PostInjectionHookT = None, ): """Enables tracing of all requests calls that go through :code:`requests.session.Session.request` (this includes @@ -300,6 +329,9 @@ def get_or_create_headers(): headers = get_or_create_headers() inject(headers) + if callable(post_injection_hook): + post_injection_hook(headers, request) + with suppress_http_instrumentation(): start_time = default_timer() try: @@ -450,6 +482,7 @@ def _instrument(self, **kwargs: Any): duration_histogram_boundaries = kwargs.get( "duration_histogram_boundaries" ) + post_injection_hook = kwargs.get("post_injection_hook") meter = get_meter( __name__, __version__, @@ -486,6 +519,7 @@ def _instrument(self, **kwargs: Any): else parse_excluded_urls(excluded_urls) ), sem_conv_opt_in_mode=semconv_opt_in_mode, + post_injection_hook=post_injection_hook, ) def _uninstrument(self, **kwargs: Any): diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index ac3d41294b..93a66ae831 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -322,6 +322,21 @@ def response_hook(span, request_obj, response): self.assertEqual(span.name, "name set from hook") self.assertEqual(span.attributes["response_hook_attr"], "value") + def test_post_injection_hook(self): + def post_injection_hook(headers, request): + headers.pop("traceparent", None) + + RequestsInstrumentor().uninstrument() + RequestsInstrumentor().instrument( + post_injection_hook=post_injection_hook + ) + + self.perform_request(self.URL) + + span = self.assert_span() + self.assertEqual(span.name, "GET") + self.assertNotIn("traceparent", httpretty.last_request().headers) + def test_excluded_urls_explicit(self): url_404 = "http://mock/status/404" httpretty.register_uri( From d429b9a3f8685774260332ce38757fb941a53a27 Mon Sep 17 00:00:00 2001 From: Ed Dawley Date: Tue, 29 Jul 2025 10:28:12 -0400 Subject: [PATCH 2/5] updated changelog with new PR --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f5d7d5873..58198eea34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,8 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) - `opentelemetry-instrumentation-kafka-python` Utilize instruments-any functionality. ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) -- `opentelemetry-instrumentation-requests` Add support for post-injection-hook. - ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) +- `opentelemetry-instrumentation-requests` Added support for post-injection-hook. + ([#3657](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3657)) ## Version 1.35.0/0.56b0 (2025-07-11) From ae947360fd78cea23adc2472948d5ef93ac604a8 Mon Sep 17 00:00:00 2001 From: Edward Dawley Date: Wed, 30 Jul 2025 11:38:19 -0400 Subject: [PATCH 3/5] Update CHANGELOG.md moved change to correct unreleased spot --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 587935bf58..836bdb2ff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added +- `opentelemetry-instrumentation-requests` Added support for post-injection-hook. + ([#3657](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3657)) + ## Version 1.36.0/0.57b0 (2025-07-29) ### Fixed From 7c750febb86eecb857d7185b942e49b03828a8ee Mon Sep 17 00:00:00 2001 From: Edward Dawley Date: Wed, 30 Jul 2025 11:38:57 -0400 Subject: [PATCH 4/5] Update CHANGELOG.md forgot to remove the old line --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 836bdb2ff4..7104e5c5b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,8 +30,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) - `opentelemetry-instrumentation-kafka-python` Utilize instruments-any functionality. ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) -- `opentelemetry-instrumentation-requests` Added support for post-injection-hook. - ([#3657](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3657)) - `opentelemetry-instrumentation-system-metrics`: Add `cpython.gc.collections` metrics with collection unit is specified in semconv ([3617](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3617)) From e29bfb277ac6c6d46cb201eff40b95ee4f334183 Mon Sep 17 00:00:00 2001 From: Edward Dawley Date: Wed, 30 Jul 2025 11:39:33 -0400 Subject: [PATCH 5/5] Update CHANGELOG.md removed unnecessary white space change --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7104e5c5b1..87171a0796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) - `opentelemetry-instrumentation-system-metrics`: Add `cpython.gc.collections` metrics with collection unit is specified in semconv ([3617](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3617)) - ## Version 1.35.0/0.56b0 (2025-07-11) ### Added