mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
(Clean up) - Allow switching off storing Error Logs in DB (#9084)
* fix - cleanup, dont store ErrorLogs in 2 tables * async_post_call_failure_hook * docs disable error logs * disable_error_logs
This commit is contained in:
parent
a7f6a95dd9
commit
73df319f4e
6 changed files with 23 additions and 180 deletions
|
|
@ -46,18 +46,17 @@ You can see the full DB Schema [here](https://github.com/BerriAI/litellm/blob/ma
|
|||
|
||||
| Table Name | Description | Row Insert Frequency |
|
||||
|------------|-------------|---------------------|
|
||||
| LiteLLM_SpendLogs | Detailed logs of all API requests. Records token usage, spend, and timing information. Tracks which models and keys were used. | **High - every LLM API request** |
|
||||
| LiteLLM_ErrorLogs | Captures failed requests and errors. Stores exception details and request information. Helps with debugging and monitoring. | **Medium - on errors only** |
|
||||
| LiteLLM_SpendLogs | Detailed logs of all API requests. Records token usage, spend, and timing information. Tracks which models and keys were used. | **High - every LLM API request - Success or Failure** |
|
||||
| LiteLLM_AuditLog | Tracks changes to system configuration. Records who made changes and what was modified. Maintains history of updates to teams, users, and models. | **Off by default**, **High - when enabled** |
|
||||
|
||||
## Disable `LiteLLM_SpendLogs` & `LiteLLM_ErrorLogs`
|
||||
## Disable `LiteLLM_SpendLogs`
|
||||
|
||||
You can disable spend_logs and error_logs by setting `disable_spend_logs` and `disable_error_logs` to `True` on the `general_settings` section of your proxy_config.yaml file.
|
||||
|
||||
```yaml
|
||||
general_settings:
|
||||
disable_spend_logs: True # Disable writing spend logs to DB
|
||||
disable_error_logs: True # Disable writing error logs to DB
|
||||
disable_error_logs: True # Only disable writing error logs to DB, regular spend logs will still be written unless `disable_spend_logs: True`
|
||||
```
|
||||
|
||||
### What is the impact of disabling these logs?
|
||||
|
|
|
|||
|
|
@ -107,9 +107,9 @@ general_settings:
|
|||
|
||||
By default, LiteLLM writes several types of logs to the database:
|
||||
- Every LLM API request to the `LiteLLM_SpendLogs` table
|
||||
- LLM Exceptions to the `LiteLLM_LogsErrors` table
|
||||
- LLM Exceptions to the `LiteLLM_SpendLogs` table
|
||||
|
||||
If you're not viewing these logs on the LiteLLM UI (most users use Prometheus for monitoring), you can disable them by setting the following flags to `True`:
|
||||
If you're not viewing these logs on the LiteLLM UI, you can disable them by setting the following flags to `True`:
|
||||
|
||||
```yaml
|
||||
general_settings:
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
"""
|
||||
Runs when LLM Exceptions occur on LiteLLM Proxy
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import litellm
|
||||
from litellm.proxy._types import LiteLLM_ErrorLogs
|
||||
|
||||
|
||||
async def _PROXY_failure_handler(
|
||||
kwargs, # kwargs to completion
|
||||
completion_response: litellm.ModelResponse, # response from completion
|
||||
start_time=None,
|
||||
end_time=None, # start/end time for completion
|
||||
):
|
||||
"""
|
||||
Async Failure Handler - runs when LLM Exceptions occur on LiteLLM Proxy.
|
||||
This function logs the errors to the Prisma DB
|
||||
|
||||
Can be disabled by setting the following on proxy_config.yaml:
|
||||
```yaml
|
||||
general_settings:
|
||||
disable_error_logs: True
|
||||
```
|
||||
|
||||
"""
|
||||
from litellm._logging import verbose_proxy_logger
|
||||
from litellm.proxy.proxy_server import general_settings, prisma_client
|
||||
|
||||
if general_settings.get("disable_error_logs") is True:
|
||||
return
|
||||
|
||||
if prisma_client is not None:
|
||||
verbose_proxy_logger.debug(
|
||||
"inside _PROXY_failure_handler kwargs=", extra=kwargs
|
||||
)
|
||||
|
||||
_exception = kwargs.get("exception")
|
||||
_exception_type = _exception.__class__.__name__
|
||||
_model = kwargs.get("model", None)
|
||||
|
||||
_optional_params = kwargs.get("optional_params", {})
|
||||
_optional_params = copy.deepcopy(_optional_params)
|
||||
|
||||
for k, v in _optional_params.items():
|
||||
v = str(v)
|
||||
v = v[:100]
|
||||
|
||||
_status_code = "500"
|
||||
try:
|
||||
_status_code = str(_exception.status_code)
|
||||
except Exception:
|
||||
# Don't let this fail logging the exception to the dB
|
||||
pass
|
||||
|
||||
_litellm_params = kwargs.get("litellm_params", {}) or {}
|
||||
_metadata = _litellm_params.get("metadata", {}) or {}
|
||||
_model_id = _metadata.get("model_info", {}).get("id", "")
|
||||
_model_group = _metadata.get("model_group", "")
|
||||
api_base = litellm.get_api_base(model=_model, optional_params=_litellm_params)
|
||||
_exception_string = str(_exception)
|
||||
|
||||
error_log = LiteLLM_ErrorLogs(
|
||||
request_id=str(uuid.uuid4()),
|
||||
model_group=_model_group,
|
||||
model_id=_model_id,
|
||||
litellm_model_name=kwargs.get("model"),
|
||||
request_kwargs=_optional_params,
|
||||
api_base=api_base,
|
||||
exception_type=_exception_type,
|
||||
status_code=_status_code,
|
||||
exception_string=_exception_string,
|
||||
startTime=kwargs.get("start_time"),
|
||||
endTime=kwargs.get("end_time"),
|
||||
)
|
||||
|
||||
error_log_dict = error_log.model_dump()
|
||||
error_log_dict["request_kwargs"] = json.dumps(error_log_dict["request_kwargs"])
|
||||
|
||||
await prisma_client.db.litellm_errorlogs.create(
|
||||
data=error_log_dict # type: ignore
|
||||
)
|
||||
|
||||
pass
|
||||
|
|
@ -34,6 +34,9 @@ class _ProxyDBLogger(CustomLogger):
|
|||
):
|
||||
from litellm.proxy.proxy_server import update_database
|
||||
|
||||
if _ProxyDBLogger._should_track_errors_in_db() is False:
|
||||
return
|
||||
|
||||
_metadata = dict(
|
||||
StandardLoggingUserAPIKeyMetadata(
|
||||
user_api_key_hash=user_api_key_dict.api_key,
|
||||
|
|
@ -202,6 +205,21 @@ class _ProxyDBLogger(CustomLogger):
|
|||
"Error in tracking cost callback - %s", str(e)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _should_track_errors_in_db():
|
||||
"""
|
||||
Returns True if errors should be tracked in the database
|
||||
|
||||
By default, errors are tracked in the database
|
||||
|
||||
If users want to disable error tracking, they can set the disable_error_logs flag in the general_settings
|
||||
"""
|
||||
from litellm.proxy.proxy_server import general_settings
|
||||
|
||||
if general_settings.get("disable_error_logs") is True:
|
||||
return False
|
||||
return
|
||||
|
||||
|
||||
def _should_track_cost_callback(
|
||||
user_api_key: Optional[str],
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ from litellm.proxy.hooks.model_max_budget_limiter import (
|
|||
from litellm.proxy.hooks.prompt_injection_detection import (
|
||||
_OPTIONAL_PromptInjectionDetection,
|
||||
)
|
||||
from litellm.proxy.hooks.proxy_failure_handler import _PROXY_failure_handler
|
||||
from litellm.proxy.hooks.proxy_track_cost_callback import _ProxyDBLogger
|
||||
from litellm.proxy.litellm_pre_call_utils import add_litellm_data_to_request
|
||||
from litellm.proxy.management_endpoints.budget_management_endpoints import (
|
||||
|
|
@ -942,15 +941,6 @@ def cost_tracking():
|
|||
litellm.logging_callback_manager.add_litellm_callback(_ProxyDBLogger())
|
||||
|
||||
|
||||
def error_tracking():
|
||||
global prisma_client
|
||||
if prisma_client is not None:
|
||||
if isinstance(litellm.failure_callback, list):
|
||||
verbose_proxy_logger.debug("setting litellm failure callback to track cost")
|
||||
if (_PROXY_failure_handler) not in litellm.failure_callback: # type: ignore
|
||||
litellm.logging_callback_manager.add_litellm_failure_callback(_PROXY_failure_handler) # type: ignore
|
||||
|
||||
|
||||
def _set_spend_logs_payload(
|
||||
payload: Union[dict, SpendLogsPayload],
|
||||
prisma_client: PrismaClient,
|
||||
|
|
@ -3150,9 +3140,6 @@ class ProxyStartupEvent:
|
|||
## COST TRACKING ##
|
||||
cost_tracking()
|
||||
|
||||
## Error Tracking ##
|
||||
error_tracking()
|
||||
|
||||
proxy_logging_obj.startup_event(
|
||||
llm_router=llm_router, redis_usage_cache=redis_usage_cache
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,43 +10,6 @@ sys.path.insert(0, os.path.abspath("../.."))
|
|||
import litellm
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disable_error_logs():
|
||||
"""
|
||||
Test that the error logs are not written to the database when disable_error_logs is True
|
||||
"""
|
||||
# Mock the necessary components
|
||||
mock_prisma_client = AsyncMock()
|
||||
mock_general_settings = {"disable_error_logs": True}
|
||||
|
||||
with patch(
|
||||
"litellm.proxy.proxy_server.general_settings", mock_general_settings
|
||||
), patch("litellm.proxy.proxy_server.prisma_client", mock_prisma_client):
|
||||
|
||||
# Create a test exception
|
||||
test_exception = Exception("Test error")
|
||||
test_kwargs = {
|
||||
"model": "gpt-4",
|
||||
"exception": test_exception,
|
||||
"optional_params": {},
|
||||
"litellm_params": {"metadata": {}},
|
||||
}
|
||||
|
||||
# Call the failure handler
|
||||
from litellm.proxy.proxy_server import _PROXY_failure_handler
|
||||
|
||||
await _PROXY_failure_handler(
|
||||
kwargs=test_kwargs,
|
||||
completion_response=None,
|
||||
start_time="2024-01-01",
|
||||
end_time="2024-01-01",
|
||||
)
|
||||
|
||||
# Verify prisma client was not called to create error logs
|
||||
if hasattr(mock_prisma_client, "db"):
|
||||
assert not mock_prisma_client.db.litellm_errorlogs.create.called
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disable_spend_logs():
|
||||
"""
|
||||
|
|
@ -72,40 +35,3 @@ async def test_disable_spend_logs():
|
|||
)
|
||||
# Verify no spend logs were added
|
||||
assert len(mock_prisma_client.spend_log_transactions) == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_enable_error_logs():
|
||||
"""
|
||||
Test that the error logs are written to the database when disable_error_logs is False
|
||||
"""
|
||||
# Mock the necessary components
|
||||
mock_prisma_client = AsyncMock()
|
||||
mock_general_settings = {"disable_error_logs": False}
|
||||
|
||||
with patch(
|
||||
"litellm.proxy.proxy_server.general_settings", mock_general_settings
|
||||
), patch("litellm.proxy.proxy_server.prisma_client", mock_prisma_client):
|
||||
|
||||
# Create a test exception
|
||||
test_exception = Exception("Test error")
|
||||
test_kwargs = {
|
||||
"model": "gpt-4",
|
||||
"exception": test_exception,
|
||||
"optional_params": {},
|
||||
"litellm_params": {"metadata": {}},
|
||||
}
|
||||
|
||||
# Call the failure handler
|
||||
from litellm.proxy.proxy_server import _PROXY_failure_handler
|
||||
|
||||
await _PROXY_failure_handler(
|
||||
kwargs=test_kwargs,
|
||||
completion_response=None,
|
||||
start_time="2024-01-01",
|
||||
end_time="2024-01-01",
|
||||
)
|
||||
|
||||
# Verify prisma client was called to create error logs
|
||||
if hasattr(mock_prisma_client, "db"):
|
||||
assert mock_prisma_client.db.litellm_errorlogs.create.called
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue