diff --git a/docs/my-website/docs/proxy/logging.md b/docs/my-website/docs/proxy/logging.md index c4098bf75..a6868d400 100644 --- a/docs/my-website/docs/proxy/logging.md +++ b/docs/my-website/docs/proxy/logging.md @@ -278,6 +278,42 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \ }' ``` + +### LiteLLM-specific Tags on Langfuse - `cache_hit`, `cache_key` + +Use this if you want to control which LiteLLM-specific fields are logged as tags by the LiteLLM proxy. By default LiteLLM Proxy logs no LiteLLM-specific fields + +| LiteLLM specific field | Description | Example Value | +|------------------------|-------------------------------------------------------|------------------------------------------------| +| `cache_hit` | Indicates whether a cache hit occured (True) or not (False) | `true`, `false` | +| `cache_key` | The Cache key used for this request | `d2b758c****`| +| `proxy_base_url` | The base URL for the proxy server, the value of env var `PROXY_BASE_URL` on your server | `https://proxy.example.com`| +| `user_api_key_alias` | An alias for the LiteLLM Virtual Key.| `prod-app1` | +| `user_api_key_user_id` | The unique ID associated with a user's API key. | `user_123`, `user_456` | +| `user_api_key_user_email` | The email associated with a user's API key. | `user@example.com`, `admin@example.com` | +| `user_api_key_team_alias` | An alias for a team associated with an API key. | `team_alpha`, `dev_team` | + + +**Usage** + +Specify `langfuse_default_tags` to control what litellm fields get logged on Langfuse + +Example config.yaml +```yaml +model_list: + - model_name: gpt-4 + litellm_params: + model: openai/fake + api_key: fake-key + api_base: https://exampleopenaiendpoint-production.up.railway.app/ + +litellm_settings: + success_callback: ["langfuse"] + + # 👇 Key Change + langfuse_default_tags: ["cache_hit", "cache_key", "proxy_base_url", "user_api_key_alias", "user_api_key_user_id", "user_api_key_user_email", "user_api_key_team_alias", "semantic-similarity", "proxy_base_url"] +``` + ### 🔧 Debugging - Viewing RAW CURL sent from LiteLLM to provider Use this when you want to view the RAW curl request sent from LiteLLM to the LLM API diff --git a/litellm/__init__.py b/litellm/__init__.py index 5429e3cfc..1c831f012 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -53,18 +53,7 @@ _known_custom_logger_compatible_callbacks: List = list( get_args(_custom_logger_compatible_callbacks_literal) ) callbacks: List[Union[Callable, _custom_logger_compatible_callbacks_literal]] = [] -_langfuse_default_tags: Optional[ - List[ - Literal[ - "user_api_key_alias", - "user_api_key_user_id", - "user_api_key_user_email", - "user_api_key_team_alias", - "semantic-similarity", - "proxy_base_url", - ] - ] -] = None +langfuse_default_tags: Optional[List[str]] = None _async_input_callback: List[Callable] = ( [] ) # internal variable - async custom callbacks are routed here. diff --git a/litellm/integrations/braintrust_logging.py b/litellm/integrations/braintrust_logging.py index e8ef692da..08676e968 100644 --- a/litellm/integrations/braintrust_logging.py +++ b/litellm/integrations/braintrust_logging.py @@ -181,9 +181,9 @@ class BraintrustLogger(CustomLogger): # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy if ( - litellm._langfuse_default_tags is not None - and isinstance(litellm._langfuse_default_tags, list) - and key in litellm._langfuse_default_tags + litellm.langfuse_default_tags is not None + and isinstance(litellm.langfuse_default_tags, list) + and key in litellm.langfuse_default_tags ): tags.append(f"{key}:{value}") @@ -307,9 +307,9 @@ class BraintrustLogger(CustomLogger): # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy if ( - litellm._langfuse_default_tags is not None - and isinstance(litellm._langfuse_default_tags, list) - and key in litellm._langfuse_default_tags + litellm.langfuse_default_tags is not None + and isinstance(litellm.langfuse_default_tags, list) + and key in litellm.langfuse_default_tags ): tags.append(f"{key}:{value}") diff --git a/litellm/integrations/langfuse.py b/litellm/integrations/langfuse.py index df4be3a5b..864fb34e2 100644 --- a/litellm/integrations/langfuse.py +++ b/litellm/integrations/langfuse.py @@ -366,12 +366,11 @@ class LangFuseLogger: clean_metadata = {} if isinstance(metadata, dict): for key, value in metadata.items(): - # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy if ( - litellm._langfuse_default_tags is not None - and isinstance(litellm._langfuse_default_tags, list) - and key in litellm._langfuse_default_tags + litellm.langfuse_default_tags is not None + and isinstance(litellm.langfuse_default_tags, list) + and key in litellm.langfuse_default_tags ): tags.append(f"{key}:{value}") @@ -386,6 +385,11 @@ class LangFuseLogger: else: clean_metadata[key] = value + # Add default langfuse tags + tags = self.add_default_langfuse_tags( + tags=tags, kwargs=kwargs, metadata=metadata + ) + session_id = clean_metadata.pop("session_id", None) trace_name = clean_metadata.pop("trace_name", None) trace_id = clean_metadata.pop("trace_id", litellm_call_id) @@ -468,9 +472,9 @@ class LangFuseLogger: clean_metadata["litellm_response_cost"] = cost if ( - litellm._langfuse_default_tags is not None - and isinstance(litellm._langfuse_default_tags, list) - and "proxy_base_url" in litellm._langfuse_default_tags + litellm.langfuse_default_tags is not None + and isinstance(litellm.langfuse_default_tags, list) + and "proxy_base_url" in litellm.langfuse_default_tags ): proxy_base_url = os.environ.get("PROXY_BASE_URL", None) if proxy_base_url is not None: @@ -583,6 +587,27 @@ class LangFuseLogger: verbose_logger.error(f"Langfuse Layer Error - {traceback.format_exc()}") return None, None + def add_default_langfuse_tags(self, tags, kwargs, metadata): + """ + Helper function to add litellm default langfuse tags + + - Special LiteLLM tags: + - cache_hit + - cache_key + + """ + if litellm.langfuse_default_tags is not None and isinstance( + litellm.langfuse_default_tags, list + ): + if "cache_hit" in litellm.langfuse_default_tags: + _cache_hit_value = kwargs.get("cache_hit", False) + tags.append(f"cache_hit:{_cache_hit_value}") + if "cache_key" in litellm.langfuse_default_tags: + _hidden_params = metadata.get("hidden_params", {}) or {} + _cache_key = _hidden_params.get("cache_key", None) + tags.append(f"cache_key:{_cache_key}") + return tags + def _add_prompt_to_generation_params( generation_params: dict, clean_metadata: dict diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index a6b23a389..660c27f24 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -40,4 +40,6 @@ general_settings: litellm_settings: fallbacks: [{"gemini-1.5-pro-001": ["gpt-4o"]}] success_callback: ["langfuse", "prometheus"] + langfuse_default_tags: ["cache_hit", "cache_key", "proxy_base_url", "user_api_key_alias", "user_api_key_user_id", "user_api_key_user_email", "user_api_key_team_alias", "semantic-similarity", "proxy_base_url"] failure_callback: ["prometheus"] + cache: True