diff --git a/skyvern/forge/request_logging.py b/skyvern/forge/request_logging.py index b6617452..d300db21 100644 --- a/skyvern/forge/request_logging.py +++ b/skyvern/forge/request_logging.py @@ -3,6 +3,7 @@ from __future__ import annotations import typing import structlog +from starlette.concurrency import iterate_in_threadpool from skyvern.config import settings @@ -49,6 +50,20 @@ def _sanitize_body(request: Request, body: bytes, content_type: str | None) -> s return text +async def _get_response_body_str(response: Response) -> str: + response_body = b"" + async for chunk in response.body_iterator: + response_body += chunk + response.body_iterator = iterate_in_threadpool(iter([response_body])) + + try: + return response_body.decode("utf-8") + except UnicodeDecodeError: + return str(response_body) + except Exception: + return str(response_body) + + async def log_raw_request_middleware(request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response: if not settings.LOG_RAW_API_REQUESTS: return await call_next(request) @@ -70,10 +85,14 @@ async def log_raw_request_middleware(request: Request, call_next: Callable[[Requ if response.status_code >= 500: log_method = LOG.error + error_body = await _get_response_body_str(response) elif response.status_code >= 400: log_method = LOG.warning + error_body = await _get_response_body_str(response) else: log_method = LOG.info + error_body = None + log_method( "api.raw_request", method=http_method, @@ -81,6 +100,7 @@ async def log_raw_request_middleware(request: Request, call_next: Callable[[Requ status_code=response.status_code, body=body_text, headers=sanitized_headers, + error_body=error_body, ) return response except Exception: