mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
fix(logging): leave oversized bodies out of the raw request log
With log_raw_request_response on, every request builds a curl string of the full body and runs secret redaction over it on the event loop. For a 16 MB body that blocks the proxy for seconds, so liveness probes time out and the pod restarts Bodies longer than MAX_RAW_REQUEST_BODY_LOG_CHARS (default 1,000,000) are now replaced by a short placeholder in the curl string, which keeps the URL and masked headers. raw_request_typed_dict still holds the full body Fixes #49673
This commit is contained in:
parent
97cd5d0c6a
commit
44862f0dc9
3 changed files with 30 additions and 1 deletions
|
|
@ -2184,6 +2184,7 @@ MICROSOFT_USER_LAST_NAME_ATTRIBUTE: Final = str(os.getenv("MICROSOFT_USER_LAST_N
|
|||
# Maximum payload size (in bytes) to fully serialize for DEBUG logging.
|
||||
# Payloads larger than this are truncated to avoid multi-second json.dumps blocking the response.
|
||||
MAX_PAYLOAD_SIZE_FOR_DEBUG_LOG: Final = get_env_int("MAX_PAYLOAD_SIZE_FOR_DEBUG_LOG", 102400) # 100 KB
|
||||
MAX_RAW_REQUEST_BODY_LOG_CHARS: Final = get_env_int("MAX_RAW_REQUEST_BODY_LOG_CHARS", 1_000_000)
|
||||
|
||||
# Policy template enrichment
|
||||
MAX_COMPETITOR_NAMES: Final = get_env_int("MAX_COMPETITOR_NAMES", 100)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ from litellm.constants import (
|
|||
INTERNAL_CALLBACK_NAMES,
|
||||
KUBERNETES_POD_ROUTING_KEY,
|
||||
LITELLM_LOGGING_NO_UPSTREAM_LLM_CALL,
|
||||
MAX_RAW_REQUEST_BODY_LOG_CHARS,
|
||||
PROVIDER_REQUEST_ID_HEADERS,
|
||||
REALTIME_METERED_USAGE_KEY,
|
||||
REDACTED_BY_LITELLM,
|
||||
|
|
@ -1830,7 +1831,10 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
verbose_logger.debug("\x1b[92m%s\x1b[0m\n", curl_command)
|
||||
|
||||
def _get_request_body(self, data: dict) -> str:
|
||||
return str(data)
|
||||
body: Final = str(data)
|
||||
if len(body) > MAX_RAW_REQUEST_BODY_LOG_CHARS:
|
||||
return f"<{len(body)} chars omitted, over MAX_RAW_REQUEST_BODY_LOG_CHARS={MAX_RAW_REQUEST_BODY_LOG_CHARS}>"
|
||||
return body
|
||||
|
||||
def _get_request_curl_command(self, api_base: str, headers: dict | None, additional_args: dict, data: dict) -> str:
|
||||
masked_api_base: Final = self._get_masked_api_base(api_base)
|
||||
|
|
|
|||
|
|
@ -8662,6 +8662,30 @@ def test_pre_call_redacts_and_masks_raw_request(logging_obj):
|
|||
assert "key=*****" in raw_api_base
|
||||
|
||||
|
||||
def test_pre_call_omits_raw_request_body_over_size_limit(logging_obj, monkeypatch):
|
||||
"""Redacting a multi-MB raw request blocks the event loop, so an oversized body is left out of it."""
|
||||
monkeypatch.setattr("litellm.litellm_core_utils.litellm_logging.MAX_RAW_REQUEST_BODY_LOG_CHARS", 100)
|
||||
metadata = {"user_api_key_alias": "qa-key"}
|
||||
logging_obj.model_call_details["litellm_params"] = {"metadata": metadata}
|
||||
logging_obj.log_raw_request_response = True
|
||||
body = {"messages": [{"role": "user", "content": "PRIVATE-PHRASE " * 20}]}
|
||||
|
||||
logging_obj.pre_call(
|
||||
input="hi",
|
||||
api_key="",
|
||||
additional_args={
|
||||
"api_base": "https://api.openai.com/v1/chat/completions",
|
||||
"headers": {},
|
||||
"complete_input_dict": body,
|
||||
},
|
||||
)
|
||||
|
||||
raw_request = metadata["raw_request"]
|
||||
assert "PRIVATE-PHRASE" not in raw_request
|
||||
assert "https://api.openai.com/v1/chat/completions" in raw_request
|
||||
assert logging_obj.model_call_details["raw_request_typed_dict"]["raw_request_body"] == body
|
||||
|
||||
|
||||
_PRIVATE_RAW_REQUEST_ARGS: Final = {
|
||||
"api_base": "https://api.openai.com/v1/chat/completions",
|
||||
"headers": {},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue