feat(logging): add retry settings for generic API logger - #26645
Conversation
Made-with: Cursor
Greptile SummaryThis PR adds opt-in retry settings ( Confidence Score: 5/5Safe to merge; the only finding is a P2 style note about an unreachable RuntimeError guard All logic is correct: the 5xx retry integrates correctly with MaskedHTTPStatusError, the cache invalidation covers all new fields, defaults preserve current behavior (max_retries=0), and new tests are mock-only. Only a cosmetic dead-code line was identified. No files require special attention
|
| Filename | Overview |
|---|---|
| litellm/integrations/generic_api/generic_api_callback.py | Adds opt-in retry settings (max_retries, retry_delay, timeout) with exponential backoff via _post_with_retries; one unreachable RuntimeError guard at the end of the method is dead code but otherwise logic is correct |
| litellm/litellm_core_utils/logging_callback_manager.py | Correctly wires max_retries, retry_delay, and timeout from YAML callback_settings into GenericAPILogger and includes them in the cache equality check to invalidate stale loggers on config change |
| tests/logging_callback_tests/test_generic_api_callback.py | Adds three well-isolated mock-only tests covering timeout retry, 5xx retry, and 4xx no-retry; uses AsyncMock with no real network calls, consistent with the folder's test rules |
| tests/litellm_utils_tests/test_logging_callback_manager.py | Adds a test verifying that YAML callback_settings retry fields propagate correctly into GenericAPILogger attributes; cleans up litellm.callback_settings and the cache in a finally block |
Sequence Diagram
sequenceDiagram
participant CB as CustomBatchLogger
participant GL as GenericAPILogger
participant PR as _post_with_retries
participant HC as AsyncHTTPHandler.post()
participant EP as Callback Endpoint
CB->>GL: async_send_batch()
GL->>PR: _post_with_retries(data)
loop attempt = 0..max_retries
PR->>HC: post(url, headers, data, [timeout])
HC->>EP: HTTP POST
alt Success (2xx)
EP-->>HC: 200 OK
HC-->>PR: httpx.Response
PR-->>GL: httpx.Response
else Timeout / TransportError
HC-->>PR: raises litellm.Timeout / httpx.TransportError
PR->>PR: _should_retry_exception → True
PR->>PR: _sleep_before_retry(attempt) [exponential]
else 5xx Error
EP-->>HC: 5xx
HC->>HC: raise_for_status() → MaskedHTTPStatusError
HC-->>PR: raises MaskedHTTPStatusError (subclass of HTTPStatusError)
PR->>PR: _should_retry_exception → status >= 500 → True
PR->>PR: _sleep_before_retry(attempt)
else 4xx Error
EP-->>HC: 4xx
HC->>HC: raise_for_status() → MaskedHTTPStatusError
HC-->>PR: raises MaskedHTTPStatusError
PR->>PR: _should_retry_exception → status < 500 → False
PR-->>GL: re-raises exception
end
end
GL->>GL: log_queue.clear() (finally)
Reviews (2): Last reviewed commit: "Refine generic API retry behavior" | Re-trigger Greptile
Made-with: Cursor
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
* Add retry settings for generic API logger Made-with: Cursor * Refine generic API retry behavior Made-with: Cursor
* Add retry settings for generic API logger Made-with: Cursor * Refine generic API retry behavior Made-with: Cursor
Relevant issues
Addresses Generic API Logger batch send failures where transient callback endpoint timeouts, such as
litellm.Timeout/httpx.ConnectTimeout, cause the batch send to fail without a configurable retry.Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
CI (LiteLLM team)
Branch creation CI run
Link:
CI run for the last commit
Link:
Merge / cherry-pick CI run
Links:
Screenshots / Proof of Fix
Targeted tests
Local timeout repro
Configured Generic API callback via YAML
callback_settings:Repro sink delayed the first callback response for
1s, exceeding the callback timeout (0.2s), then responded immediately on retry.Observed sink attempts:
{"attempt": 1, "path": "/logs", "status_code": 200, "delay_seconds": 1.0} {"attempt": 2, "path": "/logs", "status_code": 200, "delay_seconds": 0}Observed proxy retry log:
The completion request still succeeded and
/healthreturned200.Type
🆕 New Feature
✅ Test
Changes
GenericAPILogger:max_retriesretry_delaytimeoutcallback_settingsforcallback_type: generic_api.5xxerrors.4xxerrors.max_retries=0.5xxretry then success4xxno retrycallback_settingspropagation intoGenericAPILogger