From bab7f619e423ec69caa8a41f3b7e690e44965d15 Mon Sep 17 00:00:00 2001 From: Supul Date: Mon, 5 Oct 2026 00:00:20 +0530 Subject: [PATCH] fix(logging): keep request bodies out of debug logs when LITELLM_ECS_LOGS is on _print_llm_call_debugging_log only took its masked-headers branch for json_logs, so with ECS on and debug logging enabled it fell through to the curl command and wrote complete_input_dict (the full prompt) into the collected log stream --- litellm/litellm_core_utils/litellm_logging.py | 3 +- .../test_litellm_logging.py | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index 989777e9412..790ce2c4a1e 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -22,6 +22,7 @@ from pydantic import BaseModel import litellm from litellm import ( _custom_logger_compatible_callbacks_literal, + ecs_logs, json_logs, log_raw_request_response, turn_off_message_logging, @@ -1333,7 +1334,7 @@ class Logging(LiteLLMLoggingBaseClass): Prints the RAW curl command sent from LiteLLM """ if _is_debugging_on() or self.litellm_request_debug: - if json_logs: + if json_logs or ecs_logs: masked_headers: Final = self._get_masked_headers(headers) masked_api_base: Final = self._get_masked_api_base(str(api_base or "")) if self.litellm_request_debug: diff --git a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py index 0f44cbbb2a7..b2a16d186a3 100644 --- a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py +++ b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py @@ -6486,3 +6486,33 @@ def test_get_error_information_redacts_provider_key_from_upstream_url(): assert "REDACTED" in result["traceback"] assert "REDACTED" in result["error_message"] assert result["error_code"] == "400" + + +def test_ecs_logs_keep_the_request_body_out_of_the_debug_log(logging_obj, monkeypatch): + import io + import logging + + import litellm.litellm_core_utils.litellm_logging as litellm_logging_module + from litellm._logging import verbose_logger + + monkeypatch.setattr(litellm_logging_module, "json_logs", False) + monkeypatch.setattr(litellm_logging_module, "ecs_logs", True) + logging_obj.litellm_request_debug = True + stream = io.StringIO() + handler = logging.StreamHandler(stream) + verbose_logger.addHandler(handler) + try: + logging_obj._print_llm_call_debugging_log( + api_base="https://api.example.com/v1", + headers={}, + additional_args={ + "api_base": "https://api.example.com/v1", + "headers": {}, + "complete_input_dict": {"messages": [{"role": "user", "content": "my-private-prompt-text"}]}, + }, + ) + finally: + verbose_logger.removeHandler(handler) + + assert "POST Request Sent from LiteLLM" in stream.getvalue() + assert "my-private-prompt-text" not in stream.getvalue()