Skip to content

Commit aa2488e

Browse files
ivankalinovskiIvan Kalinovski
andauthored
[Core] Add third party data size (#1902)
### **User description** # Description What - Add log for third party response size Why - Know the size of data returned from third parties. How - Add log in retry transport ## Type of change Please leave one option from the following and delete the rest: - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] New Integration (non-breaking change which adds a new integration) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Non-breaking change (fix of existing functionality that will not change current behavior) - [ ] Documentation (added/updated documentation) <h4> All tests should be run against the port production environment(using a testing org). </h4> ### Core testing checklist - [ ] Integration able to create all default resources from scratch - [ ] Resync finishes successfully - [ ] Resync able to create entities - [ ] Resync able to update entities - [ ] Resync able to detect and delete entities - [ ] Scheduled resync able to abort existing resync and start a new one - [ ] Tested with at least 2 integrations from scratch - [ ] Tested with Kafka and Polling event listeners - [ ] Tested deletion of entities that don't pass the selector ### Integration testing checklist - [ ] Integration able to create all default resources from scratch - [ ] Resync able to create entities - [ ] Resync able to update entities - [ ] Resync able to detect and delete entities - [ ] Resync finishes successfully - [ ] If new resource kind is added or updated in the integration, add example raw data, mapping and expected result to the `examples` folder in the integration directory. - [ ] If resource kind is updated, run the integration with the example data and check if the expected result is achieved - [ ] If new resource kind is added or updated, validate that live-events for that resource are working as expected - [ ] Docs PR link [here](#) ### Preflight checklist - [ ] Handled rate limiting - [ ] Handled pagination - [ ] Implemented the code in async - [ ] Support Multi account ## Screenshots Include screenshots from your environment showing how the resources of the integration will look. ## API Documentation Provide links to the API documentation used for this integration. ___ ### **PR Type** Enhancement ___ ### **Description** - Add response size logging for third-party API calls - Exclude Port's own API from size logging - Support both sync and async HTTP transports - Handle content-length headers and actual content reading ___ ### **Changes diagram** ```mermaid flowchart LR A["HTTP Request"] --> B["Retry Transport"] B --> C["Execute Request"] C --> D["Get Response"] D --> E["Log Response Size"] E --> F["Return Response"] G["Content-Length Header"] --> E H["Actual Content Size"] --> E ``` ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>retry.py</strong><dd><code>Add third-party response size logging functionality</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> port_ocean/helpers/retry.py <li>Add response size logging methods for sync and async operations<br> <li> Filter out Port's own API calls from logging<br> <li> Handle content-length headers and fallback to actual content reading<br> <li> Integrate logging calls into existing request handling flow </details> </td> <td><a href="https://github.com/port-labs/ocean/pull/1902/files#diff-a02bcfe3ab769cf2d3d6ef3f313947e35886fbe56e5c55f7a9799043014aff1a">+68/-1</a>&nbsp; &nbsp; </td> </tr> </table></td></tr><tr><td><strong>Documentation</strong></td><td><table> <tr> <td> <details> <summary><strong>CHANGELOG.md</strong><dd><code>Update changelog with response size logging</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> CHANGELOG.md <li>Add changelog entry for version 0.25.3<br> <li> Document new response body size logging feature </details> </td> <td><a href="https://github.com/port-labs/ocean/pull/1902/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed">+6/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></td></tr><tr><td><strong>Configuration changes</strong></td><td><table> <tr> <td> <details> <summary><strong>pyproject.toml</strong><dd><code>Version bump to 0.25.4</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> pyproject.toml - Bump version from 0.25.3 to 0.25.4 </details> </td> <td><a href="https://github.com/port-labs/ocean/pull/1902/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about Qodo Merge usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details> --------- Co-authored-by: Ivan Kalinovski <ivankalinovski@ivan.k-laptop>
1 parent 8f2d1ca commit aa2488e

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
<!-- towncrier release notes start -->
9+
## 0.25.4 (2025-07-16)
10+
11+
### Improvements
12+
13+
- Add logging for integrations's response body size.
14+
915
## 0.25.3 (2025-07-15)
1016

1117
### Bugfix

port_ocean/helpers/retry.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from datetime import datetime
55
from functools import partial
66
from http import HTTPStatus
7-
from typing import Any, Callable, Coroutine, Iterable, Mapping, Union
7+
from typing import Any, Callable, Coroutine, Iterable, Mapping, Union, cast
88
import httpx
99
from dateutil.parser import isoparse
10+
import logging
1011

1112
_ON_RETRY_CALLBACK: Callable[[httpx.Request], httpx.Request] | None = None
1213

@@ -148,6 +149,9 @@ def handle_request(self, request: httpx.Request) -> httpx.Response:
148149
response = self._retry_operation(request, send_method)
149150
else:
150151
response = transport.handle_request(request)
152+
153+
self._log_response_size(request, response)
154+
151155
return response
152156
except Exception as e:
153157
if not self._is_retryable_method(request) and self._logger is not None:
@@ -172,6 +176,8 @@ async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
172176
else:
173177
response = await transport.handle_async_request(request)
174178

179+
await self._log_response_size_async(request, response)
180+
175181
return response
176182
except Exception as e:
177183
# Retyable methods are logged via _log_error
@@ -246,6 +252,67 @@ def _log_before_retry(
246252
f" {type(error).__name__} - {str(error) or 'No error message'}, retrying in {sleep_time} seconds."
247253
)
248254

255+
def _should_log_response_size(self, request: httpx.Request) -> bool:
256+
return self._logger is not None and not request.url.host.endswith("getport.io")
257+
258+
def _get_content_length(self, response: httpx.Response) -> int | None:
259+
content_length = response.headers.get("Content-Length") or response.headers.get(
260+
"content-length"
261+
)
262+
if content_length:
263+
return int(content_length)
264+
return None
265+
266+
async def _log_response_size_async(
267+
self, request: httpx.Request, response: httpx.Response
268+
) -> None:
269+
"""Log the size of the response."""
270+
if not self._should_log_response_size(request):
271+
return
272+
273+
# Try to get content length from headers first
274+
content_length = self._get_content_length(response)
275+
if content_length is not None:
276+
size_info = content_length
277+
else:
278+
# If no Content-Length header, try to get actual content size
279+
try:
280+
actual_size = len(await response.aread())
281+
size_info = actual_size
282+
except Exception as e:
283+
cast(logging.Logger, self._logger).error(
284+
f"Error getting response size: {e}"
285+
)
286+
return
287+
288+
cast(logging.Logger, self._logger).info(
289+
f"Response for {request.method} {request.url} - Size: {size_info} bytes"
290+
)
291+
292+
def _log_response_size(
293+
self, request: httpx.Request, response: httpx.Response
294+
) -> None:
295+
if not self._should_log_response_size(request):
296+
return
297+
298+
content_length = self._get_content_length(response)
299+
if content_length is not None:
300+
size_info = content_length
301+
else:
302+
# If no Content-Length header, try to get actual content size
303+
try:
304+
actual_size = len(response.read())
305+
size_info = actual_size
306+
except Exception as e:
307+
cast(logging.Logger, self._logger).error(
308+
f"Error getting response size: {e}"
309+
)
310+
return
311+
312+
cast(logging.Logger, self._logger).info(
313+
f"Response for {request.method} {request.url} - Size: {size_info} bytes"
314+
)
315+
249316
async def _should_retry_async(self, response: httpx.Response) -> bool:
250317
return response.status_code in self._retry_status_codes
251318

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "port-ocean"
3-
version = "0.25.3"
3+
version = "0.25.4"
44
description = "Port Ocean is a CLI tool for managing your Port projects."
55
readme = "README.md"
66
homepage = "https://app.getport.io"

0 commit comments

Comments
 (0)