fix(proxy/utils.py): log rejected proxy requests to langfuse

This commit is contained in:
Krrish Dholakia 2024-04-25 19:26:27 -07:00
parent 86a3d24d75
commit 885de2e3c6
5 changed files with 57 additions and 12 deletions

View file

@ -84,6 +84,7 @@ class LangFuseLogger:
print_verbose( print_verbose(
f"Langfuse Logging - Enters logging function for model {kwargs}" f"Langfuse Logging - Enters logging function for model {kwargs}"
) )
litellm_params = kwargs.get("litellm_params", {}) litellm_params = kwargs.get("litellm_params", {})
metadata = ( metadata = (
litellm_params.get("metadata", {}) or {} litellm_params.get("metadata", {}) or {}
@ -373,7 +374,11 @@ class LangFuseLogger:
# just log `litellm-{call_type}` as the generation name # just log `litellm-{call_type}` as the generation name
generation_name = f"litellm-{kwargs.get('call_type', 'completion')}" generation_name = f"litellm-{kwargs.get('call_type', 'completion')}"
system_fingerprint = response_obj.get("system_fingerprint", None) if response_obj is not None and "system_fingerprint" in response_obj:
system_fingerprint = response_obj.get("system_fingerprint", None)
else:
system_fingerprint = None
if system_fingerprint is not None: if system_fingerprint is not None:
optional_params["system_fingerprint"] = system_fingerprint optional_params["system_fingerprint"] = system_fingerprint

View file

@ -3663,6 +3663,17 @@ async def chat_completion(
if data["model"] in litellm.model_alias_map: if data["model"] in litellm.model_alias_map:
data["model"] = litellm.model_alias_map[data["model"]] data["model"] = litellm.model_alias_map[data["model"]]
## LOGGING OBJECT ## - initialize logging object for logging success/failure events for call
data["litellm_call_id"] = str(uuid.uuid4())
logging_obj, data = litellm.utils.function_setup(
original_function="acompletion",
rules_obj=litellm.utils.Rules(),
start_time=litellm.utils.get_utc_datetime(),
**data,
)
data["litellm_logging_obj"] = logging_obj
### CALL HOOKS ### - modify incoming data before calling the model ### CALL HOOKS ### - modify incoming data before calling the model
data = await proxy_logging_obj.pre_call_hook( data = await proxy_logging_obj.pre_call_hook(
user_api_key_dict=user_api_key_dict, data=data, call_type="completion" user_api_key_dict=user_api_key_dict, data=data, call_type="completion"

View file

@ -1,6 +1,6 @@
from typing import Optional, List, Any, Literal, Union from typing import Optional, List, Any, Literal, Union
import os, subprocess, hashlib, importlib, asyncio, copy, json, aiohttp, httpx, time import os, subprocess, hashlib, importlib, asyncio, copy, json, aiohttp, httpx, time
import litellm, backoff import litellm, backoff, traceback
from litellm.proxy._types import ( from litellm.proxy._types import (
UserAPIKeyAuth, UserAPIKeyAuth,
DynamoDBArgs, DynamoDBArgs,
@ -199,6 +199,33 @@ class ProxyLogging:
print_verbose(f"final data being sent to {call_type} call: {data}") print_verbose(f"final data being sent to {call_type} call: {data}")
return data return data
except Exception as e: except Exception as e:
if "litellm_logging_obj" in data:
logging_obj: litellm.utils.Logging = data["litellm_logging_obj"]
## ASYNC FAILURE HANDLER ##
error_message = ""
if isinstance(e, HTTPException):
if isinstance(e.detail, str):
error_message = e.detail
elif isinstance(e.detail, dict):
error_message = json.dumps(e.detail)
else:
error_message = str(e)
else:
error_message = str(e)
error_raised = Exception(f"{error_message}")
await logging_obj.async_failure_handler(
exception=error_raised,
traceback_exception=traceback.format_exc(),
)
## SYNC FAILURE HANDLER ##
try:
logging_obj.failure_handler(
error_raised, traceback.format_exc()
) # DO NOT MAKE THREADED - router retry fallback relies on this!
except Exception as error_val:
pass
raise e raise e
async def during_call_hook( async def during_call_hook(

View file

@ -25,7 +25,7 @@ def test_empty_content():
pass pass
function_setup( function_setup(
original_function=completion, original_function="completion",
rules_obj=rules_obj, rules_obj=rules_obj,
start_time=datetime.now(), start_time=datetime.now(),
messages=[], messages=[],

View file

@ -2433,7 +2433,7 @@ class Rules:
####### CLIENT ################### ####### CLIENT ###################
# make it easy to log if completion/embedding runs succeeded or failed + see what happened | Non-Blocking # make it easy to log if completion/embedding runs succeeded or failed + see what happened | Non-Blocking
def function_setup( def function_setup(
original_function, rules_obj, start_time, *args, **kwargs original_function: str, rules_obj, start_time, *args, **kwargs
): # just run once to check if user wants to send their data anywhere - PostHog/Sentry/Slack/etc. ): # just run once to check if user wants to send their data anywhere - PostHog/Sentry/Slack/etc.
try: try:
global callback_list, add_breadcrumb, user_logger_fn, Logging global callback_list, add_breadcrumb, user_logger_fn, Logging
@ -2457,10 +2457,12 @@ def function_setup(
len(litellm.input_callback) > 0 len(litellm.input_callback) > 0
or len(litellm.success_callback) > 0 or len(litellm.success_callback) > 0
or len(litellm.failure_callback) > 0 or len(litellm.failure_callback) > 0
) and len(callback_list) == 0: ) and len(
callback_list # type: ignore
) == 0: # type: ignore
callback_list = list( callback_list = list(
set( set(
litellm.input_callback litellm.input_callback # type: ignore
+ litellm.success_callback + litellm.success_callback
+ litellm.failure_callback + litellm.failure_callback
) )
@ -2469,7 +2471,7 @@ def function_setup(
## ASYNC CALLBACKS ## ASYNC CALLBACKS
if len(litellm.input_callback) > 0: if len(litellm.input_callback) > 0:
removed_async_items = [] removed_async_items = []
for index, callback in enumerate(litellm.input_callback): for index, callback in enumerate(litellm.input_callback): # type: ignore
if inspect.iscoroutinefunction(callback): if inspect.iscoroutinefunction(callback):
litellm._async_input_callback.append(callback) litellm._async_input_callback.append(callback)
removed_async_items.append(index) removed_async_items.append(index)
@ -2480,7 +2482,7 @@ def function_setup(
if len(litellm.success_callback) > 0: if len(litellm.success_callback) > 0:
removed_async_items = [] removed_async_items = []
for index, callback in enumerate(litellm.success_callback): for index, callback in enumerate(litellm.success_callback): # type: ignore
if inspect.iscoroutinefunction(callback): if inspect.iscoroutinefunction(callback):
litellm._async_success_callback.append(callback) litellm._async_success_callback.append(callback)
removed_async_items.append(index) removed_async_items.append(index)
@ -2496,7 +2498,7 @@ def function_setup(
if len(litellm.failure_callback) > 0: if len(litellm.failure_callback) > 0:
removed_async_items = [] removed_async_items = []
for index, callback in enumerate(litellm.failure_callback): for index, callback in enumerate(litellm.failure_callback): # type: ignore
if inspect.iscoroutinefunction(callback): if inspect.iscoroutinefunction(callback):
litellm._async_failure_callback.append(callback) litellm._async_failure_callback.append(callback)
removed_async_items.append(index) removed_async_items.append(index)
@ -2539,7 +2541,7 @@ def function_setup(
user_logger_fn = kwargs["logger_fn"] user_logger_fn = kwargs["logger_fn"]
# INIT LOGGER - for user-specified integrations # INIT LOGGER - for user-specified integrations
model = args[0] if len(args) > 0 else kwargs.get("model", None) model = args[0] if len(args) > 0 else kwargs.get("model", None)
call_type = original_function.__name__ call_type = original_function
if ( if (
call_type == CallTypes.completion.value call_type == CallTypes.completion.value
or call_type == CallTypes.acompletion.value or call_type == CallTypes.acompletion.value
@ -2721,7 +2723,7 @@ def client(original_function):
try: try:
if logging_obj is None: if logging_obj is None:
logging_obj, kwargs = function_setup( logging_obj, kwargs = function_setup(
original_function, rules_obj, start_time, *args, **kwargs original_function.__name__, rules_obj, start_time, *args, **kwargs
) )
kwargs["litellm_logging_obj"] = logging_obj kwargs["litellm_logging_obj"] = logging_obj
@ -3030,7 +3032,7 @@ def client(original_function):
try: try:
if logging_obj is None: if logging_obj is None:
logging_obj, kwargs = function_setup( logging_obj, kwargs = function_setup(
original_function, rules_obj, start_time, *args, **kwargs original_function.__name__, rules_obj, start_time, *args, **kwargs
) )
kwargs["litellm_logging_obj"] = logging_obj kwargs["litellm_logging_obj"] = logging_obj