diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 55ad64b7e..c376437bb 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -8367,8 +8367,19 @@ async def health_services_endpoint( raise HTTPException( status_code=400, detail={"error": "Service must be specified."} ) + if service not in ["slack_budget_alerts", "langfuse"]: + raise HTTPException( + status_code=400, + detail={ + "error": f"Service must be in list. Service={service}. List={['slack_budget_alerts']}" + }, + ) + if service == "langfuse": - # run mock completion request + from litellm.integrations.langfuse import LangFuseLogger + + langfuse_logger = LangFuseLogger() + langfuse_logger.Langfuse.auth_check() _ = litellm.completion( model="openai/litellm-mock-response-model", messages=[{"role": "user", "content": "Hey, how's it going?"}], @@ -8380,14 +8391,6 @@ async def health_services_endpoint( "message": "Mock LLM request made - check langfuse.", } - if service not in ["slack_budget_alerts", "langfuse"]: - raise HTTPException( - status_code=400, - detail={ - "error": f"Service must be in list. Service={service}. List={['slack_budget_alerts']}" - }, - ) - if "slack" in general_settings.get("alerting", []): test_message = f"""\n🚨 `ProjectedLimitExceededError` 💸\n\n`Key Alias:` litellm-ui-test-alert \n`Expected Day of Error`: 28th March \n`Current Spend`: $100.00 \n`Projected Spend at end of month`: $1000.00 \n`Soft Limit`: $700""" await proxy_logging_obj.alerting_handler(message=test_message, level="Low") diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index d6f0e497e..b0e202ced 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -1172,6 +1172,42 @@ export const slackBudgetAlertsHealthCheck = async (accessToken: String) => { +export const serviceHealthCheck= async (accessToken: String, service: String) => { + try { + let url = proxyBaseUrl + ? `${proxyBaseUrl}/health/services?service=${service}` + : `/health/services?service=${service}`; + + console.log("Checking Slack Budget Alerts service health"); + + const response = await fetch(url, { + method: "GET", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + message.error(`Failed ${service} service health check ` + errorData); + // throw error with message + throw new Error(errorData); + } + + const data = await response.json(); + message.success(`Test request to ${service} made - check logs on ${service} dashboard!`); + // You can add additional logic here based on the response if needed + return data; + } catch (error) { + console.error("Failed to perform health check:", error); + throw error; + } +}; + + + + export const getCallbacksCall = async ( accessToken: String, userID: String, diff --git a/ui/litellm-dashboard/src/components/settings.tsx b/ui/litellm-dashboard/src/components/settings.tsx index 0f5b5396c..5439acf32 100644 --- a/ui/litellm-dashboard/src/components/settings.tsx +++ b/ui/litellm-dashboard/src/components/settings.tsx @@ -17,7 +17,7 @@ import { TextInput, Col, } from "@tremor/react"; -import { getCallbacksCall, setCallbacksCall } from "./networking"; +import { getCallbacksCall, setCallbacksCall, serviceHealthCheck } from "./networking"; import { Modal, Form, Input, Select, Button as Button2, message } from "antd"; import StaticGenerationSearchParamsBailoutProvider from "next/dist/client/components/static-generation-searchparams-bailout-provider"; @@ -177,7 +177,7 @@ const Settings: React.FC = ({ -