From b0ba68f6dac2a743c49cf30890f5f5e2926dd540 Mon Sep 17 00:00:00 2001 From: euisuh Date: Fri, 24 Jul 2026 09:11:19 +0900 Subject: [PATCH 1/2] docs(httpx): document response payload logging Document how to inspect HTTPX response payload chunks without consuming the response stream inside response_hook. Assisted-by: Hermes Agent --- .../README.rst | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/README.rst b/instrumentation/opentelemetry-instrumentation-httpx/README.rst index e3a9591aa3..b3478eceb4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/README.rst +++ b/instrumentation/opentelemetry-instrumentation-httpx/README.rst @@ -256,6 +256,62 @@ Or if you are using the transport classes directly: response_hook=async_response_hook ) +Logging response payloads +------------------------- + +The ``response`` value passed to ``response_hook`` contains the response +stream. Reading that stream inside the hook consumes it before the application +can read the response body. + +To inspect or log response payload chunks, wrap the HTTPX transport and yield +chunks as the application consumes them: + +.. code-block:: python + + import httpx + from opentelemetry.instrumentation.httpx import SyncOpenTelemetryTransport + + class LoggingResponse(httpx.Response): + def iter_bytes(self, *args, **kwargs): + for chunk in super().iter_bytes(*args, **kwargs): + print(chunk) + yield chunk + + class LoggingTransport(httpx.BaseTransport): + def __init__(self, transport): + self._transport = transport + + def handle_request(self, request): + response = self._transport.handle_request(request) + return LoggingResponse( + status_code=response.status_code, + headers=response.headers, + stream=response.stream, + extensions=response.extensions, + ) + + def close(self): + self._transport.close() + + def response_hook(span, request, response): + status_code, headers, stream, extensions = response + span.set_attribute("http.response.status_code", status_code) + # Do not read stream here; LoggingResponse logs chunks safely. + + transport = LoggingTransport(httpx.HTTPTransport()) + telemetry_transport = SyncOpenTelemetryTransport( + transport, + response_hook=response_hook, + ) + + with httpx.Client(transport=telemetry_transport) as client: + response = client.get("https://example.com") + response.read() + +For request payloads, prefer logging or redacting the body before it is passed +to HTTPX. Avoid recording secrets, credentials, or personally identifiable +information in span attributes or logs. + References ---------- From 27738bd9e5f1ae89ca182a697339a3017d98ed43 Mon Sep 17 00:00:00 2001 From: euisuh Date: Fri, 24 Jul 2026 09:13:52 +0900 Subject: [PATCH 2/2] docs(httpx): clarify payload logging guidance Clarify that the transport wrapper avoids reading the hook stream directly. Assisted-by: Hermes Agent --- instrumentation/opentelemetry-instrumentation-httpx/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/README.rst b/instrumentation/opentelemetry-instrumentation-httpx/README.rst index b3478eceb4..de4cf0ca67 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/README.rst +++ b/instrumentation/opentelemetry-instrumentation-httpx/README.rst @@ -264,7 +264,7 @@ stream. Reading that stream inside the hook consumes it before the application can read the response body. To inspect or log response payload chunks, wrap the HTTPX transport and yield -chunks as the application consumes them: +chunks from the response object instead of reading the hook's stream directly: .. code-block:: python