mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
Merge a5c0874a75 into 72228db5c6
This commit is contained in:
commit
a096843d2e
4 changed files with 88 additions and 2 deletions
|
|
@ -192,6 +192,7 @@ standard_logging_payload_excluded_fields: Optional[List[str]] = (
|
|||
None # Fields to exclude from StandardLoggingPayload before callbacks receive it
|
||||
)
|
||||
log_raw_request_response: bool = False
|
||||
max_raw_request_body_log_chars: Optional[int] = None
|
||||
log_client_error_tracebacks: bool = False
|
||||
log_auth_failure_key_identity: bool = False
|
||||
request_correlation_in_logs: bool = False
|
||||
|
|
|
|||
|
|
@ -2199,6 +2199,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", 102400) # 100 KB
|
||||
|
||||
# Policy template enrichment
|
||||
MAX_COMPETITOR_NAMES: Final = get_env_int("MAX_COMPETITOR_NAMES", 100)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,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,
|
||||
|
|
@ -1841,8 +1842,17 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
else:
|
||||
verbose_logger.debug("\x1b[92m%s\x1b[0m\n", curl_command)
|
||||
|
||||
def _get_max_raw_request_body_log_chars(self) -> int:
|
||||
if getattr(litellm, "max_raw_request_body_log_chars", None) is not None:
|
||||
return cast(int, litellm.max_raw_request_body_log_chars)
|
||||
return MAX_RAW_REQUEST_BODY_LOG_CHARS
|
||||
|
||||
def _get_request_body(self, data: dict) -> str:
|
||||
return str(data)
|
||||
body: Final = str(data)
|
||||
max_chars: Final = self._get_max_raw_request_body_log_chars()
|
||||
if len(body) > max_chars:
|
||||
return f"<{len(body)} chars omitted, over MAX_RAW_REQUEST_BODY_LOG_CHARS={max_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)
|
||||
|
|
@ -1858,7 +1868,10 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
if additional_args.get("request_str", None) is not None:
|
||||
# print the sagemaker / bedrock client request
|
||||
curl_command = "\nRequest Sent from LiteLLM:\n"
|
||||
request_str: Final = additional_args.get("request_str", "")
|
||||
request_str: str = str(additional_args.get("request_str", ""))
|
||||
max_chars: Final = self._get_max_raw_request_body_log_chars()
|
||||
if len(request_str) > max_chars:
|
||||
request_str = f"<{len(request_str)} chars omitted, over MAX_RAW_REQUEST_BODY_LOG_CHARS={max_chars}>"
|
||||
curl_command += request_str
|
||||
return curl_command
|
||||
|
||||
|
|
|
|||
|
|
@ -8711,6 +8711,77 @@ 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 an oversized raw request blocks the event loop, so the body is omitted from the curl command."""
|
||||
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": "LONG-PROMPT-CONTENT " * 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 "LONG-PROMPT-CONTENT" not in raw_request
|
||||
assert "chars omitted, over MAX_RAW_REQUEST_BODY_LOG_CHARS=100" 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
|
||||
|
||||
|
||||
def test_pre_call_omits_request_str_over_size_limit(logging_obj, monkeypatch):
|
||||
"""Oversized request_str (e.g. from Bedrock or SageMaker) is also omitted from raw request logging."""
|
||||
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
|
||||
long_request_str = "BEDROCK-RAW-PAYLOAD-" * 20
|
||||
|
||||
logging_obj.pre_call(
|
||||
input="hi",
|
||||
api_key="",
|
||||
additional_args={
|
||||
"api_base": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"headers": {},
|
||||
"request_str": long_request_str,
|
||||
},
|
||||
)
|
||||
|
||||
raw_request = metadata["raw_request"]
|
||||
assert "BEDROCK-RAW-PAYLOAD-" not in raw_request
|
||||
assert "chars omitted, over MAX_RAW_REQUEST_BODY_LOG_CHARS=100" in raw_request
|
||||
|
||||
|
||||
def test_pre_call_includes_request_body_under_size_limit(logging_obj, monkeypatch):
|
||||
"""Normal sized payloads under the limit are fully included and redacted."""
|
||||
monkeypatch.setattr("litellm.litellm_core_utils.litellm_logging.MAX_RAW_REQUEST_BODY_LOG_CHARS", 1000)
|
||||
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": "short prompt"}]}
|
||||
|
||||
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 "short prompt" in raw_request
|
||||
assert "chars omitted" not in raw_request
|
||||
|
||||
|
||||
_PRIVATE_RAW_REQUEST_ARGS: Final = {
|
||||
"api_base": "https://api.openai.com/v1/chat/completions",
|
||||
"headers": {},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue