openlit 1.34.25__tar.gz → 1.34.27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openlit-1.34.25 → openlit-1.34.27}/PKG-INFO +1 -1
- {openlit-1.34.25 → openlit-1.34.27}/pyproject.toml +1 -1
- openlit-1.34.27/src/openlit/instrumentation/astra/__init__.py +90 -0
- openlit-1.34.27/src/openlit/instrumentation/astra/astra.py +55 -0
- openlit-1.34.27/src/openlit/instrumentation/astra/async_astra.py +55 -0
- openlit-1.34.27/src/openlit/instrumentation/astra/utils.py +277 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/chroma/__init__.py +1 -1
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/chroma/chroma.py +6 -8
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/chroma/utils.py +48 -3
- openlit-1.34.27/src/openlit/instrumentation/milvus/__init__.py +56 -0
- openlit-1.34.27/src/openlit/instrumentation/milvus/milvus.py +52 -0
- openlit-1.34.27/src/openlit/instrumentation/milvus/utils.py +276 -0
- openlit-1.34.27/src/openlit/instrumentation/pinecone/__init__.py +78 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pinecone/async_pinecone.py +6 -8
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pinecone/pinecone.py +6 -8
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pinecone/utils.py +41 -1
- openlit-1.34.27/src/openlit/instrumentation/qdrant/__init__.py +80 -0
- openlit-1.34.27/src/openlit/instrumentation/qdrant/async_qdrant.py +55 -0
- openlit-1.34.27/src/openlit/instrumentation/qdrant/qdrant.py +55 -0
- openlit-1.34.27/src/openlit/instrumentation/qdrant/utils.py +328 -0
- openlit-1.34.25/src/openlit/instrumentation/astra/__init__.py +0 -178
- openlit-1.34.25/src/openlit/instrumentation/astra/astra.py +0 -45
- openlit-1.34.25/src/openlit/instrumentation/astra/async_astra.py +0 -45
- openlit-1.34.25/src/openlit/instrumentation/astra/utils.py +0 -102
- openlit-1.34.25/src/openlit/instrumentation/milvus/__init__.py +0 -94
- openlit-1.34.25/src/openlit/instrumentation/milvus/milvus.py +0 -179
- openlit-1.34.25/src/openlit/instrumentation/pinecone/__init__.py +0 -174
- openlit-1.34.25/src/openlit/instrumentation/qdrant/__init__.py +0 -295
- openlit-1.34.25/src/openlit/instrumentation/qdrant/async_qdrant.py +0 -267
- openlit-1.34.25/src/openlit/instrumentation/qdrant/qdrant.py +0 -274
- {openlit-1.34.25 → openlit-1.34.27}/LICENSE +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/README.md +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/__helpers.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/all.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/bias_detection.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/hallucination.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/toxicity.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/evals/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/all.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/prompt_injection.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/restrict_topic.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/sensitive_topic.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/guard/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ag2/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ag2/ag2.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ag2/async_ag2.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ag2/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ai21/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ai21/ai21.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ai21/async_ai21.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ai21/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/anthropic/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/anthropic/anthropic.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/anthropic/async_anthropic.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/anthropic/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/assemblyai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/assemblyai/assemblyai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/assemblyai/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/azure_ai_inference/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/azure_ai_inference/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/bedrock/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/bedrock/bedrock.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/bedrock/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/cohere/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/cohere/async_cohere.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/cohere/cohere.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/cohere/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/controlflow/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/controlflow/controlflow.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/crawl4ai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/crawl4ai/async_crawl4ai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/crawl4ai/crawl4ai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/crewai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/crewai/crewai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/dynamiq/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/dynamiq/dynamiq.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/elevenlabs/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/elevenlabs/async_elevenlabs.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/elevenlabs/elevenlabs.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/elevenlabs/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/embedchain/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/embedchain/embedchain.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/firecrawl/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/firecrawl/firecrawl.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/google_ai_studio/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/google_ai_studio/google_ai_studio.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/google_ai_studio/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/gpt4all/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/gpt4all/gpt4all.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/gpt4all/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/gpu/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/groq/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/groq/async_groq.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/groq/groq.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/groq/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/haystack/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/haystack/haystack.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/julep/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/julep/async_julep.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/julep/julep.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain/async_langchain.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain/langchain.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain_community/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain_community/async_langchain_community.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain_community/langchain_community.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/langchain_community/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/letta/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/letta/letta.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/litellm/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/litellm/async_litellm.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/litellm/litellm.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/litellm/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/llamaindex/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/llamaindex/llamaindex.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mem0/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mem0/mem0.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mistral/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mistral/async_mistral.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mistral/mistral.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/mistral/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/multion/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/multion/async_multion.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/multion/multion.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ollama/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ollama/async_ollama.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ollama/ollama.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/ollama/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai/async_openai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai/openai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai_agents/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/openai_agents/openai_agents.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/phidata/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/phidata/phidata.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/premai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/premai/premai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/premai/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pydantic_ai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pydantic_ai/pydantic_ai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/pydantic_ai/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/reka/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/reka/async_reka.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/reka/reka.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/reka/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/together/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/together/async_together.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/together/together.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/together/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/transformers/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/transformers/transformers.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/transformers/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vertexai/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vertexai/async_vertexai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vertexai/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vertexai/vertexai.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vllm/__init__.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vllm/utils.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/instrumentation/vllm/vllm.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/otel/events.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/otel/metrics.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/otel/tracing.py +0 -0
- {openlit-1.34.25 → openlit-1.34.27}/src/openlit/semcov/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: openlit
|
3
|
-
Version: 1.34.
|
3
|
+
Version: 1.34.27
|
4
4
|
Summary: OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications and GPUs, facilitating the integration of observability into your GenAI-driven projects
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: OpenTelemetry,otel,otlp,llm,tracing,openai,anthropic,claude,cohere,llm monitoring,observability,monitoring,gpt,Generative AI,chatGPT,gpu
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "openlit"
|
3
|
-
version = "1.34.
|
3
|
+
version = "1.34.27"
|
4
4
|
description = "OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications and GPUs, facilitating the integration of observability into your GenAI-driven projects"
|
5
5
|
authors = ["OpenLIT"]
|
6
6
|
license = "Apache-2.0"
|
@@ -0,0 +1,90 @@
|
|
1
|
+
"""
|
2
|
+
OpenLIT AstraDB Instrumentation
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Collection
|
6
|
+
import importlib.metadata
|
7
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
8
|
+
from wrapt import wrap_function_wrapper
|
9
|
+
|
10
|
+
from openlit.instrumentation.astra.astra import general_wrap
|
11
|
+
from openlit.instrumentation.astra.async_astra import async_general_wrap
|
12
|
+
|
13
|
+
_instruments = ("astrapy >= 1.5.2",)
|
14
|
+
|
15
|
+
# AstraDB sync operations
|
16
|
+
ASTRA_SYNC_OPERATIONS = [
|
17
|
+
# Database operations
|
18
|
+
("astrapy.database", "Database.create_collection", "astra.create_collection"),
|
19
|
+
("astrapy.database", "Database.drop_collection", "astra.drop_collection"),
|
20
|
+
|
21
|
+
# Collection operations
|
22
|
+
("astrapy.collection", "Collection.insert_one", "astra.insert_one"),
|
23
|
+
("astrapy.collection", "Collection.insert_many", "astra.insert_many"),
|
24
|
+
("astrapy.collection", "Collection.update_one", "astra.update_one"),
|
25
|
+
("astrapy.collection", "Collection.update_many", "astra.update_many"),
|
26
|
+
("astrapy.collection", "Collection.find_one_and_update", "astra.find_one_and_update"),
|
27
|
+
("astrapy.collection", "Collection.find", "astra.find"),
|
28
|
+
("astrapy.collection", "Collection.replace_one", "astra.replace_one"),
|
29
|
+
("astrapy.collection", "Collection.find_one_and_delete", "astra.find_one_and_delete"),
|
30
|
+
("astrapy.collection", "Collection.delete_one", "astra.delete_one"),
|
31
|
+
("astrapy.collection", "Collection.delete_many", "astra.delete_many"),
|
32
|
+
]
|
33
|
+
|
34
|
+
# AstraDB async operations
|
35
|
+
ASTRA_ASYNC_OPERATIONS = [
|
36
|
+
# Async Database operations
|
37
|
+
("astrapy.database", "AsyncDatabase.create_collection", "astra.create_collection"),
|
38
|
+
("astrapy.database", "AsyncDatabase.drop_collection", "astra.drop_collection"),
|
39
|
+
|
40
|
+
# Async Collection operations
|
41
|
+
("astrapy.collection", "AsyncCollection.insert_one", "astra.insert_one"),
|
42
|
+
("astrapy.collection", "AsyncCollection.insert_many", "astra.insert_many"),
|
43
|
+
("astrapy.collection", "AsyncCollection.update_one", "astra.update_one"),
|
44
|
+
("astrapy.collection", "AsyncCollection.update_many", "astra.update_many"),
|
45
|
+
("astrapy.collection", "AsyncCollection.find_one_and_update", "astra.find_one_and_update"),
|
46
|
+
("astrapy.collection", "AsyncCollection.find", "astra.find"),
|
47
|
+
("astrapy.collection", "AsyncCollection.replace_one", "astra.replace_one"),
|
48
|
+
("astrapy.collection", "AsyncCollection.find_one_and_delete", "astra.find_one_and_delete"),
|
49
|
+
("astrapy.collection", "AsyncCollection.delete_one", "astra.delete_one"),
|
50
|
+
("astrapy.collection", "AsyncCollection.delete_many", "astra.delete_many"),
|
51
|
+
]
|
52
|
+
|
53
|
+
class AstraInstrumentor(BaseInstrumentor):
|
54
|
+
"""
|
55
|
+
An instrumentor for AstraDB's client library.
|
56
|
+
"""
|
57
|
+
|
58
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
59
|
+
return _instruments
|
60
|
+
|
61
|
+
def _instrument(self, **kwargs):
|
62
|
+
version = importlib.metadata.version("astrapy")
|
63
|
+
environment = kwargs.get("environment", "default")
|
64
|
+
application_name = kwargs.get("application_name", "default")
|
65
|
+
tracer = kwargs.get("tracer")
|
66
|
+
pricing_info = kwargs.get("pricing_info", {})
|
67
|
+
capture_message_content = kwargs.get("capture_message_content", False)
|
68
|
+
metrics = kwargs.get("metrics_dict")
|
69
|
+
disable_metrics = kwargs.get("disable_metrics")
|
70
|
+
|
71
|
+
# Wrap sync operations
|
72
|
+
for module, class_method, endpoint in ASTRA_SYNC_OPERATIONS:
|
73
|
+
wrap_function_wrapper(
|
74
|
+
module,
|
75
|
+
class_method,
|
76
|
+
general_wrap(endpoint, version, environment, application_name,
|
77
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics),
|
78
|
+
)
|
79
|
+
|
80
|
+
# Wrap async operations
|
81
|
+
for module, class_method, endpoint in ASTRA_ASYNC_OPERATIONS:
|
82
|
+
wrap_function_wrapper(
|
83
|
+
module,
|
84
|
+
class_method,
|
85
|
+
async_general_wrap(endpoint, version, environment, application_name,
|
86
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics),
|
87
|
+
)
|
88
|
+
|
89
|
+
def _uninstrument(self, **kwargs):
|
90
|
+
pass
|
@@ -0,0 +1,55 @@
|
|
1
|
+
"""
|
2
|
+
Module for monitoring AstraDB API calls.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import time
|
6
|
+
from opentelemetry.trace import SpanKind
|
7
|
+
from opentelemetry import context as context_api
|
8
|
+
from openlit.__helpers import handle_exception
|
9
|
+
from openlit.instrumentation.astra.utils import (
|
10
|
+
process_astra_response,
|
11
|
+
DB_OPERATION_MAP,
|
12
|
+
set_server_address_and_port,
|
13
|
+
)
|
14
|
+
|
15
|
+
def general_wrap(gen_ai_endpoint, version, environment, application_name,
|
16
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics):
|
17
|
+
"""
|
18
|
+
Generates a telemetry wrapper for AstraDB function calls.
|
19
|
+
"""
|
20
|
+
def wrapper(wrapped, instance, args, kwargs):
|
21
|
+
# CRITICAL: Suppression check
|
22
|
+
if context_api.get_value(context_api._SUPPRESS_INSTRUMENTATION_KEY):
|
23
|
+
return wrapped(*args, **kwargs)
|
24
|
+
|
25
|
+
# Get server address and port using the standard helper
|
26
|
+
server_address, server_port = set_server_address_and_port(instance)
|
27
|
+
|
28
|
+
db_operation = DB_OPERATION_MAP.get(gen_ai_endpoint, "unknown")
|
29
|
+
|
30
|
+
# Handle upsert detection for replace operations
|
31
|
+
if db_operation == "DB_OPERATION_REPLACE" and kwargs.get("upsert"):
|
32
|
+
db_operation = "DB_OPERATION_UPSERT"
|
33
|
+
|
34
|
+
# Get collection name for span naming
|
35
|
+
collection_name = getattr(instance, "name", "unknown")
|
36
|
+
span_name = f"{db_operation} {collection_name}"
|
37
|
+
|
38
|
+
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
39
|
+
start_time = time.time()
|
40
|
+
response = wrapped(*args, **kwargs)
|
41
|
+
|
42
|
+
try:
|
43
|
+
# Process response and generate telemetry
|
44
|
+
response = process_astra_response(
|
45
|
+
response, db_operation, server_address, server_port,
|
46
|
+
environment, application_name, metrics, start_time, span,
|
47
|
+
capture_message_content, disable_metrics, version, instance, args, **kwargs
|
48
|
+
)
|
49
|
+
|
50
|
+
except Exception as e:
|
51
|
+
handle_exception(span, e)
|
52
|
+
|
53
|
+
return response
|
54
|
+
|
55
|
+
return wrapper
|
@@ -0,0 +1,55 @@
|
|
1
|
+
"""
|
2
|
+
Module for monitoring AstraDB async API calls.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import time
|
6
|
+
from opentelemetry.trace import SpanKind
|
7
|
+
from opentelemetry import context as context_api
|
8
|
+
from openlit.__helpers import handle_exception
|
9
|
+
from openlit.instrumentation.astra.utils import (
|
10
|
+
process_astra_response,
|
11
|
+
DB_OPERATION_MAP,
|
12
|
+
set_server_address_and_port,
|
13
|
+
)
|
14
|
+
|
15
|
+
def async_general_wrap(gen_ai_endpoint, version, environment, application_name,
|
16
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics):
|
17
|
+
"""
|
18
|
+
Generates a telemetry wrapper for AstraDB async function calls.
|
19
|
+
"""
|
20
|
+
async def wrapper(wrapped, instance, args, kwargs):
|
21
|
+
# CRITICAL: Suppression check
|
22
|
+
if context_api.get_value(context_api._SUPPRESS_INSTRUMENTATION_KEY):
|
23
|
+
return wrapped(*args, **kwargs)
|
24
|
+
|
25
|
+
# Get server address and port using the standard helper
|
26
|
+
server_address, server_port = set_server_address_and_port(instance)
|
27
|
+
|
28
|
+
db_operation = DB_OPERATION_MAP.get(gen_ai_endpoint, "unknown")
|
29
|
+
|
30
|
+
# Handle upsert detection for replace operations
|
31
|
+
if db_operation == "DB_OPERATION_REPLACE" and kwargs.get("upsert"):
|
32
|
+
db_operation = "DB_OPERATION_UPSERT"
|
33
|
+
|
34
|
+
# Get collection name for span naming
|
35
|
+
collection_name = getattr(instance, "name", "unknown")
|
36
|
+
span_name = f"{db_operation} {collection_name}"
|
37
|
+
|
38
|
+
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
39
|
+
start_time = time.time()
|
40
|
+
response = await wrapped(*args, **kwargs)
|
41
|
+
|
42
|
+
try:
|
43
|
+
# Process response and generate telemetry
|
44
|
+
response = process_astra_response(
|
45
|
+
response, db_operation, server_address, server_port,
|
46
|
+
environment, application_name, metrics, start_time, span,
|
47
|
+
capture_message_content, disable_metrics, version, instance, args, **kwargs
|
48
|
+
)
|
49
|
+
|
50
|
+
except Exception as e:
|
51
|
+
handle_exception(span, e)
|
52
|
+
|
53
|
+
return response
|
54
|
+
|
55
|
+
return wrapper
|
@@ -0,0 +1,277 @@
|
|
1
|
+
"""
|
2
|
+
Utility functions for AstraDB instrumentation.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import time
|
6
|
+
from urllib.parse import urlparse
|
7
|
+
from opentelemetry.trace import Status, StatusCode
|
8
|
+
from openlit.__helpers import (
|
9
|
+
common_db_span_attributes,
|
10
|
+
record_db_metrics,
|
11
|
+
)
|
12
|
+
from openlit.semcov import SemanticConvention
|
13
|
+
|
14
|
+
# Operation mapping for simple span naming
|
15
|
+
DB_OPERATION_MAP = {
|
16
|
+
"astra.create_collection": SemanticConvention.DB_OPERATION_CREATE_COLLECTION,
|
17
|
+
"astra.drop_collection": SemanticConvention.DB_OPERATION_DELETE_COLLECTION,
|
18
|
+
"astra.insert": SemanticConvention.DB_OPERATION_INSERT,
|
19
|
+
"astra.insert_one": SemanticConvention.DB_OPERATION_INSERT,
|
20
|
+
"astra.insert_many": SemanticConvention.DB_OPERATION_INSERT,
|
21
|
+
"astra.update": SemanticConvention.DB_OPERATION_UPDATE,
|
22
|
+
"astra.update_one": SemanticConvention.DB_OPERATION_UPDATE,
|
23
|
+
"astra.update_many": SemanticConvention.DB_OPERATION_UPDATE,
|
24
|
+
"astra.find": SemanticConvention.DB_OPERATION_SELECT,
|
25
|
+
"astra.find_one_and_update": SemanticConvention.DB_OPERATION_REPLACE,
|
26
|
+
"astra.replace_one": SemanticConvention.DB_OPERATION_REPLACE,
|
27
|
+
"astra.find_one_and_delete": SemanticConvention.DB_OPERATION_FIND_AND_DELETE,
|
28
|
+
"astra.delete": SemanticConvention.DB_OPERATION_DELETE,
|
29
|
+
"astra.delete_one": SemanticConvention.DB_OPERATION_DELETE,
|
30
|
+
"astra.delete_many": SemanticConvention.DB_OPERATION_DELETE,
|
31
|
+
}
|
32
|
+
|
33
|
+
def object_count(obj):
|
34
|
+
"""
|
35
|
+
Counts length of object if it exists, else returns 0.
|
36
|
+
"""
|
37
|
+
if isinstance(obj, list):
|
38
|
+
return len(obj)
|
39
|
+
elif obj is not None:
|
40
|
+
return 1
|
41
|
+
return 0
|
42
|
+
|
43
|
+
def set_server_address_and_port(instance):
|
44
|
+
"""
|
45
|
+
Extracts server address and port from AstraDB client instance.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
instance: AstraDB client instance
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
tuple: (server_address, server_port)
|
52
|
+
"""
|
53
|
+
server_address = "astra.datastax.com"
|
54
|
+
server_port = 443
|
55
|
+
|
56
|
+
# Try getting api_endpoint from instance or its database
|
57
|
+
api_endpoint = getattr(instance, "api_endpoint", None)
|
58
|
+
if not api_endpoint:
|
59
|
+
# Try getting from database attribute
|
60
|
+
database = getattr(instance, "database", None)
|
61
|
+
if database:
|
62
|
+
api_endpoint = getattr(database, "api_endpoint", None)
|
63
|
+
|
64
|
+
if api_endpoint and isinstance(api_endpoint, str):
|
65
|
+
if api_endpoint.startswith(("http://", "https://")):
|
66
|
+
try:
|
67
|
+
parsed = urlparse(api_endpoint)
|
68
|
+
server_address = parsed.hostname or server_address
|
69
|
+
server_port = parsed.port or server_port
|
70
|
+
except Exception:
|
71
|
+
pass
|
72
|
+
else:
|
73
|
+
# Handle cases like "hostname:port" or just "hostname"
|
74
|
+
if ":" in api_endpoint:
|
75
|
+
parts = api_endpoint.split(":")
|
76
|
+
server_address = parts[0]
|
77
|
+
try:
|
78
|
+
server_port = int(parts[1])
|
79
|
+
except (ValueError, IndexError):
|
80
|
+
pass
|
81
|
+
else:
|
82
|
+
server_address = api_endpoint
|
83
|
+
|
84
|
+
return server_address, server_port
|
85
|
+
|
86
|
+
def common_astra_logic(scope, environment, application_name,
|
87
|
+
metrics, capture_message_content, disable_metrics, version,
|
88
|
+
instance=None, endpoint=None):
|
89
|
+
"""
|
90
|
+
Process AstraDB request and generate telemetry.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
scope: Scope object containing span, response, and operation details
|
94
|
+
environment: Deployment environment
|
95
|
+
application_name: Name of the application
|
96
|
+
metrics: Metrics dictionary for recording telemetry
|
97
|
+
capture_message_content: Flag to capture message content
|
98
|
+
disable_metrics: Flag to disable metrics collection
|
99
|
+
version: Version of the AstraDB client
|
100
|
+
instance: AstraDB client instance
|
101
|
+
endpoint: Operation endpoint for differentiation
|
102
|
+
"""
|
103
|
+
scope._end_time = time.time()
|
104
|
+
|
105
|
+
# Set common database span attributes using helper
|
106
|
+
common_db_span_attributes(scope, SemanticConvention.DB_SYSTEM_ASTRA,
|
107
|
+
scope._server_address, scope._server_port, environment, application_name, version)
|
108
|
+
|
109
|
+
# Set DB operation specific attributes
|
110
|
+
scope._span.set_attribute(SemanticConvention.DB_OPERATION_NAME, scope._db_operation)
|
111
|
+
scope._span.set_attribute(SemanticConvention.DB_CLIENT_OPERATION_DURATION,
|
112
|
+
scope._end_time - scope._start_time)
|
113
|
+
|
114
|
+
# Get collection name from instance
|
115
|
+
collection_name = getattr(instance, "name", "unknown")
|
116
|
+
scope._span.set_attribute(SemanticConvention.DB_COLLECTION_NAME, collection_name)
|
117
|
+
|
118
|
+
if scope._db_operation == SemanticConvention.DB_OPERATION_CREATE_COLLECTION:
|
119
|
+
# Handle create_collection operation
|
120
|
+
scope._span.set_attribute(SemanticConvention.DB_COLLECTION_DIMENSION,
|
121
|
+
scope._kwargs.get("dimension", -1))
|
122
|
+
scope._span.set_attribute(SemanticConvention.DB_INDEX_METRIC,
|
123
|
+
str(scope._kwargs.get("metric", "")))
|
124
|
+
|
125
|
+
# Set namespace if available in response
|
126
|
+
if scope._response and hasattr(scope._response, "keyspace"):
|
127
|
+
scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, scope._response.keyspace)
|
128
|
+
|
129
|
+
if scope._response and hasattr(scope._response, "name"):
|
130
|
+
scope._span.set_attribute(SemanticConvention.DB_COLLECTION_NAME, scope._response.name)
|
131
|
+
|
132
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
133
|
+
f"{scope._db_operation} {collection_name} "
|
134
|
+
f"dimension={scope._kwargs.get('dimension', 'None')} "
|
135
|
+
f"metric={scope._kwargs.get('metric', 'None')}")
|
136
|
+
|
137
|
+
elif scope._db_operation == SemanticConvention.DB_OPERATION_DELETE_COLLECTION:
|
138
|
+
# Handle drop_collection operation
|
139
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
140
|
+
f"{scope._db_operation} {collection_name}")
|
141
|
+
|
142
|
+
elif scope._db_operation == SemanticConvention.DB_OPERATION_INSERT:
|
143
|
+
# Handle insert operations (insert_one, insert_many, regular insert)
|
144
|
+
documents = scope._args[0] if scope._args else scope._kwargs.get("documents", [])
|
145
|
+
|
146
|
+
scope._span.set_attribute(SemanticConvention.DB_DOCUMENTS_COUNT, object_count(documents))
|
147
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(documents))
|
148
|
+
|
149
|
+
# Response metrics
|
150
|
+
if scope._response and hasattr(scope._response, "inserted_ids"):
|
151
|
+
scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS,
|
152
|
+
len(scope._response.inserted_ids))
|
153
|
+
|
154
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
155
|
+
f"{scope._db_operation} {collection_name} "
|
156
|
+
f"documents_count={object_count(documents)}")
|
157
|
+
|
158
|
+
elif scope._db_operation == SemanticConvention.DB_OPERATION_UPDATE:
|
159
|
+
# Handle update operations (update_one, update_many, regular update)
|
160
|
+
update_query = scope._args[1] if len(scope._args) > 1 else scope._kwargs.get("update", {})
|
161
|
+
filter_query = scope._args[0] if scope._args else scope._kwargs.get("filter", {})
|
162
|
+
|
163
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(update_query))
|
164
|
+
scope._span.set_attribute(SemanticConvention.DB_FILTER, str(filter_query))
|
165
|
+
|
166
|
+
# Response metrics
|
167
|
+
if scope._response and hasattr(scope._response, "update_info"):
|
168
|
+
scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS,
|
169
|
+
scope._response.update_info.get("nModified", 0))
|
170
|
+
|
171
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
172
|
+
f"{scope._db_operation} {collection_name} "
|
173
|
+
f"filter={str(filter_query)[:100]}... "
|
174
|
+
f"update={str(update_query)[:100]}...")
|
175
|
+
|
176
|
+
elif scope._db_operation == SemanticConvention.DB_OPERATION_REPLACE:
|
177
|
+
# Handle replace operations (find_one_and_update, replace_one)
|
178
|
+
filter_query = scope._args[0] if scope._args else scope._kwargs.get("filter", {})
|
179
|
+
|
180
|
+
# Check if it's an upsert operation
|
181
|
+
if scope._kwargs.get("upsert"):
|
182
|
+
scope._db_operation = SemanticConvention.DB_OPERATION_UPSERT
|
183
|
+
scope._span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
|
184
|
+
SemanticConvention.DB_OPERATION_UPSERT)
|
185
|
+
|
186
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(filter_query))
|
187
|
+
scope._span.set_attribute(SemanticConvention.DB_FILTER, str(filter_query))
|
188
|
+
|
189
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
190
|
+
f"{scope._db_operation} {collection_name} "
|
191
|
+
f"filter={str(filter_query)[:100]}... "
|
192
|
+
f"upsert={scope._kwargs.get('upsert', False)}")
|
193
|
+
|
194
|
+
elif scope._db_operation == SemanticConvention.DB_OPERATION_SELECT:
|
195
|
+
# Handle find operations
|
196
|
+
filter_query = scope._args[0] if scope._args else scope._kwargs.get("filter", {})
|
197
|
+
|
198
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(filter_query))
|
199
|
+
scope._span.set_attribute(SemanticConvention.DB_FILTER, str(filter_query))
|
200
|
+
|
201
|
+
# Response metrics
|
202
|
+
if scope._response and hasattr(scope._response, "__len__"):
|
203
|
+
scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS,
|
204
|
+
len(scope._response))
|
205
|
+
|
206
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
207
|
+
f"{scope._db_operation} {collection_name} "
|
208
|
+
f"filter={str(filter_query)[:100]}...")
|
209
|
+
|
210
|
+
elif scope._db_operation in [SemanticConvention.DB_OPERATION_DELETE,
|
211
|
+
SemanticConvention.DB_OPERATION_FIND_AND_DELETE]:
|
212
|
+
# Handle delete operations (delete_one, delete_many, find_one_and_delete)
|
213
|
+
filter_query = scope._args[0] if scope._args else scope._kwargs.get("filter", {})
|
214
|
+
|
215
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(filter_query))
|
216
|
+
scope._span.set_attribute(SemanticConvention.DB_FILTER, str(filter_query))
|
217
|
+
|
218
|
+
# Response metrics
|
219
|
+
if scope._response and hasattr(scope._response, "deleted_count"):
|
220
|
+
scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS,
|
221
|
+
scope._response.deleted_count)
|
222
|
+
|
223
|
+
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
224
|
+
f"{scope._db_operation} {collection_name} "
|
225
|
+
f"filter={str(filter_query)[:100]}...")
|
226
|
+
|
227
|
+
scope._span.set_status(Status(StatusCode.OK))
|
228
|
+
|
229
|
+
# Record metrics using helper
|
230
|
+
if not disable_metrics:
|
231
|
+
record_db_metrics(metrics, SemanticConvention.DB_SYSTEM_ASTRA,
|
232
|
+
scope._server_address, scope._server_port, environment, application_name,
|
233
|
+
scope._start_time, scope._end_time)
|
234
|
+
|
235
|
+
def process_astra_response(response, db_operation, server_address, server_port,
|
236
|
+
environment, application_name, metrics, start_time, span,
|
237
|
+
capture_message_content, disable_metrics, version, instance, args, **kwargs):
|
238
|
+
"""
|
239
|
+
Process AstraDB response and generate telemetry.
|
240
|
+
|
241
|
+
Args:
|
242
|
+
response: Response from AstraDB operation
|
243
|
+
db_operation: Database operation type
|
244
|
+
server_address: Server address
|
245
|
+
server_port: Server port
|
246
|
+
environment: Deployment environment
|
247
|
+
application_name: Application name
|
248
|
+
metrics: Metrics dictionary
|
249
|
+
start_time: Start time of the operation
|
250
|
+
span: OpenTelemetry span
|
251
|
+
capture_message_content: Flag to capture message content
|
252
|
+
disable_metrics: Flag to disable metrics
|
253
|
+
version: AstraDB client version
|
254
|
+
instance: AstraDB client instance
|
255
|
+
args: Positional arguments
|
256
|
+
**kwargs: Keyword arguments
|
257
|
+
|
258
|
+
Returns:
|
259
|
+
Original response
|
260
|
+
"""
|
261
|
+
|
262
|
+
# Create a scope object to hold all the context
|
263
|
+
scope = type("GenericScope", (), {})()
|
264
|
+
scope._response = response
|
265
|
+
scope._db_operation = db_operation
|
266
|
+
scope._server_address = server_address
|
267
|
+
scope._server_port = server_port
|
268
|
+
scope._start_time = start_time
|
269
|
+
scope._span = span
|
270
|
+
scope._kwargs = kwargs
|
271
|
+
scope._args = args
|
272
|
+
|
273
|
+
# Process the response using common logic
|
274
|
+
common_astra_logic(scope, environment, application_name,
|
275
|
+
metrics, capture_message_content, disable_metrics, version, instance)
|
276
|
+
|
277
|
+
return response
|
@@ -13,7 +13,7 @@ _instruments = ("chromadb >= 0.4.0",)
|
|
13
13
|
|
14
14
|
class ChromaInstrumentor(BaseInstrumentor):
|
15
15
|
"""
|
16
|
-
An instrumentor for ChromaDB
|
16
|
+
An instrumentor for ChromaDB client library.
|
17
17
|
"""
|
18
18
|
|
19
19
|
def instrumentation_dependencies(self) -> Collection[str]:
|
@@ -5,13 +5,11 @@ Module for monitoring ChromaDB API calls.
|
|
5
5
|
import time
|
6
6
|
from opentelemetry.trace import SpanKind
|
7
7
|
from opentelemetry import context as context_api
|
8
|
-
from openlit.__helpers import
|
9
|
-
handle_exception,
|
10
|
-
set_server_address_and_port,
|
11
|
-
)
|
8
|
+
from openlit.__helpers import handle_exception
|
12
9
|
from openlit.instrumentation.chroma.utils import (
|
13
10
|
process_vectordb_response,
|
14
11
|
DB_OPERATION_MAP,
|
12
|
+
set_server_address_and_port,
|
15
13
|
)
|
16
14
|
|
17
15
|
def general_wrap(gen_ai_endpoint, version, environment, application_name,
|
@@ -29,7 +27,7 @@ def general_wrap(gen_ai_endpoint, version, environment, application_name,
|
|
29
27
|
return wrapped(*args, **kwargs)
|
30
28
|
|
31
29
|
# Get server address and port using the standard helper
|
32
|
-
server_address, server_port = set_server_address_and_port(instance
|
30
|
+
server_address, server_port = set_server_address_and_port(instance)
|
33
31
|
|
34
32
|
db_operation = DB_OPERATION_MAP.get(gen_ai_endpoint, "unknown")
|
35
33
|
if db_operation == "create_collection":
|
@@ -39,10 +37,10 @@ def general_wrap(gen_ai_endpoint, version, environment, application_name,
|
|
39
37
|
span_name = f"{db_operation} {namespace}"
|
40
38
|
|
41
39
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
42
|
-
|
43
|
-
|
44
|
-
response = wrapped(*args, **kwargs)
|
40
|
+
start_time = time.time()
|
41
|
+
response = wrapped(*args, **kwargs)
|
45
42
|
|
43
|
+
try:
|
46
44
|
# Process response and generate telemetry
|
47
45
|
response = process_vectordb_response(
|
48
46
|
response, db_operation, server_address, server_port,
|
@@ -2,7 +2,7 @@
|
|
2
2
|
ChromaDB OpenTelemetry instrumentation utility functions
|
3
3
|
"""
|
4
4
|
import time
|
5
|
-
|
5
|
+
from urllib.parse import urlparse
|
6
6
|
from opentelemetry.trace import Status, StatusCode
|
7
7
|
|
8
8
|
from openlit.__helpers import (
|
@@ -29,6 +29,51 @@ def object_count(obj):
|
|
29
29
|
"""
|
30
30
|
return len(obj) if obj else 0
|
31
31
|
|
32
|
+
def set_server_address_and_port(instance):
|
33
|
+
"""
|
34
|
+
Extracts server address and port from ChromaDB client instance.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
instance: ChromaDB client instance
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
tuple: (server_address, server_port)
|
41
|
+
"""
|
42
|
+
server_address = "localhost"
|
43
|
+
server_port = 8000
|
44
|
+
|
45
|
+
# Try getting base_url from multiple potential attributes
|
46
|
+
base_client = getattr(instance, "_client", None)
|
47
|
+
base_url = getattr(base_client, "base_url", None)
|
48
|
+
|
49
|
+
if not base_url:
|
50
|
+
# Attempt to get endpoint from instance._config.endpoint
|
51
|
+
config = getattr(instance, "_config", None)
|
52
|
+
base_url = getattr(config, "endpoint", None)
|
53
|
+
|
54
|
+
if not base_url:
|
55
|
+
# Attempt to get server_url from instance.sdk_configuration.server_url
|
56
|
+
config = getattr(instance, "sdk_configuration", None)
|
57
|
+
base_url = getattr(config, "server_url", None)
|
58
|
+
|
59
|
+
if base_url:
|
60
|
+
if isinstance(base_url, str):
|
61
|
+
# Check if it a full URL or just a hostname
|
62
|
+
if base_url.startswith(("http://", "https://")):
|
63
|
+
try:
|
64
|
+
url = urlparse(base_url)
|
65
|
+
if url.hostname:
|
66
|
+
server_address = url.hostname
|
67
|
+
if url.port:
|
68
|
+
server_port = url.port
|
69
|
+
except Exception:
|
70
|
+
pass
|
71
|
+
else:
|
72
|
+
# Just a hostname
|
73
|
+
server_address = base_url
|
74
|
+
|
75
|
+
return server_address, server_port
|
76
|
+
|
32
77
|
def common_vectordb_logic(scope, environment, application_name,
|
33
78
|
metrics, capture_message_content, disable_metrics, version, instance=None, endpoint=None):
|
34
79
|
"""
|
@@ -120,8 +165,8 @@ def common_vectordb_logic(scope, environment, application_name,
|
|
120
165
|
# Extract response metrics if available
|
121
166
|
if scope._response:
|
122
167
|
# Get number of results returned
|
123
|
-
if hasattr(scope._response,
|
124
|
-
returned_rows = object_count(scope._response[
|
168
|
+
if hasattr(scope._response, "get") and scope._response.get("ids"):
|
169
|
+
returned_rows = object_count(scope._response["ids"][0]) if scope._response["ids"] else 0
|
125
170
|
scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS, returned_rows)
|
126
171
|
|
127
172
|
scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"""
|
2
|
+
OpenLIT Milvus Instrumentation
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Collection
|
6
|
+
import importlib.metadata
|
7
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
8
|
+
from wrapt import wrap_function_wrapper
|
9
|
+
|
10
|
+
from openlit.instrumentation.milvus.milvus import general_wrap
|
11
|
+
|
12
|
+
_instruments = ("pymilvus >= 2.4.3",)
|
13
|
+
|
14
|
+
# Operations to wrap for Milvus client
|
15
|
+
MILVUS_OPERATIONS = [
|
16
|
+
("create_collection", "milvus.create_collection"),
|
17
|
+
("drop_collection", "milvus.drop_collection"),
|
18
|
+
("insert", "milvus.insert"),
|
19
|
+
("upsert", "milvus.upsert"),
|
20
|
+
("search", "milvus.search"),
|
21
|
+
("query", "milvus.query"),
|
22
|
+
("get", "milvus.get"),
|
23
|
+
("delete", "milvus.delete"),
|
24
|
+
]
|
25
|
+
|
26
|
+
class MilvusInstrumentor(BaseInstrumentor):
|
27
|
+
"""
|
28
|
+
An instrumentor for Milvus's client library.
|
29
|
+
"""
|
30
|
+
|
31
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
32
|
+
return _instruments
|
33
|
+
|
34
|
+
def _instrument(self, **kwargs):
|
35
|
+
version = importlib.metadata.version("pymilvus")
|
36
|
+
environment = kwargs.get("environment", "default")
|
37
|
+
application_name = kwargs.get("application_name", "default")
|
38
|
+
tracer = kwargs.get("tracer")
|
39
|
+
pricing_info = kwargs.get("pricing_info", {})
|
40
|
+
capture_message_content = kwargs.get("capture_message_content", False)
|
41
|
+
metrics = kwargs.get("metrics_dict")
|
42
|
+
disable_metrics = kwargs.get("disable_metrics")
|
43
|
+
|
44
|
+
# Wrap operations
|
45
|
+
for method_name, endpoint in MILVUS_OPERATIONS:
|
46
|
+
wrap_function_wrapper(
|
47
|
+
"pymilvus",
|
48
|
+
f"MilvusClient.{method_name}",
|
49
|
+
general_wrap(
|
50
|
+
endpoint, version, environment, application_name, tracer,
|
51
|
+
pricing_info, capture_message_content, metrics, disable_metrics
|
52
|
+
),
|
53
|
+
)
|
54
|
+
|
55
|
+
def _uninstrument(self, **kwargs):
|
56
|
+
pass
|