mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-25 10:44:24 +00:00
* remove unused imports * fix AmazonConverseConfig * fix test * fix import * ruff check fixes * test fixes * fix testing * fix imports
137 lines
4.5 KiB
Python
137 lines
4.5 KiB
Python
"""
|
|
Helper functions to query prometheus API
|
|
"""
|
|
|
|
import time
|
|
from datetime import datetime, timedelta
|
|
from typing import Optional
|
|
|
|
from litellm import get_secret
|
|
from litellm._logging import verbose_logger
|
|
from litellm.llms.custom_httpx.http_handler import (
|
|
get_async_httpx_client,
|
|
httpxSpecialProvider,
|
|
)
|
|
|
|
PROMETHEUS_URL: Optional[str] = get_secret("PROMETHEUS_URL") # type: ignore
|
|
PROMETHEUS_SELECTED_INSTANCE: Optional[str] = get_secret("PROMETHEUS_SELECTED_INSTANCE") # type: ignore
|
|
async_http_handler = get_async_httpx_client(
|
|
llm_provider=httpxSpecialProvider.LoggingCallback
|
|
)
|
|
|
|
|
|
async def get_metric_from_prometheus(
|
|
metric_name: str,
|
|
):
|
|
# Get the start of the current day in Unix timestamp
|
|
if PROMETHEUS_URL is None:
|
|
raise ValueError(
|
|
"PROMETHEUS_URL not set please set 'PROMETHEUS_URL=<>' in .env"
|
|
)
|
|
|
|
query = f"{metric_name}[24h]"
|
|
now = int(time.time())
|
|
response = await async_http_handler.get(
|
|
f"{PROMETHEUS_URL}/api/v1/query", params={"query": query, "time": now}
|
|
) # End of the day
|
|
_json_response = response.json()
|
|
verbose_logger.debug("json response from prometheus /query api %s", _json_response)
|
|
results = response.json()["data"]["result"]
|
|
return results
|
|
|
|
|
|
async def get_fallback_metric_from_prometheus():
|
|
"""
|
|
Gets fallback metrics from prometheus for the last 24 hours
|
|
"""
|
|
response_message = ""
|
|
relevant_metrics = [
|
|
"litellm_deployment_successful_fallbacks_total",
|
|
"litellm_deployment_failed_fallbacks_total",
|
|
]
|
|
for metric in relevant_metrics:
|
|
response_json = await get_metric_from_prometheus(
|
|
metric_name=metric,
|
|
)
|
|
|
|
if response_json:
|
|
verbose_logger.debug("response json %s", response_json)
|
|
for result in response_json:
|
|
verbose_logger.debug("result= %s", result)
|
|
metric = result["metric"]
|
|
metric_values = result["values"]
|
|
most_recent_value = metric_values[0]
|
|
|
|
if PROMETHEUS_SELECTED_INSTANCE is not None:
|
|
if metric.get("instance") != PROMETHEUS_SELECTED_INSTANCE:
|
|
continue
|
|
|
|
value = int(float(most_recent_value[1])) # Convert value to integer
|
|
primary_model = metric.get("primary_model", "Unknown")
|
|
fallback_model = metric.get("fallback_model", "Unknown")
|
|
response_message += f"`{value} successful fallback requests` with primary model=`{primary_model}` -> fallback model=`{fallback_model}`"
|
|
response_message += "\n"
|
|
verbose_logger.debug("response message %s", response_message)
|
|
return response_message
|
|
|
|
|
|
def is_prometheus_connected() -> bool:
|
|
if PROMETHEUS_URL is not None:
|
|
return True
|
|
return False
|
|
|
|
|
|
async def get_daily_spend_from_prometheus(api_key: Optional[str]):
|
|
"""
|
|
Expected Response Format:
|
|
[
|
|
{
|
|
"date": "2024-08-18T00:00:00+00:00",
|
|
"spend": 1.001818099998933
|
|
},
|
|
...]
|
|
"""
|
|
if PROMETHEUS_URL is None:
|
|
raise ValueError(
|
|
"PROMETHEUS_URL not set please set 'PROMETHEUS_URL=<>' in .env"
|
|
)
|
|
|
|
# Calculate the start and end dates for the last 30 days
|
|
end_date = datetime.utcnow()
|
|
start_date = end_date - timedelta(days=30)
|
|
|
|
# Format dates as ISO 8601 strings with UTC offset
|
|
start_str = start_date.isoformat() + "+00:00"
|
|
end_str = end_date.isoformat() + "+00:00"
|
|
|
|
url = f"{PROMETHEUS_URL}/api/v1/query_range"
|
|
|
|
if api_key is None:
|
|
query = "sum(delta(litellm_spend_metric_total[1d]))"
|
|
else:
|
|
query = (
|
|
f'sum(delta(litellm_spend_metric_total{{hashed_api_key="{api_key}"}}[1d]))'
|
|
)
|
|
|
|
params = {
|
|
"query": query,
|
|
"start": start_str,
|
|
"end": end_str,
|
|
"step": "86400", # Step size of 1 day in seconds
|
|
}
|
|
|
|
response = await async_http_handler.get(url, params=params)
|
|
_json_response = response.json()
|
|
verbose_logger.debug("json response from prometheus /query api %s", _json_response)
|
|
results = response.json()["data"]["result"]
|
|
formatted_results = []
|
|
|
|
for result in results:
|
|
metric_data = result["values"]
|
|
for timestamp, value in metric_data:
|
|
# Convert timestamp to ISO 8601 string with UTC offset
|
|
date = datetime.fromtimestamp(float(timestamp)).isoformat() + "+00:00"
|
|
spend = float(value)
|
|
formatted_results.append({"date": date, "spend": spend})
|
|
|
|
return formatted_results
|