forked from phoenix/litellm-mirror
fix(litellm_logging.py): fix lago callback logic
This commit is contained in:
parent
cc066e019a
commit
2623bb260f
8 changed files with 112 additions and 102 deletions
|
@ -1,13 +1,19 @@
|
||||||
# What is this?
|
# What is this?
|
||||||
## On Success events log cost to Lago - https://github.com/BerriAI/litellm/issues/3639
|
## On Success events log cost to Lago - https://github.com/BerriAI/litellm/issues/3639
|
||||||
|
|
||||||
import dotenv, os, json
|
import json
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
import uuid
|
||||||
|
from typing import Literal, Optional
|
||||||
|
|
||||||
|
import dotenv
|
||||||
|
import httpx
|
||||||
|
|
||||||
import litellm
|
import litellm
|
||||||
import traceback, httpx
|
from litellm import verbose_logger
|
||||||
from litellm.integrations.custom_logger import CustomLogger
|
from litellm.integrations.custom_logger import CustomLogger
|
||||||
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
|
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
|
||||||
import uuid
|
|
||||||
from typing import Optional, Literal
|
|
||||||
|
|
||||||
|
|
||||||
def get_utc_datetime():
|
def get_utc_datetime():
|
||||||
|
@ -143,6 +149,7 @@ class LagoLogger(CustomLogger):
|
||||||
|
|
||||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||||
try:
|
try:
|
||||||
|
verbose_logger.debug("ENTERS LAGO CALLBACK")
|
||||||
_url = os.getenv("LAGO_API_BASE")
|
_url = os.getenv("LAGO_API_BASE")
|
||||||
assert _url is not None and isinstance(
|
assert _url is not None and isinstance(
|
||||||
_url, str
|
_url, str
|
||||||
|
|
|
@ -1,74 +1,76 @@
|
||||||
# What is this?
|
# What is this?
|
||||||
## Common Utility file for Logging handler
|
## Common Utility file for Logging handler
|
||||||
# Logging function -> log the exact model details + what's being sent | Non-Blocking
|
# Logging function -> log the exact model details + what's being sent | Non-Blocking
|
||||||
from litellm.types.utils import CallTypes
|
import copy
|
||||||
from typing import Optional
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import uuid
|
||||||
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
import litellm
|
||||||
from litellm import (
|
from litellm import (
|
||||||
verbose_logger,
|
|
||||||
json_logs,
|
json_logs,
|
||||||
log_raw_request_response,
|
log_raw_request_response,
|
||||||
turn_off_message_logging,
|
turn_off_message_logging,
|
||||||
|
verbose_logger,
|
||||||
)
|
)
|
||||||
import traceback
|
|
||||||
import litellm
|
|
||||||
import copy
|
|
||||||
import sys
|
|
||||||
import uuid
|
|
||||||
import os
|
|
||||||
from litellm.integrations.custom_logger import CustomLogger
|
from litellm.integrations.custom_logger import CustomLogger
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from litellm.litellm_core_utils.redact_messages import (
|
from litellm.litellm_core_utils.redact_messages import (
|
||||||
redact_message_input_output_from_logging,
|
redact_message_input_output_from_logging,
|
||||||
)
|
)
|
||||||
from litellm.utils import (
|
|
||||||
_get_base_model_from_metadata,
|
|
||||||
supabaseClient,
|
|
||||||
liteDebuggerClient,
|
|
||||||
promptLayerLogger,
|
|
||||||
weightsBiasesLogger,
|
|
||||||
langsmithLogger,
|
|
||||||
logfireLogger,
|
|
||||||
capture_exception,
|
|
||||||
add_breadcrumb,
|
|
||||||
lunaryLogger,
|
|
||||||
prometheusLogger,
|
|
||||||
print_verbose,
|
|
||||||
customLogger,
|
|
||||||
prompt_token_calculator,
|
|
||||||
)
|
|
||||||
from litellm.types.utils import (
|
from litellm.types.utils import (
|
||||||
ModelResponse,
|
CallTypes,
|
||||||
EmbeddingResponse,
|
EmbeddingResponse,
|
||||||
ImageResponse,
|
ImageResponse,
|
||||||
TranscriptionResponse,
|
ModelResponse,
|
||||||
TextCompletionResponse,
|
TextCompletionResponse,
|
||||||
|
TranscriptionResponse,
|
||||||
)
|
)
|
||||||
import subprocess
|
from litellm.utils import (
|
||||||
from ..integrations.traceloop import TraceloopLogger
|
_get_base_model_from_metadata,
|
||||||
from ..integrations.athina import AthinaLogger
|
add_breadcrumb,
|
||||||
from ..integrations.helicone import HeliconeLogger
|
capture_exception,
|
||||||
|
customLogger,
|
||||||
|
langsmithLogger,
|
||||||
|
liteDebuggerClient,
|
||||||
|
logfireLogger,
|
||||||
|
lunaryLogger,
|
||||||
|
print_verbose,
|
||||||
|
prometheusLogger,
|
||||||
|
prompt_token_calculator,
|
||||||
|
promptLayerLogger,
|
||||||
|
supabaseClient,
|
||||||
|
weightsBiasesLogger,
|
||||||
|
)
|
||||||
|
|
||||||
from ..integrations.aispend import AISpendLogger
|
from ..integrations.aispend import AISpendLogger
|
||||||
|
from ..integrations.athina import AthinaLogger
|
||||||
from ..integrations.berrispend import BerriSpendLogger
|
from ..integrations.berrispend import BerriSpendLogger
|
||||||
from ..integrations.supabase import Supabase
|
from ..integrations.clickhouse import ClickhouseLogger
|
||||||
from ..integrations.lunary import LunaryLogger
|
|
||||||
from ..integrations.prompt_layer import PromptLayerLogger
|
|
||||||
from ..integrations.langsmith import LangsmithLogger
|
|
||||||
from ..integrations.logfire_logger import LogfireLogger, LogfireLevel
|
|
||||||
from ..integrations.weights_biases import WeightsBiasesLogger
|
|
||||||
from ..integrations.custom_logger import CustomLogger
|
from ..integrations.custom_logger import CustomLogger
|
||||||
from ..integrations.langfuse import LangFuseLogger
|
|
||||||
from ..integrations.openmeter import OpenMeterLogger
|
|
||||||
from ..integrations.lago import LagoLogger
|
|
||||||
from ..integrations.datadog import DataDogLogger
|
from ..integrations.datadog import DataDogLogger
|
||||||
|
from ..integrations.dynamodb import DyanmoDBLogger
|
||||||
|
from ..integrations.greenscale import GreenscaleLogger
|
||||||
|
from ..integrations.helicone import HeliconeLogger
|
||||||
|
from ..integrations.lago import LagoLogger
|
||||||
|
from ..integrations.langfuse import LangFuseLogger
|
||||||
|
from ..integrations.langsmith import LangsmithLogger
|
||||||
|
from ..integrations.litedebugger import LiteDebugger
|
||||||
|
from ..integrations.logfire_logger import LogfireLevel, LogfireLogger
|
||||||
|
from ..integrations.lunary import LunaryLogger
|
||||||
|
from ..integrations.openmeter import OpenMeterLogger
|
||||||
from ..integrations.prometheus import PrometheusLogger
|
from ..integrations.prometheus import PrometheusLogger
|
||||||
from ..integrations.prometheus_services import PrometheusServicesLogger
|
from ..integrations.prometheus_services import PrometheusServicesLogger
|
||||||
from ..integrations.dynamodb import DyanmoDBLogger
|
from ..integrations.prompt_layer import PromptLayerLogger
|
||||||
from ..integrations.s3 import S3Logger
|
from ..integrations.s3 import S3Logger
|
||||||
from ..integrations.clickhouse import ClickhouseLogger
|
from ..integrations.supabase import Supabase
|
||||||
from ..integrations.greenscale import GreenscaleLogger
|
from ..integrations.traceloop import TraceloopLogger
|
||||||
from ..integrations.litedebugger import LiteDebugger
|
from ..integrations.weights_biases import WeightsBiasesLogger
|
||||||
|
|
||||||
|
|
||||||
class Logging:
|
class Logging:
|
||||||
|
@ -1778,3 +1780,12 @@ def set_callbacks(callback_list, function_id=None):
|
||||||
customLogger = CustomLogger()
|
customLogger = CustomLogger()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
def _init_custom_logger_compatible_class(
|
||||||
|
logging_integration: litellm._custom_logger_compatible_callbacks_literal,
|
||||||
|
) -> Callable:
|
||||||
|
if logging_integration == "lago":
|
||||||
|
return LagoLogger() # type: ignore
|
||||||
|
elif logging_integration == "openmeter":
|
||||||
|
return OpenMeterLogger() # type: ignore
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -75,6 +75,7 @@ router_settings:
|
||||||
enable_pre_call_checks: true
|
enable_pre_call_checks: true
|
||||||
|
|
||||||
litellm_settings:
|
litellm_settings:
|
||||||
|
callbacks: ["lago"]
|
||||||
success_callback: ["langfuse"]
|
success_callback: ["langfuse"]
|
||||||
failure_callback: ["langfuse"]
|
failure_callback: ["langfuse"]
|
||||||
cache: true
|
cache: true
|
||||||
|
|
|
@ -1,56 +1,53 @@
|
||||||
from typing import Optional, List, Any, Literal, Union, TYPE_CHECKING, Tuple
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import hashlib
|
|
||||||
import importlib
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import copy
|
import copy
|
||||||
|
import hashlib
|
||||||
|
import importlib
|
||||||
import json
|
import json
|
||||||
import httpx
|
import os
|
||||||
|
import re
|
||||||
|
import smtplib
|
||||||
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import litellm
|
|
||||||
import backoff
|
|
||||||
import traceback
|
import traceback
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from functools import wraps
|
||||||
|
from typing import TYPE_CHECKING, Any, List, Literal, Optional, Tuple, Union
|
||||||
|
|
||||||
|
import backoff
|
||||||
|
import httpx
|
||||||
|
from fastapi import HTTPException, Request, status
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from typing_extensions import overload
|
||||||
|
|
||||||
|
import litellm
|
||||||
import litellm.litellm_core_utils
|
import litellm.litellm_core_utils
|
||||||
import litellm.litellm_core_utils.litellm_logging
|
import litellm.litellm_core_utils.litellm_logging
|
||||||
|
from litellm import EmbeddingResponse, ImageResponse, ModelResponse
|
||||||
|
from litellm._logging import verbose_proxy_logger
|
||||||
|
from litellm._service_logger import ServiceLogging, ServiceTypes
|
||||||
|
from litellm.caching import DualCache, RedisCache
|
||||||
|
from litellm.exceptions import RejectedRequestError
|
||||||
|
from litellm.integrations.custom_logger import CustomLogger
|
||||||
|
from litellm.integrations.slack_alerting import SlackAlerting
|
||||||
|
from litellm.llms.custom_httpx.httpx_handler import HTTPHandler
|
||||||
from litellm.proxy._types import (
|
from litellm.proxy._types import (
|
||||||
UserAPIKeyAuth,
|
AlertType,
|
||||||
|
CallInfo,
|
||||||
DynamoDBArgs,
|
DynamoDBArgs,
|
||||||
LiteLLM_VerificationTokenView,
|
LiteLLM_VerificationTokenView,
|
||||||
CallInfo,
|
|
||||||
AlertType,
|
|
||||||
ResetTeamBudgetRequest,
|
|
||||||
LitellmUserRoles,
|
LitellmUserRoles,
|
||||||
|
ResetTeamBudgetRequest,
|
||||||
SpendLogsMetadata,
|
SpendLogsMetadata,
|
||||||
SpendLogsPayload,
|
SpendLogsPayload,
|
||||||
|
UserAPIKeyAuth,
|
||||||
)
|
)
|
||||||
from litellm.caching import DualCache, RedisCache
|
from litellm.proxy.hooks.cache_control_check import _PROXY_CacheControlCheck
|
||||||
from litellm.llms.custom_httpx.httpx_handler import HTTPHandler
|
from litellm.proxy.hooks.max_budget_limiter import _PROXY_MaxBudgetLimiter
|
||||||
from litellm.proxy.hooks.parallel_request_limiter import (
|
from litellm.proxy.hooks.parallel_request_limiter import (
|
||||||
_PROXY_MaxParallelRequestsHandler,
|
_PROXY_MaxParallelRequestsHandler,
|
||||||
)
|
)
|
||||||
from litellm.exceptions import RejectedRequestError
|
|
||||||
from litellm._service_logger import ServiceLogging, ServiceTypes
|
|
||||||
from litellm import (
|
|
||||||
ModelResponse,
|
|
||||||
EmbeddingResponse,
|
|
||||||
ImageResponse,
|
|
||||||
)
|
|
||||||
from litellm.proxy.hooks.max_budget_limiter import _PROXY_MaxBudgetLimiter
|
|
||||||
from litellm.proxy.hooks.cache_control_check import _PROXY_CacheControlCheck
|
|
||||||
from litellm.integrations.custom_logger import CustomLogger
|
|
||||||
from litellm._logging import verbose_proxy_logger
|
|
||||||
from fastapi import HTTPException, status
|
|
||||||
import smtplib
|
|
||||||
import re
|
|
||||||
from email.mime.text import MIMEText
|
|
||||||
from email.mime.multipart import MIMEMultipart
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from litellm.integrations.slack_alerting import SlackAlerting
|
|
||||||
from typing_extensions import overload
|
|
||||||
from functools import wraps
|
|
||||||
from fastapi import Request
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from opentelemetry.trace import Span as _Span
|
from opentelemetry.trace import Span as _Span
|
||||||
|
@ -244,7 +241,9 @@ class ProxyLogging:
|
||||||
)
|
)
|
||||||
for callback in litellm.callbacks:
|
for callback in litellm.callbacks:
|
||||||
if isinstance(callback, str):
|
if isinstance(callback, str):
|
||||||
callback = litellm.utils._init_custom_logger_compatible_class(callback)
|
callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class(
|
||||||
|
callback
|
||||||
|
)
|
||||||
if callback not in litellm.input_callback:
|
if callback not in litellm.input_callback:
|
||||||
litellm.input_callback.append(callback)
|
litellm.input_callback.append(callback)
|
||||||
if callback not in litellm.success_callback:
|
if callback not in litellm.success_callback:
|
||||||
|
@ -1957,8 +1956,7 @@ async def send_email(receiver_email, subject, html):
|
||||||
sender_email,
|
sender_email,
|
||||||
"""
|
"""
|
||||||
## SERVER SETUP ##
|
## SERVER SETUP ##
|
||||||
from litellm.proxy.proxy_server import premium_user
|
from litellm.proxy.proxy_server import CommonProxyErrors, premium_user
|
||||||
from litellm.proxy.proxy_server import CommonProxyErrors
|
|
||||||
|
|
||||||
smtp_host = os.getenv("SMTP_HOST")
|
smtp_host = os.getenv("SMTP_HOST")
|
||||||
smtp_port = int(os.getenv("SMTP_PORT", "587")) # default to port 587
|
smtp_port = int(os.getenv("SMTP_PORT", "587")) # default to port 587
|
||||||
|
@ -2008,9 +2006,10 @@ def hash_token(token: str):
|
||||||
def get_logging_payload(
|
def get_logging_payload(
|
||||||
kwargs, response_obj, start_time, end_time, end_user_id: Optional[str]
|
kwargs, response_obj, start_time, end_time, end_user_id: Optional[str]
|
||||||
) -> SpendLogsPayload:
|
) -> SpendLogsPayload:
|
||||||
from litellm.proxy._types import LiteLLM_SpendLogs
|
|
||||||
from pydantic import Json
|
from pydantic import Json
|
||||||
|
|
||||||
|
from litellm.proxy._types import LiteLLM_SpendLogs
|
||||||
|
|
||||||
verbose_proxy_logger.debug(
|
verbose_proxy_logger.debug(
|
||||||
f"SpendTable: get_logging_payload - kwargs: {kwargs}\n\n"
|
f"SpendTable: get_logging_payload - kwargs: {kwargs}\n\n"
|
||||||
)
|
)
|
||||||
|
@ -2762,6 +2761,7 @@ def _is_valid_team_configs(team_id=None, team_config=None, request_data=None):
|
||||||
|
|
||||||
def encrypt_value(value: str, master_key: str):
|
def encrypt_value(value: str, master_key: str):
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
import nacl.secret
|
import nacl.secret
|
||||||
import nacl.utils
|
import nacl.utils
|
||||||
|
|
||||||
|
@ -2782,6 +2782,7 @@ def encrypt_value(value: str, master_key: str):
|
||||||
|
|
||||||
def decrypt_value(value: bytes, master_key: str) -> str:
|
def decrypt_value(value: bytes, master_key: str) -> str:
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
import nacl.secret
|
import nacl.secret
|
||||||
import nacl.utils
|
import nacl.utils
|
||||||
|
|
||||||
|
|
|
@ -327,15 +327,6 @@ class Rules:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _init_custom_logger_compatible_class(
|
|
||||||
logging_integration: litellm._custom_logger_compatible_callbacks_literal,
|
|
||||||
) -> Callable:
|
|
||||||
if logging_integration == "lago":
|
|
||||||
return LagoLogger() # type: ignore
|
|
||||||
elif logging_integration == "openmeter":
|
|
||||||
return OpenMeterLogger() # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
####### 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(
|
||||||
|
@ -353,7 +344,9 @@ def function_setup(
|
||||||
for callback in litellm.callbacks:
|
for callback in litellm.callbacks:
|
||||||
# check if callback is a string - e.g. "lago", "openmeter"
|
# check if callback is a string - e.g. "lago", "openmeter"
|
||||||
if isinstance(callback, str):
|
if isinstance(callback, str):
|
||||||
callback = _init_custom_logger_compatible_class(callback)
|
callback = litellm.litellm_core_utils.litellm_logging._init_custom_logger_compatible_class(
|
||||||
|
callback
|
||||||
|
)
|
||||||
if any(
|
if any(
|
||||||
isinstance(cb, type(callback))
|
isinstance(cb, type(callback))
|
||||||
for cb in litellm._async_success_callback
|
for cb in litellm._async_success_callback
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue