mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(proxy): surface a failed project spend enqueue at error level
The call-site guard kept a project enqueue failure from skipping the sibling spend writes, but logged it at debug only, so a dropped project charge was invisible on a default log level. Log it through spend_log_error inside the helper and re-raise, the way the org and agent helpers already do.
This commit is contained in:
parent
e4778cd2d1
commit
89289d4f77
2 changed files with 36 additions and 19 deletions
|
|
@ -988,13 +988,23 @@ class DBSpendUpdateWriter:
|
|||
) -> None:
|
||||
if project_id is None or prisma_client is None:
|
||||
return
|
||||
await self.spend_update_queue.add_update(
|
||||
update=SpendUpdateQueueItem(
|
||||
entity_type=Litellm_EntityType.PROJECT,
|
||||
entity_id=project_id,
|
||||
response_cost=response_cost,
|
||||
try:
|
||||
await self.spend_update_queue.add_update(
|
||||
update=SpendUpdateQueueItem(
|
||||
entity_type=Litellm_EntityType.PROJECT,
|
||||
entity_id=project_id,
|
||||
response_cost=response_cost,
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
spend_log_error(
|
||||
"Spend tracking - failed to enqueue project spend update. project_id=%s, response_cost=%s - %s",
|
||||
project_id,
|
||||
response_cost,
|
||||
str(e),
|
||||
exc=e,
|
||||
)
|
||||
raise e
|
||||
|
||||
async def _update_agent_db(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import asyncio
|
||||
import copy
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ import pytest
|
|||
from redis.exceptions import DataError
|
||||
|
||||
import litellm
|
||||
from litellm._logging import verbose_proxy_logger
|
||||
from litellm.proxy._types import Litellm_EntityType, SpendUpdateQueueItem
|
||||
from litellm.proxy.db.db_spend_update_writer import DBSpendUpdateWriter
|
||||
from litellm.proxy.db.db_transaction_queue.spend_update_queue import SpendUpdateQueue
|
||||
|
|
@ -1177,7 +1179,9 @@ async def test_batch_database_updates_without_project_id_touches_no_project_row(
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_failed_project_enqueue_does_not_drop_the_rest_of_the_batch():
|
||||
async def test_failed_project_enqueue_is_reported_and_does_not_drop_the_rest_of_the_batch(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
):
|
||||
class _ProjectRejectingQueue(SpendUpdateQueue):
|
||||
async def add_update(self, update: SpendUpdateQueueItem):
|
||||
if update.get("entity_type") is Litellm_EntityType.PROJECT:
|
||||
|
|
@ -1187,18 +1191,21 @@ async def test_failed_project_enqueue_does_not_drop_the_rest_of_the_batch():
|
|||
db_writer: Final = DBSpendUpdateWriter()
|
||||
db_writer.spend_update_queue = _ProjectRejectingQueue()
|
||||
|
||||
await db_writer._batch_database_updates(
|
||||
response_cost=0.25,
|
||||
user_id="u1",
|
||||
hashed_token="t1",
|
||||
team_id="team-1",
|
||||
org_id="org-1",
|
||||
end_user_id=None,
|
||||
prisma_client=MagicMock(),
|
||||
litellm_proxy_budget_name=None,
|
||||
payload={"request_id": "req-1", "model": "gpt-4o-mini", "spend": 0.25, "request_tags": ["tag-1"]},
|
||||
project_id="proj-1",
|
||||
)
|
||||
with caplog.at_level(logging.ERROR, logger=verbose_proxy_logger.name):
|
||||
await db_writer._batch_database_updates(
|
||||
response_cost=0.25,
|
||||
user_id="u1",
|
||||
hashed_token="t1",
|
||||
team_id="team-1",
|
||||
org_id="org-1",
|
||||
end_user_id=None,
|
||||
prisma_client=MagicMock(),
|
||||
litellm_proxy_budget_name=None,
|
||||
payload={"request_id": "req-1", "model": "gpt-4o-mini", "spend": 0.25, "request_tags": ["tag-1"]},
|
||||
project_id="proj-1",
|
||||
)
|
||||
|
||||
assert any("proj-1" in record.getMessage() for record in caplog.records if record.levelno >= logging.ERROR)
|
||||
|
||||
transactions: Final = await db_writer.spend_update_queue.flush_and_get_aggregated_db_spend_update_transactions()
|
||||
assert transactions["project_list_transactions"] == {}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue