mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-25 18:54:30 +00:00
Support for Athina logging
This commit is contained in:
parent
a08c4bb1bf
commit
244fa1c4ab
7 changed files with 124 additions and 5 deletions
|
@ -100,7 +100,7 @@ for part in response:
|
||||||
```
|
```
|
||||||
|
|
||||||
## Logging Observability ([Docs](https://docs.litellm.ai/docs/observability/callbacks))
|
## Logging Observability ([Docs](https://docs.litellm.ai/docs/observability/callbacks))
|
||||||
LiteLLM exposes pre defined callbacks to send data to Langfuse, DynamoDB, s3 Buckets, LLMonitor, Helicone, Promptlayer, Traceloop, Slack
|
LiteLLM exposes pre defined callbacks to send data to Langfuse, DynamoDB, s3 Buckets, LLMonitor, Helicone, Promptlayer, Traceloop, Athina, Slack
|
||||||
```python
|
```python
|
||||||
from litellm import completion
|
from litellm import completion
|
||||||
|
|
||||||
|
@ -108,11 +108,12 @@ from litellm import completion
|
||||||
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
|
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
|
||||||
os.environ["LANGFUSE_SECRET_KEY"] = ""
|
os.environ["LANGFUSE_SECRET_KEY"] = ""
|
||||||
os.environ["LLMONITOR_APP_ID"] = "your-llmonitor-app-id"
|
os.environ["LLMONITOR_APP_ID"] = "your-llmonitor-app-id"
|
||||||
|
os.environ["ATHINA_API_KEY"] = "your-athina-api-key"
|
||||||
|
|
||||||
os.environ["OPENAI_API_KEY"]
|
os.environ["OPENAI_API_KEY"]
|
||||||
|
|
||||||
# set callbacks
|
# set callbacks
|
||||||
litellm.success_callback = ["langfuse", "llmonitor"] # log input/output to langfuse, llmonitor, supabase
|
litellm.success_callback = ["langfuse", "llmonitor", "athina"] # log input/output to langfuse, llmonitor, supabase, athina etc
|
||||||
|
|
||||||
#openai call
|
#openai call
|
||||||
response = completion(model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Hi 👋 - i'm openai"}])
|
response = completion(model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Hi 👋 - i'm openai"}])
|
||||||
|
|
50
docs/my-website/docs/observability/athina_integration.md
Normal file
50
docs/my-website/docs/observability/athina_integration.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import Image from '@theme/IdealImage';
|
||||||
|
|
||||||
|
# Athina
|
||||||
|
|
||||||
|
[Athina](https://athina.ai/) is an evaluation framework and production monitoring platform for your LLM-powered app. Athina is designed to enhance the performance and reliability of AI applications through real-time monitoring, granular analytics, and plug-and-play evaluations.
|
||||||
|
|
||||||
|
<Image img={require('../../athina_dashboard.png')} />
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Use Athina to log requests across all LLM Providers (OpenAI, Azure, Anthropic, Cohere, Replicate, PaLM)
|
||||||
|
|
||||||
|
liteLLM provides `callbacks`, making it easy for you to log data depending on the status of your responses.
|
||||||
|
|
||||||
|
## Using Callbacks
|
||||||
|
|
||||||
|
First, sign up to get an API_KEY on the [Athina dashboard](https://app.athina.ai).
|
||||||
|
|
||||||
|
Use just 1 line of code, to instantly log your responses **across all providers** with Athina:
|
||||||
|
|
||||||
|
```python
|
||||||
|
litellm.success_callback = ["athina"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete code
|
||||||
|
|
||||||
|
```python
|
||||||
|
from litellm import completion
|
||||||
|
|
||||||
|
## set env variables
|
||||||
|
os.environ["ATHINA_API_KEY"] = "your-athina-api-key"
|
||||||
|
os.environ["OPENAI_API_KEY"]= ""
|
||||||
|
|
||||||
|
# set callback
|
||||||
|
litellm.success_callback = ["athina"]
|
||||||
|
|
||||||
|
#openai call
|
||||||
|
response = completion(
|
||||||
|
model="gpt-3.5-turbo",
|
||||||
|
messages=[{"role": "user", "content": "Hi 👋 - i'm openai"}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support & Talk with us
|
||||||
|
|
||||||
|
- [Schedule Demo 👋](https://cal.com/shiv-athina/30min)
|
||||||
|
- [Website 💻](https://athina.ai/?utm_source=litellm&utm_medium=website)
|
||||||
|
- [Docs 📖](https://docs.athina.ai/?utm_source=litellm&utm_medium=website)
|
||||||
|
- [Demo Video 📺](https://www.loom.com/share/d9ef2c62e91b46769a39c42bb6669834?sid=711df413-0adb-4267-9708-5f29cef929e3)
|
||||||
|
- Our emails ✉️ shiv@athina.ai, akshat@athina.ai, vivek@athina.ai
|
|
@ -10,6 +10,7 @@ liteLLM supports:
|
||||||
- [LLMonitor](https://llmonitor.com/docs)
|
- [LLMonitor](https://llmonitor.com/docs)
|
||||||
- [Helicone](https://docs.helicone.ai/introduction)
|
- [Helicone](https://docs.helicone.ai/introduction)
|
||||||
- [Traceloop](https://traceloop.com/docs)
|
- [Traceloop](https://traceloop.com/docs)
|
||||||
|
- [Athina](https://docs.athina.ai/)
|
||||||
- [Sentry](https://docs.sentry.io/platforms/python/)
|
- [Sentry](https://docs.sentry.io/platforms/python/)
|
||||||
- [PostHog](https://posthog.com/docs/libraries/python)
|
- [PostHog](https://posthog.com/docs/libraries/python)
|
||||||
- [Slack](https://slack.dev/bolt-python/concepts)
|
- [Slack](https://slack.dev/bolt-python/concepts)
|
||||||
|
@ -21,7 +22,7 @@ from litellm import completion
|
||||||
|
|
||||||
# set callbacks
|
# set callbacks
|
||||||
litellm.input_callback=["sentry"] # for sentry breadcrumbing - logs the input being sent to the api
|
litellm.input_callback=["sentry"] # for sentry breadcrumbing - logs the input being sent to the api
|
||||||
litellm.success_callback=["posthog", "helicone", "llmonitor"]
|
litellm.success_callback=["posthog", "helicone", "llmonitor", "athina"]
|
||||||
litellm.failure_callback=["sentry", "llmonitor"]
|
litellm.failure_callback=["sentry", "llmonitor"]
|
||||||
|
|
||||||
## set env variables
|
## set env variables
|
||||||
|
@ -30,6 +31,7 @@ os.environ['POSTHOG_API_KEY'], os.environ['POSTHOG_API_URL'] = "api-key", "api-u
|
||||||
os.environ["HELICONE_API_KEY"] = ""
|
os.environ["HELICONE_API_KEY"] = ""
|
||||||
os.environ["TRACELOOP_API_KEY"] = ""
|
os.environ["TRACELOOP_API_KEY"] = ""
|
||||||
os.environ["LLMONITOR_APP_ID"] = ""
|
os.environ["LLMONITOR_APP_ID"] = ""
|
||||||
|
os.environ["ATHINA_API_KEY"] = ""
|
||||||
|
|
||||||
response = completion(model="gpt-3.5-turbo", messages=messages)
|
response = completion(model="gpt-3.5-turbo", messages=messages)
|
||||||
```
|
```
|
BIN
docs/my-website/img/athina_dashboard.png
Normal file
BIN
docs/my-website/img/athina_dashboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
|
@ -170,6 +170,7 @@ const sidebars = {
|
||||||
"observability/langsmith_integration",
|
"observability/langsmith_integration",
|
||||||
"observability/slack_integration",
|
"observability/slack_integration",
|
||||||
"observability/traceloop_integration",
|
"observability/traceloop_integration",
|
||||||
|
"observability/athina_integration",
|
||||||
"observability/llmonitor_integration",
|
"observability/llmonitor_integration",
|
||||||
"observability/helicone_integration",
|
"observability/helicone_integration",
|
||||||
"observability/supabase_integration",
|
"observability/supabase_integration",
|
||||||
|
|
49
litellm/integrations/athina.py
Normal file
49
litellm/integrations/athina.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
class AthinaLogger:
|
||||||
|
def __init__(self):
|
||||||
|
import os
|
||||||
|
self.athina_api_key = os.getenv("ATHINA_API_KEY")
|
||||||
|
self.headers = {
|
||||||
|
"athina-api-key": self.athina_api_key,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
self.athina_logging_url = "https://log.athina.ai/api/v1/log/inference"
|
||||||
|
self.additional_keys = ["environment", "prompt_slug", "customer_id", "customer_user_id", "session_id", "external_reference_id", "context", "expected_response"]
|
||||||
|
|
||||||
|
def log_event(self, kwargs, response_obj, start_time, end_time, print_verbose):
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import traceback
|
||||||
|
raise Exception("This method is not implemented yet")
|
||||||
|
try:
|
||||||
|
response_json = response_obj.model_dump() if response_obj else {}
|
||||||
|
data = {
|
||||||
|
"language_model_id": kwargs.get("model"),
|
||||||
|
"response_time": int((end_time - start_time).total_seconds() * 1000),
|
||||||
|
"request": kwargs,
|
||||||
|
"response": response_json,
|
||||||
|
"prompt": kwargs.get("messages"),
|
||||||
|
"user_query": kwargs.get("messages")[0].get("content"),
|
||||||
|
"prompt_tokens": response_json.get("usage", {}).get("prompt_tokens"),
|
||||||
|
"completion_tokens": response_json.get("usage", {}).get("completion_tokens"),
|
||||||
|
"total_tokens": response_json.get("usage", {}).get("total_tokens"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Directly add tools or functions if present
|
||||||
|
optional_params = kwargs.get("optional_params", {})
|
||||||
|
data.update((k, v) for k, v in optional_params.items() if k in ["tools", "functions"])
|
||||||
|
|
||||||
|
# Add additional metadata keys
|
||||||
|
metadata = kwargs.get("litellm_params", {}).get("metadata", {})
|
||||||
|
if metadata:
|
||||||
|
for key in self.additional_keys:
|
||||||
|
if key in metadata:
|
||||||
|
data[key] = metadata[key]
|
||||||
|
|
||||||
|
response = requests.post(self.athina_logging_url, headers=self.headers, data=json.dumps(data, default=str))
|
||||||
|
if response.status_code != 200:
|
||||||
|
print_verbose(f"Athina Logger Error - {response.text}, {response.status_code}")
|
||||||
|
else:
|
||||||
|
print_verbose(f"Athina Logger Succeeded - {response.text}")
|
||||||
|
except Exception as e:
|
||||||
|
print_verbose(f"Athina Logger Error - {e}, Stack trace: {traceback.format_exc()}")
|
||||||
|
pass
|
|
@ -55,6 +55,7 @@ encoding = tiktoken.get_encoding("cl100k_base")
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
from ._logging import verbose_logger
|
from ._logging import verbose_logger
|
||||||
from .integrations.traceloop import TraceloopLogger
|
from .integrations.traceloop import TraceloopLogger
|
||||||
|
from .integrations.athina import AthinaLogger
|
||||||
from .integrations.helicone import HeliconeLogger
|
from .integrations.helicone import HeliconeLogger
|
||||||
from .integrations.aispend import AISpendLogger
|
from .integrations.aispend import AISpendLogger
|
||||||
from .integrations.berrispend import BerriSpendLogger
|
from .integrations.berrispend import BerriSpendLogger
|
||||||
|
@ -114,6 +115,7 @@ posthog = None
|
||||||
slack_app = None
|
slack_app = None
|
||||||
alerts_channel = None
|
alerts_channel = None
|
||||||
heliconeLogger = None
|
heliconeLogger = None
|
||||||
|
athinaLogger = None
|
||||||
promptLayerLogger = None
|
promptLayerLogger = None
|
||||||
langsmithLogger = None
|
langsmithLogger = None
|
||||||
weightsBiasesLogger = None
|
weightsBiasesLogger = None
|
||||||
|
@ -1419,6 +1421,17 @@ class Logging:
|
||||||
result = kwargs["complete_streaming_response"]
|
result = kwargs["complete_streaming_response"]
|
||||||
# only add to cache once we have a complete streaming response
|
# only add to cache once we have a complete streaming response
|
||||||
litellm.cache.add_cache(result, **kwargs)
|
litellm.cache.add_cache(result, **kwargs)
|
||||||
|
if callback == "athina":
|
||||||
|
deep_copy = {}
|
||||||
|
for k, v in self.model_call_details.items():
|
||||||
|
deep_copy[k] = v
|
||||||
|
athinaLogger.log_event(
|
||||||
|
kwargs=deep_copy,
|
||||||
|
response_obj=result,
|
||||||
|
start_time=start_time,
|
||||||
|
end_time=end_time,
|
||||||
|
print_verbose=print_verbose,
|
||||||
|
)
|
||||||
if callback == "traceloop":
|
if callback == "traceloop":
|
||||||
deep_copy = {}
|
deep_copy = {}
|
||||||
for k, v in self.model_call_details.items():
|
for k, v in self.model_call_details.items():
|
||||||
|
@ -5506,7 +5519,7 @@ def validate_environment(model: Optional[str] = None) -> dict:
|
||||||
|
|
||||||
|
|
||||||
def set_callbacks(callback_list, function_id=None):
|
def set_callbacks(callback_list, function_id=None):
|
||||||
global sentry_sdk_instance, capture_exception, add_breadcrumb, posthog, slack_app, alerts_channel, traceloopLogger, heliconeLogger, aispendLogger, berrispendLogger, supabaseClient, liteDebuggerClient, llmonitorLogger, promptLayerLogger, langFuseLogger, customLogger, weightsBiasesLogger, langsmithLogger, dynamoLogger, s3Logger
|
global sentry_sdk_instance, capture_exception, add_breadcrumb, posthog, slack_app, alerts_channel, traceloopLogger, athinaLogger, heliconeLogger, aispendLogger, berrispendLogger, supabaseClient, liteDebuggerClient, llmonitorLogger, promptLayerLogger, langFuseLogger, customLogger, weightsBiasesLogger, langsmithLogger, dynamoLogger, s3Logger
|
||||||
try:
|
try:
|
||||||
for callback in callback_list:
|
for callback in callback_list:
|
||||||
print_verbose(f"callback: {callback}")
|
print_verbose(f"callback: {callback}")
|
||||||
|
@ -5561,6 +5574,9 @@ def set_callbacks(callback_list, function_id=None):
|
||||||
print_verbose(f"Initialized Slack App: {slack_app}")
|
print_verbose(f"Initialized Slack App: {slack_app}")
|
||||||
elif callback == "traceloop":
|
elif callback == "traceloop":
|
||||||
traceloopLogger = TraceloopLogger()
|
traceloopLogger = TraceloopLogger()
|
||||||
|
elif callback == "athina":
|
||||||
|
athinaLogger = AthinaLogger()
|
||||||
|
print_verbose("Initialized Athina Logger")
|
||||||
elif callback == "helicone":
|
elif callback == "helicone":
|
||||||
heliconeLogger = HeliconeLogger()
|
heliconeLogger = HeliconeLogger()
|
||||||
elif callback == "llmonitor":
|
elif callback == "llmonitor":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue