fix(proxy): log the open-breaker TTL preservation fallback at debug instead of per request warning

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
mateo 2026-09-10 21:24:29 +00:00
parent 1957bd388e
commit 14b5915d4c
2 changed files with 31 additions and 2 deletions

View file

@ -26,6 +26,7 @@ from typing_extensions import NotRequired, ReadOnly
from litellm import DualCache
from litellm._logging import verbose_proxy_logger
from litellm.caching.redis_cache import RedisCircuitBreakerOpenError
from litellm.constants import DYNAMIC_RATE_LIMIT_ERROR_THRESHOLD_PER_MINUTE, INTERNAL_CALL_ORIGIN_METADATA_KEY
from litellm.integrations.custom_logger import CustomLogger
from litellm.litellm_core_utils.prompt_templates.common_utils import (
@ -3856,8 +3857,12 @@ class _PROXY_MaxParallelRequestsHandler_v3(CustomLogger):
)
except Exception as e:
verbose_proxy_logger.warning("TTL preservation failed, falling back to regular pipeline: %s", e)
# Fallback to regular pipeline on error
log: Final = (
verbose_proxy_logger.debug
if isinstance(e, RedisCircuitBreakerOpenError)
else verbose_proxy_logger.warning
)
log("TTL preservation failed, falling back to regular pipeline: %s", e)
await self.internal_usage_cache.dual_cache.async_increment_cache_pipeline(
increment_list=pipeline_operations,
litellm_parent_otel_span=parent_otel_span,

View file

@ -1795,6 +1795,30 @@ async def test_async_increment_tokens_fallback_behavior():
), "Fallback method should be called when Lua script is not available"
@pytest.mark.asyncio
async def test_async_increment_tokens_open_breaker_falls_back_without_warning(caplog):
"""An open Redis breaker fast-fails the Lua script on every request, so it must fall
back to the regular pipeline quietly instead of emitting a WARNING per request."""
from unittest.mock import AsyncMock
from litellm.caching.redis_cache import RedisCircuitBreakerOpenError
handler = _PROXY_MaxParallelRequestsHandler(internal_usage_cache=InternalUsageCache(DualCache()))
handler.token_increment_script = object()
handler._execute_token_increment_script = AsyncMock(
side_effect=RedisCircuitBreakerOpenError("Redis circuit breaker is open, skipping run_script")
)
fallback = AsyncMock()
handler.internal_usage_cache.dual_cache.async_increment_cache_pipeline = fallback
pipeline_operations = [RedisPipelineIncrementOperation(key="test_breaker_key", increment_value=10.0, ttl=60)]
with caplog.at_level(logging.DEBUG, logger="LiteLLM Proxy"):
await handler.async_increment_tokens_with_ttl_preservation(pipeline_operations=pipeline_operations)
assert fallback.await_count == 1
assert [r.levelno for r in caplog.records if "TTL preservation failed" in r.getMessage()] == [logging.DEBUG]
# Redis Cluster Compatibility Tests
def test_group_keys_by_hash_tag_regular_redis():
"""