From 1b732c485dc5e6e40ea7e6781149334a229c0f51 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 7 Sep 2024 11:42:16 -0700 Subject: [PATCH 1/3] fix slack alerting allow setting custom spend report frequency --- litellm/integrations/slack_alerting.py | 59 ++++++++++++++------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 20accb1b467..eab3f9c3881 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -1688,53 +1688,56 @@ Model Info: await asyncio.sleep(interval) return - async def send_weekly_spend_report(self): - """ """ + async def send_weekly_spend_report(self, time_range: str = "7d"): + """ + Send a spend report for a configurable time range. + + :param time_range: A string specifying the time range, e.g., "1d", "7d", "30d" + """ try: from litellm.proxy.spend_tracking.spend_management_endpoints import ( _get_spend_report_for_time_range, ) - todays_date = datetime.datetime.now().date() - week_before = todays_date - datetime.timedelta(days=7) + # Parse the time range + days = int(time_range[:-1]) + if time_range[-1].lower() != "d": + raise ValueError("Time range must be specified in days, e.g., '7d'") - weekly_spend_per_team, weekly_spend_per_tag = ( - await _get_spend_report_for_time_range( - start_date=week_before.strftime("%Y-%m-%d"), - end_date=todays_date.strftime("%Y-%m-%d"), - ) + todays_date = datetime.datetime.now().date() + start_date = todays_date - datetime.timedelta(days=days) + + spend_per_team, spend_per_tag = await _get_spend_report_for_time_range( + start_date=start_date.strftime("%Y-%m-%d"), + end_date=todays_date.strftime("%Y-%m-%d"), ) - _weekly_spend_message = f"*💸 Weekly Spend Report for `{week_before.strftime('%m-%d-%Y')} - {todays_date.strftime('%m-%d-%Y')}` *\n" + _spend_message = f"*💸 Spend Report for `{start_date.strftime('%m-%d-%Y')} - {todays_date.strftime('%m-%d-%Y')}` ({days} days)*\n" - if weekly_spend_per_team is not None: - _weekly_spend_message += "\n*Team Spend Report:*\n" - for spend in weekly_spend_per_team: - _team_spend = spend["total_spend"] - _team_spend = float(_team_spend) - # round to 4 decimal places - _team_spend = round(_team_spend, 4) - _weekly_spend_message += ( + if spend_per_team is not None: + _spend_message += "\n*Team Spend Report:*\n" + for spend in spend_per_team: + _team_spend = round(float(spend["total_spend"]), 4) + _spend_message += ( f"Team: `{spend['team_alias']}` | Spend: `${_team_spend}`\n" ) - if weekly_spend_per_tag is not None: - _weekly_spend_message += "\n*Tag Spend Report:*\n" - for spend in weekly_spend_per_tag: - _tag_spend = spend["total_spend"] - _tag_spend = float(_tag_spend) - # round to 4 decimal places - _tag_spend = round(_tag_spend, 4) - _weekly_spend_message += f"Tag: `{spend['individual_request_tag']}` | Spend: `${_tag_spend}`\n" + if spend_per_tag is not None: + _spend_message += "\n*Tag Spend Report:*\n" + for spend in spend_per_tag: + _tag_spend = round(float(spend["total_spend"]), 4) + _spend_message += f"Tag: `{spend['individual_request_tag']}` | Spend: `${_tag_spend}`\n" await self.send_alert( - message=_weekly_spend_message, + message=_spend_message, level="Low", alert_type="spend_reports", alerting_metadata={}, ) + except ValueError as ve: + verbose_proxy_logger.error(f"Invalid time range format: {ve}") except Exception as e: - verbose_proxy_logger.error("Error sending weekly spend report %s", e) + verbose_proxy_logger.error(f"Error sending spend report: {e}") async def send_monthly_spend_report(self): """ """ From 805e4c5754488f39dd3455b57b9a4b233668371c Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 7 Sep 2024 11:44:58 -0700 Subject: [PATCH 2/3] add spend_report_frequency as a general setting --- litellm/proxy/proxy_server.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index f4f3a1e586d..b6ebbe1df84 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2961,11 +2961,26 @@ async def startup_event(): and prisma_client is not None ): print("Alerting: Initializing Weekly/Monthly Spend Reports") # noqa - ### Schedule weekly/monhtly spend reports ### + ### Schedule weekly/monthly spend reports ### + ### Schedule spend reports ### + spend_report_frequency: str = ( + general_settings.get("spend_report_frequency", "7d") or "7d" + ) + + # Parse the frequency + days = int(spend_report_frequency[:-1]) + if spend_report_frequency[-1].lower() != "d": + raise ValueError( + "spend_report_frequency must be specified in days, e.g., '1d', '7d'" + ) + scheduler.add_job( proxy_logging_obj.slack_alerting_instance.send_weekly_spend_report, - "cron", - day_of_week="mon", + "interval", + days=days, + next_run_time=datetime.now() + + timedelta(seconds=10), # Start 10 seconds from now + args=[spend_report_frequency], ) scheduler.add_job( From ecb774c3e8cf72a64c6631726430212bfcb428b5 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 7 Sep 2024 11:54:33 -0700 Subject: [PATCH 3/3] add doc on spend report frequency --- docs/my-website/docs/proxy/alerting.md | 21 ++++++++++++--------- litellm/proxy/proxy_config.yaml | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/my-website/docs/proxy/alerting.md b/docs/my-website/docs/proxy/alerting.md index 257f5af81fe..15bd518edfe 100644 --- a/docs/my-website/docs/proxy/alerting.md +++ b/docs/my-website/docs/proxy/alerting.md @@ -45,6 +45,7 @@ export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/<>/<>/<>" general_settings: alerting: ["slack"] alerting_threshold: 300 # sends alerts if requests hang for 5min+ and responses take 5min+ + spend_report_frequency: "1d" # [Optional] set as 1d, 2d, 30d .... Specifiy how often you want a Spend Report to be sent ``` Start proxy @@ -61,7 +62,9 @@ curl -X GET 'http://0.0.0.0:4000/health/services?service=slack' \ -H 'Authorization: Bearer sk-1234' ``` -## Advanced - Redacting Messages from Alerts +## Advanced + +### Redacting Messages from Alerts By default alerts show the `messages/input` passed to the LLM. If you want to redact this from slack alerting set the following setting on your config @@ -76,7 +79,7 @@ litellm_settings: ``` -## Advanced - Add Metadata to alerts +### Add Metadata to alerts Add alerting metadata to proxy calls for debugging. @@ -105,7 +108,7 @@ response = client.chat.completions.create( -## Advanced - Opting into specific alert types +### Opting into specific alert types Set `alert_types` if you want to Opt into only specific alert types @@ -134,7 +137,7 @@ AlertType = Literal[ ``` -## Advanced - set specific slack channels per alert type +### Set specific slack channels per alert type Use this if you want to set specific channels per alert type @@ -190,7 +193,7 @@ curl -i http://localhost:4000/v1/chat/completions \ ``` -## Advanced - provide multiple slack channels for a given alert type +### Provide multiple slack channels for a given alert type Just add it like this - `alert_type: [, ]`. @@ -220,7 +223,7 @@ curl -X GET 'http://0.0.0.0:4000/health/services?service=slack' \ In case of error, check server logs for the error message! -## Advanced - Using MS Teams Webhooks +### Using MS Teams Webhooks MS Teams provides a slack compatible webhook url that you can use for alerting @@ -262,7 +265,7 @@ curl --location 'http://0.0.0.0:4000/health/services?service=slack' \ -## Advanced - Using Discord Webhooks +### Using Discord Webhooks Discord provides a slack compatible webhook url that you can use for alerting @@ -294,7 +297,7 @@ environment_variables: ``` -## Advanced - [BETA] Webhooks for Budget Alerts +## [BETA] Webhooks for Budget Alerts **Note**: This is a beta feature, so the spec might change. @@ -374,7 +377,7 @@ curl -X GET --location 'http://0.0.0.0:4000/health/services?service=webhook' \ - `event_message` *str*: A human-readable description of the event. -## Advanced - Region-outage alerting (✨ Enterprise feature) +## Region-outage alerting (✨ Enterprise feature) :::info [Get a free 2-week license](https://forms.gle/P518LXsAZ7PhXpDn8) diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index f6942dd29eb..71a356b8043 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -17,4 +17,6 @@ guardrails: general_settings: master_key: sk-1234 + alerting: ["slack"] + spend_report_frequency: "1d"