openlit 1.10.0__tar.gz → 1.13.0__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.10.0 → openlit-1.13.0}/PKG-INFO +18 -15
- {openlit-1.10.0 → openlit-1.13.0}/README.md +17 -14
- {openlit-1.10.0 → openlit-1.13.0}/pyproject.toml +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/__init__.py +220 -32
- openlit-1.13.0/src/openlit/instrumentation/gpt4all/__init__.py +52 -0
- openlit-1.13.0/src/openlit/instrumentation/gpt4all/gpt4all.py +352 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/async_groq.py +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/groq.py +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/async_azure_openai.py +2 -2
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/async_openai.py +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/azure_openai.py +2 -2
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/openai.py +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/transformers/transformers.py +1 -1
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/semcov/__init__.py +4 -3
- {openlit-1.10.0 → openlit-1.13.0}/LICENSE +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/__helpers.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/anthropic.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/anthropic/async_anthropic.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/bedrock/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/bedrock/bedrock.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/chroma/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/chroma/chroma.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/cohere/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/cohere/cohere.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/embedchain/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/embedchain/embedchain.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/groq/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/haystack/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/haystack/haystack.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/langchain/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/langchain/langchain.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/llamaindex/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/llamaindex/llamaindex.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/milvus/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/milvus/milvus.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/async_mistral.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/mistral/mistral.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/async_ollama.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/ollama/ollama.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/openai/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/pinecone/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/pinecone/pinecone.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/qdrant/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/qdrant/qdrant.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/transformers/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/__init__.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/async_vertexai.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/instrumentation/vertexai/vertexai.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/otel/metrics.py +0 -0
- {openlit-1.10.0 → openlit-1.13.0}/src/openlit/otel/tracing.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: openlit
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.13.0
|
4
4
|
Summary: OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications, facilitating the integration of observability into your GenAI-driven projects
|
5
5
|
Home-page: https://github.com/openlit/openlit/tree/main/openlit/python
|
6
6
|
Keywords: OpenTelemetry,otel,otlp,llm,tracing,openai,anthropic,claude,cohere,llm monitoring,observability,monitoring,gpt,Generative AI,chatGPT
|
@@ -36,7 +36,8 @@ OpenTelemetry Auto-Instrumentation for GenAI & LLM Applications</h1>
|
|
36
36
|
[](https://github.com/openlit/openlit/graphs/contributors)
|
37
37
|
|
38
38
|
[](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
|
39
|
-
[](https://discord.gg/rjvTm6zd)
|
40
|
+
[](https://twitter.com/openlit_io)
|
40
41
|
|
41
42
|

|
42
43
|
|
@@ -51,26 +52,28 @@ This project adheres to the [Semantic Conventions](https://github.com/open-telem
|
|
51
52
|
|
52
53
|
## Auto Instrumentation Capabilities
|
53
54
|
|
54
|
-
| LLMs
|
55
|
-
|
56
|
-
| [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai)
|
57
|
-
| [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama)
|
58
|
-
| [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic)
|
59
|
-
| [✅
|
60
|
-
| [✅
|
61
|
-
| [✅
|
55
|
+
| LLMs | Vector DBs | Frameworks |
|
56
|
+
|-----------------------------------------------------------------|----------------------------------------------|----------------------------------------------|
|
57
|
+
| [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
|
58
|
+
| [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
|
59
|
+
| [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
|
60
|
+
| [✅ GPT4All](https://docs.openlit.io/latest/integrations/gpt4all) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
|
61
|
+
| [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | | [✅ EmbedChain](https://docs.openlit.io/latest/integrations/embedchain) |
|
62
|
+
| [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
|
63
|
+
| [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
|
62
64
|
| [✅ HuggingFace Transformers](https://docs.openlit.io/latest/integrations/huggingface) | |
|
63
|
-
| [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock)
|
65
|
+
| [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
|
64
66
|
| [✅ Vertex AI](https://docs.openlit.io/latest/integrations/vertexai) | |
|
65
|
-
| [✅ Groq](https://docs.openlit.io/latest/integrations/groq)
|
67
|
+
| [✅ Groq](https://docs.openlit.io/latest/integrations/groq) |
|
66
68
|
|
67
69
|
## Supported Destinations
|
68
70
|
- [✅ OpenTelemetry Collector](https://docs.openlit.io/latest/connections/otelcol)
|
69
71
|
- [✅ Prometheus + Tempo](https://docs.openlit.io/latest/connections/prometheus-tempo)
|
70
72
|
- [✅ Prometheus + Jaeger](https://docs.openlit.io/latest/connections/prometheus-jaeger)
|
71
73
|
- [✅ Grafana Cloud](https://docs.openlit.io/latest/connections/grafanacloud)
|
72
|
-
- [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
|
73
74
|
- [✅ New Relic](https://docs.openlit.io/latest/connections/new-relic)
|
75
|
+
- [✅ Elastic](https://docs.openlit.io/latest/connections/elastic)
|
76
|
+
- [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
|
74
77
|
- [✅ SigNoz](https://docs.openlit.io/latest/connections/signoz)
|
75
78
|
- [✅ Dynatrace](https://docs.openlit.io/latest/connections/dynatrace)
|
76
79
|
- [✅ OpenObserve](https://docs.openlit.io/latest/connections/openobserve)
|
@@ -189,7 +192,7 @@ Whether it's big or small, we love contributions 💚. Check out our [Contributi
|
|
189
192
|
|
190
193
|
Unsure where to start? Here are a few ways to get involved:
|
191
194
|
|
192
|
-
- Join our [Slack
|
195
|
+
- Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
|
193
196
|
|
194
197
|
Your input helps us grow and improve, and we're here to support you every step of the way.
|
195
198
|
|
@@ -198,7 +201,7 @@ Your input helps us grow and improve, and we're here to support you every step o
|
|
198
201
|
Connect with the OpenLIT community and maintainers for support, discussions, and updates:
|
199
202
|
|
200
203
|
- 🌟 If you like it, Leave a star on our [GitHub](https://github.com/openlit/openlit/)
|
201
|
-
- 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
|
204
|
+
- 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community for live interactions and questions.
|
202
205
|
- 🐞 Report bugs on our [GitHub Issues](https://github.com/openlit/openlit/issues) to help us improve OpenLIT.
|
203
206
|
- 𝕏 Follow us on [X](https://x.com/openlit_io) for the latest updates and news.
|
204
207
|
|
@@ -11,7 +11,8 @@ OpenTelemetry Auto-Instrumentation for GenAI & LLM Applications</h1>
|
|
11
11
|
[](https://github.com/openlit/openlit/graphs/contributors)
|
12
12
|
|
13
13
|
[](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
|
14
|
-
[](https://discord.gg/rjvTm6zd)
|
15
|
+
[](https://twitter.com/openlit_io)
|
15
16
|
|
16
17
|

|
17
18
|
|
@@ -26,26 +27,28 @@ This project adheres to the [Semantic Conventions](https://github.com/open-telem
|
|
26
27
|
|
27
28
|
## Auto Instrumentation Capabilities
|
28
29
|
|
29
|
-
| LLMs
|
30
|
-
|
31
|
-
| [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai)
|
32
|
-
| [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama)
|
33
|
-
| [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic)
|
34
|
-
| [✅
|
35
|
-
| [✅
|
36
|
-
| [✅
|
30
|
+
| LLMs | Vector DBs | Frameworks |
|
31
|
+
|-----------------------------------------------------------------|----------------------------------------------|----------------------------------------------|
|
32
|
+
| [✅ OpenAI](https://docs.openlit.io/latest/integrations/openai) | [✅ ChromaDB](https://docs.openlit.io/latest/integrations/chromadb) | [✅ Langchain](https://docs.openlit.io/latest/integrations/langchain) |
|
33
|
+
| [✅ Ollama](https://docs.openlit.io/latest/integrations/ollama) | [✅ Pinecone](https://docs.openlit.io/latest/integrations/pinecone) | [✅ LiteLLM](https://docs.openlit.io/latest/integrations/litellm) |
|
34
|
+
| [✅ Anthropic](https://docs.openlit.io/latest/integrations/anthropic) | [✅ Qdrant](https://docs.openlit.io/latest/integrations/qdrant) | [✅ LlamaIndex](https://docs.openlit.io/latest/integrations/llama-index) |
|
35
|
+
| [✅ GPT4All](https://docs.openlit.io/latest/integrations/gpt4all) | [✅ Milvus](https://docs.openlit.io/latest/integrations/milvus) | [✅ Haystack](https://docs.openlit.io/latest/integrations/haystack) |
|
36
|
+
| [✅ Cohere](https://docs.openlit.io/latest/integrations/cohere) | | [✅ EmbedChain](https://docs.openlit.io/latest/integrations/embedchain) |
|
37
|
+
| [✅ Mistral](https://docs.openlit.io/latest/integrations/mistral) | |
|
38
|
+
| [✅ Azure OpenAI](https://docs.openlit.io/latest/integrations/azure-openai) | |
|
37
39
|
| [✅ HuggingFace Transformers](https://docs.openlit.io/latest/integrations/huggingface) | |
|
38
|
-
| [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock)
|
40
|
+
| [✅ Amazon Bedrock](https://docs.openlit.io/latest/integrations/bedrock) | |
|
39
41
|
| [✅ Vertex AI](https://docs.openlit.io/latest/integrations/vertexai) | |
|
40
|
-
| [✅ Groq](https://docs.openlit.io/latest/integrations/groq)
|
42
|
+
| [✅ Groq](https://docs.openlit.io/latest/integrations/groq) |
|
41
43
|
|
42
44
|
## Supported Destinations
|
43
45
|
- [✅ OpenTelemetry Collector](https://docs.openlit.io/latest/connections/otelcol)
|
44
46
|
- [✅ Prometheus + Tempo](https://docs.openlit.io/latest/connections/prometheus-tempo)
|
45
47
|
- [✅ Prometheus + Jaeger](https://docs.openlit.io/latest/connections/prometheus-jaeger)
|
46
48
|
- [✅ Grafana Cloud](https://docs.openlit.io/latest/connections/grafanacloud)
|
47
|
-
- [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
|
48
49
|
- [✅ New Relic](https://docs.openlit.io/latest/connections/new-relic)
|
50
|
+
- [✅ Elastic](https://docs.openlit.io/latest/connections/elastic)
|
51
|
+
- [✅ DataDog](https://docs.openlit.io/latest/connections/datadog)
|
49
52
|
- [✅ SigNoz](https://docs.openlit.io/latest/connections/signoz)
|
50
53
|
- [✅ Dynatrace](https://docs.openlit.io/latest/connections/dynatrace)
|
51
54
|
- [✅ OpenObserve](https://docs.openlit.io/latest/connections/openobserve)
|
@@ -164,7 +167,7 @@ Whether it's big or small, we love contributions 💚. Check out our [Contributi
|
|
164
167
|
|
165
168
|
Unsure where to start? Here are a few ways to get involved:
|
166
169
|
|
167
|
-
- Join our [Slack
|
170
|
+
- Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
|
168
171
|
|
169
172
|
Your input helps us grow and improve, and we're here to support you every step of the way.
|
170
173
|
|
@@ -173,6 +176,6 @@ Your input helps us grow and improve, and we're here to support you every step o
|
|
173
176
|
Connect with the OpenLIT community and maintainers for support, discussions, and updates:
|
174
177
|
|
175
178
|
- 🌟 If you like it, Leave a star on our [GitHub](https://github.com/openlit/openlit/)
|
176
|
-
- 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
|
179
|
+
- 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community for live interactions and questions.
|
177
180
|
- 🐞 Report bugs on our [GitHub Issues](https://github.com/openlit/openlit/issues) to help us improve OpenLIT.
|
178
181
|
- 𝕏 Follow us on [X](https://x.com/openlit_io) for the latest updates and news.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "openlit"
|
3
|
-
version = "1.
|
3
|
+
version = "1.13.0"
|
4
4
|
description = "OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications, facilitating the integration of observability into your GenAI-driven projects"
|
5
5
|
authors = ["OpenLIT"]
|
6
6
|
repository = "https://github.com/openlit/openlit/tree/main/openlit/python"
|
@@ -1,17 +1,26 @@
|
|
1
|
+
# pylint: disable=broad-exception-caught
|
1
2
|
"""
|
2
3
|
The __init__.py module for the openLIT package.
|
3
4
|
This module sets up the openLIT configuration and instrumentation for various
|
4
5
|
large language models (LLMs).
|
5
6
|
"""
|
7
|
+
|
6
8
|
from typing import Dict
|
7
9
|
import logging
|
8
10
|
from importlib.util import find_spec
|
11
|
+
from functools import wraps
|
12
|
+
from contextlib import contextmanager
|
13
|
+
|
9
14
|
|
10
15
|
# Import internal modules for setting up tracing and fetching pricing info.
|
16
|
+
from opentelemetry import trace as t
|
17
|
+
from opentelemetry.trace import SpanKind, Status, StatusCode, Span
|
18
|
+
from openlit.semcov import SemanticConvetion
|
11
19
|
from openlit.otel.tracing import setup_tracing
|
12
20
|
from openlit.otel.metrics import setup_meter
|
13
21
|
from openlit.__helpers import fetch_pricing_info
|
14
22
|
|
23
|
+
|
15
24
|
# Instrumentors for various large language models.
|
16
25
|
from openlit.instrumentation.openai import OpenAIInstrumentor
|
17
26
|
from openlit.instrumentation.anthropic import AnthropicInstrumentor
|
@@ -21,6 +30,7 @@ from openlit.instrumentation.bedrock import BedrockInstrumentor
|
|
21
30
|
from openlit.instrumentation.vertexai import VertexAIInstrumentor
|
22
31
|
from openlit.instrumentation.groq import GroqInstrumentor
|
23
32
|
from openlit.instrumentation.ollama import OllamaInstrumentor
|
33
|
+
from openlit.instrumentation.gpt4all import GPT4AllInstrumentor
|
24
34
|
from openlit.instrumentation.langchain import LangChainInstrumentor
|
25
35
|
from openlit.instrumentation.llamaindex import LlamaIndexInstrumentor
|
26
36
|
from openlit.instrumentation.haystack import HaystackInstrumentor
|
@@ -34,13 +44,14 @@ from openlit.instrumentation.transformers import TransformersInstrumentor
|
|
34
44
|
# Set up logging for error and information messages.
|
35
45
|
logger = logging.getLogger(__name__)
|
36
46
|
|
47
|
+
|
37
48
|
class OpenlitConfig:
|
38
49
|
"""
|
39
50
|
A Singleton Configuration class for openLIT.
|
40
|
-
|
51
|
+
|
41
52
|
This class maintains a single instance of configuration settings including
|
42
53
|
environment details, application name, and tracing information throughout the openLIT package.
|
43
|
-
|
54
|
+
|
44
55
|
Attributes:
|
45
56
|
environment (str): Deployment environment of the application.
|
46
57
|
application_name (str): Name of the application using openLIT.
|
@@ -51,6 +62,7 @@ class OpenlitConfig:
|
|
51
62
|
disable_batch (bool): Flag to disable batch span processing in tracing.
|
52
63
|
trace_content (bool): Flag to enable or disable tracing of content.
|
53
64
|
"""
|
65
|
+
|
54
66
|
_instance = None
|
55
67
|
|
56
68
|
def __new__(cls):
|
@@ -75,9 +87,19 @@ class OpenlitConfig:
|
|
75
87
|
cls.disable_metrics = False
|
76
88
|
|
77
89
|
@classmethod
|
78
|
-
def update_config(
|
79
|
-
|
80
|
-
|
90
|
+
def update_config(
|
91
|
+
cls,
|
92
|
+
environment,
|
93
|
+
application_name,
|
94
|
+
tracer,
|
95
|
+
otlp_endpoint,
|
96
|
+
otlp_headers,
|
97
|
+
disable_batch,
|
98
|
+
trace_content,
|
99
|
+
metrics_dict,
|
100
|
+
disable_metrics,
|
101
|
+
pricing_json,
|
102
|
+
):
|
81
103
|
"""
|
82
104
|
Updates the configuration based on provided parameters.
|
83
105
|
|
@@ -103,8 +125,14 @@ class OpenlitConfig:
|
|
103
125
|
cls.trace_content = trace_content
|
104
126
|
cls.disable_metrics = disable_metrics
|
105
127
|
|
106
|
-
|
107
|
-
|
128
|
+
|
129
|
+
def instrument_if_available(
|
130
|
+
instrumentor_name,
|
131
|
+
instrumentor_instance,
|
132
|
+
config,
|
133
|
+
disabled_instrumentors,
|
134
|
+
module_name_map,
|
135
|
+
):
|
108
136
|
"""Instruments the specified instrumentor if its library is available."""
|
109
137
|
if instrumentor_name in disabled_instrumentors:
|
110
138
|
return
|
@@ -120,22 +148,33 @@ def instrument_if_available(instrumentor_name, instrumentor_instance, config,
|
|
120
148
|
pricing_info=config.pricing_info,
|
121
149
|
trace_content=config.trace_content,
|
122
150
|
metrics_dict=config.metrics_dict,
|
123
|
-
disable_metrics=config.disable_metrics
|
151
|
+
disable_metrics=config.disable_metrics,
|
124
152
|
)
|
125
153
|
|
126
154
|
# pylint: disable=broad-exception-caught
|
127
155
|
except Exception as e:
|
128
156
|
logger.error("Failed to instrument %s: %s", instrumentor_name, e)
|
129
157
|
|
130
|
-
|
131
|
-
|
132
|
-
|
158
|
+
|
159
|
+
def init(
|
160
|
+
environment="default",
|
161
|
+
application_name="default",
|
162
|
+
tracer=None,
|
163
|
+
otlp_endpoint=None,
|
164
|
+
otlp_headers=None,
|
165
|
+
disable_batch=False,
|
166
|
+
trace_content=True,
|
167
|
+
disabled_instrumentors=None,
|
168
|
+
meter=None,
|
169
|
+
disable_metrics=False,
|
170
|
+
pricing_json=None,
|
171
|
+
):
|
133
172
|
"""
|
134
173
|
Initializes the openLIT configuration and setups tracing.
|
135
|
-
|
136
|
-
This function sets up the openLIT environment with provided configurations
|
174
|
+
|
175
|
+
This function sets up the openLIT environment with provided configurations
|
137
176
|
and initializes instrumentors for tracing.
|
138
|
-
|
177
|
+
|
139
178
|
Args:
|
140
179
|
environment (str): Deployment environment.
|
141
180
|
application_name (str): Application name.
|
@@ -154,13 +193,14 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
154
193
|
|
155
194
|
module_name_map = {
|
156
195
|
"openai": "openai",
|
157
|
-
"anthropic": "anthropic",
|
158
|
-
"cohere": "cohere",
|
196
|
+
"anthropic": "anthropic",
|
197
|
+
"cohere": "cohere",
|
159
198
|
"mistral": "mistralai",
|
160
199
|
"bedrock": "boto3",
|
161
200
|
"vertexai": "vertexai",
|
162
201
|
"groq": "groq",
|
163
202
|
"ollama": "ollama",
|
203
|
+
"gpt4all": "gpt4all",
|
164
204
|
"langchain": "langchain",
|
165
205
|
"llama_index": "llama_index",
|
166
206
|
"haystack": "haystack",
|
@@ -169,12 +209,16 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
169
209
|
"pinecone": "pinecone",
|
170
210
|
"qdrant": "qdrant_client",
|
171
211
|
"milvus": "pymilvus",
|
172
|
-
"transformers": "transformers"
|
212
|
+
"transformers": "transformers",
|
173
213
|
}
|
174
214
|
|
175
|
-
invalid_instrumentors = [
|
215
|
+
invalid_instrumentors = [
|
216
|
+
name for name in disabled_instrumentors if name not in module_name_map
|
217
|
+
]
|
176
218
|
for invalid_name in invalid_instrumentors:
|
177
|
-
logger.warning(
|
219
|
+
logger.warning(
|
220
|
+
"Invalid instrumentor name detected and ignored: '%s'", invalid_name
|
221
|
+
)
|
178
222
|
|
179
223
|
try:
|
180
224
|
# Retrieve or create the single configuration instance.
|
@@ -183,9 +227,11 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
183
227
|
# Setup tracing based on the provided or default configuration.
|
184
228
|
tracer = setup_tracing(
|
185
229
|
application_name=application_name,
|
186
|
-
environment=environment,
|
187
|
-
|
188
|
-
|
230
|
+
environment=environment,
|
231
|
+
tracer=tracer,
|
232
|
+
otlp_endpoint=otlp_endpoint,
|
233
|
+
otlp_headers=otlp_headers,
|
234
|
+
disable_batch=disable_batch,
|
189
235
|
)
|
190
236
|
|
191
237
|
if not tracer:
|
@@ -193,18 +239,31 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
193
239
|
return
|
194
240
|
|
195
241
|
# Setup meter and receive metrics_dict instead of meter
|
196
|
-
metrics_dict = setup_meter(
|
197
|
-
|
198
|
-
|
242
|
+
metrics_dict = setup_meter(
|
243
|
+
application_name=application_name,
|
244
|
+
environment=environment,
|
245
|
+
meter=meter,
|
246
|
+
otlp_endpoint=otlp_endpoint,
|
247
|
+
otlp_headers=otlp_headers,
|
248
|
+
)
|
199
249
|
|
200
250
|
if not metrics_dict:
|
201
251
|
logger.error("openLIT metrics setup failed. Metrics will not be available.")
|
202
252
|
return
|
203
253
|
|
204
254
|
# Update global configuration with the provided settings.
|
205
|
-
config.update_config(
|
206
|
-
|
207
|
-
|
255
|
+
config.update_config(
|
256
|
+
environment,
|
257
|
+
application_name,
|
258
|
+
tracer,
|
259
|
+
otlp_endpoint,
|
260
|
+
otlp_headers,
|
261
|
+
disable_batch,
|
262
|
+
trace_content,
|
263
|
+
metrics_dict,
|
264
|
+
disable_metrics,
|
265
|
+
pricing_json,
|
266
|
+
)
|
208
267
|
|
209
268
|
# Map instrumentor names to their instances
|
210
269
|
instrumentor_instances = {
|
@@ -216,6 +275,7 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
216
275
|
"vertexai": VertexAIInstrumentor(),
|
217
276
|
"groq": GroqInstrumentor(),
|
218
277
|
"ollama": OllamaInstrumentor(),
|
278
|
+
"gpt4all": GPT4AllInstrumentor(),
|
219
279
|
"langchain": LangChainInstrumentor(),
|
220
280
|
"llama_index": LlamaIndexInstrumentor(),
|
221
281
|
"haystack": HaystackInstrumentor(),
|
@@ -224,14 +284,142 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
|
|
224
284
|
"pinecone": PineconeInstrumentor(),
|
225
285
|
"qdrant": QdrantInstrumentor(),
|
226
286
|
"milvus": MilvusInstrumentor(),
|
227
|
-
"transformers": TransformersInstrumentor()
|
287
|
+
"transformers": TransformersInstrumentor(),
|
228
288
|
}
|
229
289
|
|
230
290
|
# Initialize and instrument only the enabled instrumentors
|
231
291
|
for name, instrumentor in instrumentor_instances.items():
|
232
|
-
instrument_if_available(
|
233
|
-
|
292
|
+
instrument_if_available(
|
293
|
+
name, instrumentor, config, disabled_instrumentors, module_name_map
|
294
|
+
)
|
234
295
|
|
235
|
-
# pylint: disable=broad-exception-caught
|
236
296
|
except Exception as e:
|
237
297
|
logger.error("Error during openLIT initialization: %s", e)
|
298
|
+
|
299
|
+
|
300
|
+
def trace(wrapped):
|
301
|
+
"""
|
302
|
+
Generates a telemetry wrapper for messages to collect metrics.
|
303
|
+
"""
|
304
|
+
|
305
|
+
@wraps(wrapped)
|
306
|
+
def wrapper(*args, **kwargs):
|
307
|
+
__trace = t.get_tracer_provider()
|
308
|
+
with __trace.get_tracer(__name__).start_as_current_span(
|
309
|
+
name=wrapped.__name__,
|
310
|
+
kind=SpanKind.CLIENT,
|
311
|
+
) as span:
|
312
|
+
try:
|
313
|
+
response = wrapped(*args, **kwargs)
|
314
|
+
span.set_attribute(
|
315
|
+
SemanticConvetion.GEN_AI_CONTENT_COMPLETION, response
|
316
|
+
)
|
317
|
+
span.set_status(Status(StatusCode.OK))
|
318
|
+
|
319
|
+
except Exception as e:
|
320
|
+
response = None
|
321
|
+
span.record_exception(e)
|
322
|
+
span.set_status(status=Status(StatusCode.ERROR), description=e)
|
323
|
+
logging.error("Error in %s: %s", wrapped.__name__, e, exc_info=True)
|
324
|
+
|
325
|
+
# Adding function arguments as metadata
|
326
|
+
try:
|
327
|
+
span.set_attribute("function.args", str(args))
|
328
|
+
span.set_attribute("function.kwargs", str(kwargs))
|
329
|
+
span.set_attribute(
|
330
|
+
SemanticConvetion.GEN_AI_APPLICATION_NAME,
|
331
|
+
OpenlitConfig.application_name,
|
332
|
+
)
|
333
|
+
span.set_attribute(
|
334
|
+
SemanticConvetion.GEN_AI_ENVIRONMENT, OpenlitConfig.environment
|
335
|
+
)
|
336
|
+
|
337
|
+
except Exception as meta_exception:
|
338
|
+
logging.error(
|
339
|
+
"Failed to set metadata for %s: %s",
|
340
|
+
wrapped.__name__,
|
341
|
+
meta_exception,
|
342
|
+
exc_info=True,
|
343
|
+
)
|
344
|
+
|
345
|
+
return response
|
346
|
+
|
347
|
+
return wrapper
|
348
|
+
|
349
|
+
|
350
|
+
class TracedSpan:
|
351
|
+
"""
|
352
|
+
A wrapper class for an OpenTelemetry span that provides helper methods
|
353
|
+
for setting result and metadata attributes on the span.
|
354
|
+
|
355
|
+
Attributes:
|
356
|
+
_span (Span): The underlying OpenTelemetry span.
|
357
|
+
"""
|
358
|
+
|
359
|
+
def __init__(self, span):
|
360
|
+
"""
|
361
|
+
Initializes the TracedSpan with the given span.
|
362
|
+
|
363
|
+
Params:
|
364
|
+
span (Span): The OpenTelemetry span to be wrapped.
|
365
|
+
"""
|
366
|
+
|
367
|
+
self._span: Span = span
|
368
|
+
|
369
|
+
def set_result(self, result):
|
370
|
+
"""
|
371
|
+
Sets the result attribute on the underlying span.
|
372
|
+
|
373
|
+
Params:
|
374
|
+
result: The result to be set as an attribute on the span.
|
375
|
+
"""
|
376
|
+
|
377
|
+
self._span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION, result)
|
378
|
+
|
379
|
+
def set_metadata(self, metadata: Dict):
|
380
|
+
"""
|
381
|
+
Sets multiple attributes on the underlying span.
|
382
|
+
|
383
|
+
Params:
|
384
|
+
metadata (Dict): A dictionary of attributes to be set on the span.
|
385
|
+
"""
|
386
|
+
|
387
|
+
self._span.set_attributes(attributes=metadata)
|
388
|
+
|
389
|
+
def __enter__(self):
|
390
|
+
"""
|
391
|
+
Enters the context of the TracedSpan, returning itself.
|
392
|
+
|
393
|
+
Returns:
|
394
|
+
TracedSpan: The instance of TracedSpan.
|
395
|
+
"""
|
396
|
+
|
397
|
+
return self
|
398
|
+
|
399
|
+
def __exit__(self, _exc_type, _exc_val, _exc_tb):
|
400
|
+
"""
|
401
|
+
Exits the context of the TracedSpan by ending the underlying span.
|
402
|
+
"""
|
403
|
+
|
404
|
+
self._span.end()
|
405
|
+
|
406
|
+
|
407
|
+
@contextmanager
|
408
|
+
def start_trace(name: str):
|
409
|
+
"""
|
410
|
+
A context manager that starts a new trace and provides a TracedSpan
|
411
|
+
for usage within the context.
|
412
|
+
|
413
|
+
Params:
|
414
|
+
name (str): The name of the span.
|
415
|
+
|
416
|
+
Yields:
|
417
|
+
TracedSpan: The wrapped span for trace operations.
|
418
|
+
"""
|
419
|
+
|
420
|
+
__trace = t.get_tracer_provider()
|
421
|
+
with __trace.get_tracer(__name__).start_as_current_span(
|
422
|
+
name,
|
423
|
+
kind=SpanKind.CLIENT,
|
424
|
+
) as span:
|
425
|
+
yield TracedSpan(span)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# pylint: disable=useless-return, bad-staticmethod-argument, disable=duplicate-code
|
2
|
+
"""Initializer of Auto Instrumentation of GPT4All Functions"""
|
3
|
+
|
4
|
+
from typing import Collection
|
5
|
+
import importlib.metadata
|
6
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
7
|
+
from wrapt import wrap_function_wrapper
|
8
|
+
|
9
|
+
from openlit.instrumentation.gpt4all.gpt4all import (
|
10
|
+
embed, generate
|
11
|
+
)
|
12
|
+
|
13
|
+
_instruments = ("gpt4all >= 2.6.0",)
|
14
|
+
|
15
|
+
class GPT4AllInstrumentor(BaseInstrumentor):
|
16
|
+
"""
|
17
|
+
An instrumentor for GPT4All's client library.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
21
|
+
return _instruments
|
22
|
+
|
23
|
+
def _instrument(self, **kwargs):
|
24
|
+
application_name = kwargs.get("application_name", "default_application")
|
25
|
+
environment = kwargs.get("environment", "default_environment")
|
26
|
+
tracer = kwargs.get("tracer")
|
27
|
+
metrics = kwargs.get("metrics_dict")
|
28
|
+
pricing_info = kwargs.get("pricing_info", {})
|
29
|
+
trace_content = kwargs.get("trace_content", False)
|
30
|
+
disable_metrics = kwargs.get("disable_metrics")
|
31
|
+
version = importlib.metadata.version("gpt4all")
|
32
|
+
|
33
|
+
# generate
|
34
|
+
wrap_function_wrapper(
|
35
|
+
"gpt4all",
|
36
|
+
"GPT4All.generate",
|
37
|
+
generate("gpt4all.generate", version, environment, application_name,
|
38
|
+
tracer, pricing_info, trace_content, metrics, disable_metrics),
|
39
|
+
)
|
40
|
+
|
41
|
+
# embed
|
42
|
+
wrap_function_wrapper(
|
43
|
+
"gpt4all",
|
44
|
+
"Embed4All.embed",
|
45
|
+
embed("gpt4all.embed", version, environment, application_name,
|
46
|
+
tracer, pricing_info, trace_content, metrics, disable_metrics),
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
def _uninstrument(self, **kwargs):
|
51
|
+
# Proper uninstrumentation logic to revert patched methods
|
52
|
+
pass
|
@@ -0,0 +1,352 @@
|
|
1
|
+
# pylint: disable=duplicate-code, broad-exception-caught, too-many-statements, unused-argument, possibly-used-before-assignment
|
2
|
+
"""
|
3
|
+
Module for monitoring GPT4All API calls.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import logging
|
7
|
+
from opentelemetry.trace import SpanKind, Status, StatusCode
|
8
|
+
from opentelemetry.sdk.resources import TELEMETRY_SDK_NAME
|
9
|
+
from openlit.__helpers import handle_exception, general_tokens
|
10
|
+
from openlit.semcov import SemanticConvetion
|
11
|
+
|
12
|
+
# Initialize logger for logging potential issues and operations
|
13
|
+
logger = logging.getLogger(__name__)
|
14
|
+
|
15
|
+
def generate(gen_ai_endpoint, version, environment, application_name,
|
16
|
+
tracer, pricing_info, trace_content, metrics, disable_metrics):
|
17
|
+
"""
|
18
|
+
Generates a telemetry wrapper for generate to collect metrics.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
gen_ai_endpoint: Endpoint identifier for logging and tracing.
|
22
|
+
version: Version of the monitoring package.
|
23
|
+
environment: Deployment environment (e.g., production, staging).
|
24
|
+
application_name: Name of the application using the GPT4All API.
|
25
|
+
tracer: OpenTelemetry tracer for creating spans.
|
26
|
+
pricing_info: Information used for calculating the cost of GPT4All usage.
|
27
|
+
trace_content: Flag indicating whether to trace the actual content.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
A function that wraps the generate method to add telemetry.
|
31
|
+
"""
|
32
|
+
|
33
|
+
def wrapper(wrapped, instance, args, kwargs):
|
34
|
+
"""
|
35
|
+
Wraps the 'generate' API call to add telemetry.
|
36
|
+
|
37
|
+
This collects metrics such as execution time, cost, and token usage, and handles errors
|
38
|
+
gracefully, adding details to the trace for observability.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
wrapped: The original 'generate' method to be wrapped.
|
42
|
+
instance: The instance of the class where the original method is defined.
|
43
|
+
args: Positional arguments for the 'generate' method.
|
44
|
+
kwargs: Keyword arguments for the 'generate' method.
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
The response from the original 'generate' method.
|
48
|
+
"""
|
49
|
+
|
50
|
+
# Check if streaming is enabled for the API call
|
51
|
+
streaming = kwargs.get("streaming", False)
|
52
|
+
|
53
|
+
# pylint: disable=no-else-return
|
54
|
+
if streaming:
|
55
|
+
# Special handling for streaming response to accommodate the nature of data flow
|
56
|
+
def stream_generator():
|
57
|
+
with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
|
58
|
+
# Placeholder for aggregating streaming response
|
59
|
+
llmresponse = ""
|
60
|
+
|
61
|
+
# Loop through streaming events capturing relevant details
|
62
|
+
for chunk in wrapped(*args, **kwargs):
|
63
|
+
# Collect aggregated response from events
|
64
|
+
llmresponse += chunk
|
65
|
+
|
66
|
+
yield chunk
|
67
|
+
|
68
|
+
# Handling exception ensure observability without disrupting operation
|
69
|
+
try:
|
70
|
+
# Calculate cost of the operation
|
71
|
+
cost = 0
|
72
|
+
|
73
|
+
# pylint: disable=line-too-long
|
74
|
+
model = str(instance.model.model_path).rsplit('/', maxsplit=1)[-1] or "orca-mini-3b-gguf2-q4_0.gguf"
|
75
|
+
prompt = kwargs.get("prompt") or args[0] or ""
|
76
|
+
|
77
|
+
# Calculate cost of the operation
|
78
|
+
cost = 0
|
79
|
+
prompt_tokens = general_tokens(prompt)
|
80
|
+
completion_tokens = general_tokens(llmresponse)
|
81
|
+
total_tokens = prompt_tokens + completion_tokens
|
82
|
+
|
83
|
+
# Set base span attribues
|
84
|
+
span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
|
85
|
+
span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
|
86
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
|
87
|
+
span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
|
88
|
+
SemanticConvetion.GEN_AI_TYPE_CHAT)
|
89
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
|
90
|
+
gen_ai_endpoint)
|
91
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
|
92
|
+
environment)
|
93
|
+
span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
|
94
|
+
application_name)
|
95
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
|
96
|
+
model)
|
97
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_K,
|
98
|
+
kwargs.get("top_k", 40))
|
99
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_P,
|
100
|
+
kwargs.get("top_p", 0.4))
|
101
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MAX_TOKENS,
|
102
|
+
kwargs.get("max_tokens", 200))
|
103
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TEMPERATURE,
|
104
|
+
kwargs.get("temperature", 0.7))
|
105
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_FREQUENCY_PENALTY,
|
106
|
+
kwargs.get("frequency_penalty", 1.18))
|
107
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_IS_STREAM,
|
108
|
+
True)
|
109
|
+
if trace_content:
|
110
|
+
span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
|
111
|
+
prompt)
|
112
|
+
span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION,
|
113
|
+
llmresponse)
|
114
|
+
|
115
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
|
116
|
+
prompt_tokens)
|
117
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COMPLETION_TOKENS,
|
118
|
+
completion_tokens)
|
119
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
|
120
|
+
total_tokens)
|
121
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
|
122
|
+
cost)
|
123
|
+
|
124
|
+
span.set_status(Status(StatusCode.OK))
|
125
|
+
|
126
|
+
if disable_metrics is False:
|
127
|
+
attributes = {
|
128
|
+
TELEMETRY_SDK_NAME:
|
129
|
+
"openlit",
|
130
|
+
SemanticConvetion.GEN_AI_APPLICATION_NAME:
|
131
|
+
application_name,
|
132
|
+
SemanticConvetion.GEN_AI_SYSTEM:
|
133
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
|
134
|
+
SemanticConvetion.GEN_AI_ENVIRONMENT:
|
135
|
+
environment,
|
136
|
+
SemanticConvetion.GEN_AI_TYPE:
|
137
|
+
SemanticConvetion.GEN_AI_TYPE_CHAT,
|
138
|
+
SemanticConvetion.GEN_AI_REQUEST_MODEL:
|
139
|
+
model
|
140
|
+
}
|
141
|
+
|
142
|
+
metrics["genai_requests"].add(1, attributes)
|
143
|
+
metrics["genai_total_tokens"].add(total_tokens, attributes)
|
144
|
+
metrics["genai_completion_tokens"].add(completion_tokens, attributes)
|
145
|
+
metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
|
146
|
+
metrics["genai_cost"].record(cost, attributes)
|
147
|
+
|
148
|
+
except Exception as e:
|
149
|
+
handle_exception(span, e)
|
150
|
+
logger.error("Error in trace creation: %s", e)
|
151
|
+
|
152
|
+
return stream_generator()
|
153
|
+
|
154
|
+
# Handling for non-streaming responses
|
155
|
+
else:
|
156
|
+
# pylint: disable=line-too-long
|
157
|
+
with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
|
158
|
+
response = wrapped(*args, **kwargs)
|
159
|
+
|
160
|
+
# pylint: disable=line-too-long
|
161
|
+
model = str(instance.model.model_path).rsplit('/', maxsplit=1)[-1] or "orca-mini-3b-gguf2-q4_0.gguf"
|
162
|
+
prompt = kwargs.get("prompt") or args[0] or ""
|
163
|
+
|
164
|
+
# Calculate cost of the operation
|
165
|
+
cost = 0
|
166
|
+
prompt_tokens = general_tokens(prompt)
|
167
|
+
completion_tokens = general_tokens(response)
|
168
|
+
total_tokens = prompt_tokens + completion_tokens
|
169
|
+
|
170
|
+
try:
|
171
|
+
# Set base span attribues
|
172
|
+
span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
|
173
|
+
span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
|
174
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
|
175
|
+
span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
|
176
|
+
SemanticConvetion.GEN_AI_TYPE_CHAT)
|
177
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
|
178
|
+
gen_ai_endpoint)
|
179
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
|
180
|
+
environment)
|
181
|
+
span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
|
182
|
+
application_name)
|
183
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
|
184
|
+
model)
|
185
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_K,
|
186
|
+
kwargs.get("top_k", 40))
|
187
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_P,
|
188
|
+
kwargs.get("top_p", 0.4))
|
189
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MAX_TOKENS,
|
190
|
+
kwargs.get("max_tokens", 200))
|
191
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TEMPERATURE,
|
192
|
+
kwargs.get("temperature", 0.7))
|
193
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_FREQUENCY_PENALTY,
|
194
|
+
kwargs.get("frequency_penalty", 1.18))
|
195
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_IS_STREAM,
|
196
|
+
False)
|
197
|
+
if trace_content:
|
198
|
+
span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
|
199
|
+
prompt)
|
200
|
+
span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION,
|
201
|
+
response)
|
202
|
+
|
203
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
|
204
|
+
prompt_tokens)
|
205
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COMPLETION_TOKENS,
|
206
|
+
completion_tokens)
|
207
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
|
208
|
+
total_tokens)
|
209
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
|
210
|
+
cost)
|
211
|
+
|
212
|
+
span.set_status(Status(StatusCode.OK))
|
213
|
+
|
214
|
+
if disable_metrics is False:
|
215
|
+
attributes = {
|
216
|
+
TELEMETRY_SDK_NAME:
|
217
|
+
"openlit",
|
218
|
+
SemanticConvetion.GEN_AI_APPLICATION_NAME:
|
219
|
+
application_name,
|
220
|
+
SemanticConvetion.GEN_AI_SYSTEM:
|
221
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
|
222
|
+
SemanticConvetion.GEN_AI_ENVIRONMENT:
|
223
|
+
environment,
|
224
|
+
SemanticConvetion.GEN_AI_TYPE:
|
225
|
+
SemanticConvetion.GEN_AI_TYPE_CHAT,
|
226
|
+
SemanticConvetion.GEN_AI_REQUEST_MODEL:
|
227
|
+
model
|
228
|
+
}
|
229
|
+
|
230
|
+
metrics["genai_requests"].add(1, attributes)
|
231
|
+
metrics["genai_total_tokens"].add(total_tokens, attributes)
|
232
|
+
metrics["genai_completion_tokens"].add(completion_tokens, attributes)
|
233
|
+
metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
|
234
|
+
metrics["genai_cost"].record(cost, attributes)
|
235
|
+
|
236
|
+
# Return original response
|
237
|
+
return response
|
238
|
+
|
239
|
+
except Exception as e:
|
240
|
+
handle_exception(span, e)
|
241
|
+
logger.error("Error in trace creation: %s", e)
|
242
|
+
|
243
|
+
# Return original response
|
244
|
+
return response
|
245
|
+
|
246
|
+
return wrapper
|
247
|
+
|
248
|
+
def embed(gen_ai_endpoint, version, environment, application_name,
|
249
|
+
tracer, pricing_info, trace_content, metrics, disable_metrics):
|
250
|
+
"""
|
251
|
+
Generates a telemetry wrapper for embeddings to collect metrics.
|
252
|
+
|
253
|
+
Args:
|
254
|
+
gen_ai_endpoint: Endpoint identifier for logging and tracing.
|
255
|
+
version: Version of the monitoring package.
|
256
|
+
environment: Deployment environment (e.g., production, staging).
|
257
|
+
application_name: Name of the application using the GPT4All API.
|
258
|
+
tracer: OpenTelemetry tracer for creating spans.
|
259
|
+
pricing_info: Information used for calculating the cost of GPT4All usage.
|
260
|
+
trace_content: Flag indicating whether to trace the actual content.
|
261
|
+
|
262
|
+
Returns:
|
263
|
+
A function that wraps the embeddings method to add telemetry.
|
264
|
+
"""
|
265
|
+
|
266
|
+
def wrapper(wrapped, instance, args, kwargs):
|
267
|
+
"""
|
268
|
+
Wraps the 'embeddings' API call to add telemetry.
|
269
|
+
|
270
|
+
This collects metrics such as execution time, cost, and token usage, and handles errors
|
271
|
+
gracefully, adding details to the trace for observability.
|
272
|
+
|
273
|
+
Args:
|
274
|
+
wrapped: The original 'embeddings' method to be wrapped.
|
275
|
+
instance: The instance of the class where the original method is defined.
|
276
|
+
args: Positional arguments for the 'embeddings' method.
|
277
|
+
kwargs: Keyword arguments for the 'embeddings' method.
|
278
|
+
|
279
|
+
Returns:
|
280
|
+
The response from the original 'embeddings' method.
|
281
|
+
"""
|
282
|
+
|
283
|
+
with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
|
284
|
+
response = wrapped(*args, **kwargs)
|
285
|
+
|
286
|
+
try:
|
287
|
+
# pylint: disable=line-too-long
|
288
|
+
model = str(instance.gpt4all.model.model_path).rsplit('/', maxsplit=1)[-1] or "all-MiniLM-L6-v2.gguf2.f16.gguf"
|
289
|
+
prompt = kwargs.get("prompt") or args[0] or ""
|
290
|
+
|
291
|
+
# Calculate cost of the operation
|
292
|
+
cost = 0
|
293
|
+
prompt_tokens = general_tokens(prompt)
|
294
|
+
|
295
|
+
# Set Span attributes
|
296
|
+
span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
|
297
|
+
span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM,
|
298
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL)
|
299
|
+
span.set_attribute(SemanticConvetion.GEN_AI_TYPE,
|
300
|
+
SemanticConvetion.GEN_AI_TYPE_EMBEDDING)
|
301
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENDPOINT,
|
302
|
+
gen_ai_endpoint)
|
303
|
+
span.set_attribute(SemanticConvetion.GEN_AI_ENVIRONMENT,
|
304
|
+
environment)
|
305
|
+
span.set_attribute(SemanticConvetion.GEN_AI_APPLICATION_NAME,
|
306
|
+
application_name)
|
307
|
+
span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL,
|
308
|
+
model)
|
309
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_PROMPT_TOKENS,
|
310
|
+
prompt_tokens)
|
311
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS,
|
312
|
+
prompt_tokens)
|
313
|
+
span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST,
|
314
|
+
cost)
|
315
|
+
if trace_content:
|
316
|
+
span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_PROMPT,
|
317
|
+
prompt)
|
318
|
+
|
319
|
+
span.set_status(Status(StatusCode.OK))
|
320
|
+
|
321
|
+
if disable_metrics is False:
|
322
|
+
attributes = {
|
323
|
+
TELEMETRY_SDK_NAME:
|
324
|
+
"openlit",
|
325
|
+
SemanticConvetion.GEN_AI_APPLICATION_NAME:
|
326
|
+
application_name,
|
327
|
+
SemanticConvetion.GEN_AI_SYSTEM:
|
328
|
+
SemanticConvetion.GEN_AI_SYSTEM_GPT4ALL,
|
329
|
+
SemanticConvetion.GEN_AI_ENVIRONMENT:
|
330
|
+
environment,
|
331
|
+
SemanticConvetion.GEN_AI_TYPE:
|
332
|
+
SemanticConvetion.GEN_AI_TYPE_EMBEDDING,
|
333
|
+
SemanticConvetion.GEN_AI_REQUEST_MODEL:
|
334
|
+
model
|
335
|
+
}
|
336
|
+
|
337
|
+
metrics["genai_requests"].add(1, attributes)
|
338
|
+
metrics["genai_total_tokens"].add(prompt_tokens, attributes)
|
339
|
+
metrics["genai_prompt_tokens"].add(prompt_tokens, attributes)
|
340
|
+
metrics["genai_cost"].record(cost, attributes)
|
341
|
+
|
342
|
+
# Return original response
|
343
|
+
return response
|
344
|
+
|
345
|
+
except Exception as e:
|
346
|
+
handle_exception(span, e)
|
347
|
+
logger.error("Error in trace creation: %s", e)
|
348
|
+
|
349
|
+
# Return original response
|
350
|
+
return response
|
351
|
+
|
352
|
+
return wrapper
|
@@ -268,7 +268,7 @@ def async_chat(gen_ai_endpoint, version, environment, application_name,
|
|
268
268
|
else:
|
269
269
|
i = 0
|
270
270
|
while i < kwargs["n"] and trace_content is True:
|
271
|
-
attribute_name = f"gen_ai.
|
271
|
+
attribute_name = f"gen_ai.completion.{i}"
|
272
272
|
span.set_attribute(attribute_name,
|
273
273
|
response.choices[i].message.content)
|
274
274
|
i += 1
|
@@ -268,7 +268,7 @@ def chat(gen_ai_endpoint, version, environment, application_name,
|
|
268
268
|
else:
|
269
269
|
i = 0
|
270
270
|
while i < kwargs["n"] and trace_content is True:
|
271
|
-
attribute_name = f"gen_ai.
|
271
|
+
attribute_name = f"gen_ai.completion.{i}"
|
272
272
|
span.set_attribute(attribute_name,
|
273
273
|
response.choices[i].message.content)
|
274
274
|
i += 1
|
@@ -269,7 +269,7 @@ def azure_async_chat_completions(gen_ai_endpoint, version, environment, applicat
|
|
269
269
|
else:
|
270
270
|
i = 0
|
271
271
|
while i < kwargs["n"] and trace_content is True:
|
272
|
-
attribute_name = f"gen_ai.
|
272
|
+
attribute_name = f"gen_ai.completion.{i}"
|
273
273
|
span.set_attribute(attribute_name,
|
274
274
|
response.choices[i].message.content)
|
275
275
|
i += 1
|
@@ -550,7 +550,7 @@ def azure_async_completions(gen_ai_endpoint, version, environment, application_n
|
|
550
550
|
else:
|
551
551
|
i = 0
|
552
552
|
while i < kwargs["n"] and trace_content is True:
|
553
|
-
attribute_name = f"gen_ai.
|
553
|
+
attribute_name = f"gen_ai.completion.{i}"
|
554
554
|
span.set_attribute(attribute_name,
|
555
555
|
response.choices[i].text)
|
556
556
|
i += 1
|
@@ -273,7 +273,7 @@ def async_chat_completions(gen_ai_endpoint, version, environment, application_na
|
|
273
273
|
else:
|
274
274
|
i = 0
|
275
275
|
while i < kwargs["n"] and trace_content is True:
|
276
|
-
attribute_name = f"gen_ai.
|
276
|
+
attribute_name = f"gen_ai.completion.{i}"
|
277
277
|
span.set_attribute(attribute_name,
|
278
278
|
response.choices[i].message.content)
|
279
279
|
i += 1
|
@@ -269,7 +269,7 @@ def azure_chat_completions(gen_ai_endpoint, version, environment, application_na
|
|
269
269
|
else:
|
270
270
|
i = 0
|
271
271
|
while i < kwargs["n"] and trace_content is True:
|
272
|
-
attribute_name = f"gen_ai.
|
272
|
+
attribute_name = f"gen_ai.completion.{i}"
|
273
273
|
span.set_attribute(attribute_name,
|
274
274
|
response.choices[i].message.content)
|
275
275
|
i += 1
|
@@ -548,7 +548,7 @@ def azure_completions(gen_ai_endpoint, version, environment, application_name,
|
|
548
548
|
else:
|
549
549
|
i = 0
|
550
550
|
while i < kwargs["n"] and trace_content is True:
|
551
|
-
attribute_name = f"gen_ai.
|
551
|
+
attribute_name = f"gen_ai.completion.{i}"
|
552
552
|
span.set_attribute(attribute_name,
|
553
553
|
response.choices[i].text)
|
554
554
|
i += 1
|
@@ -272,7 +272,7 @@ def chat_completions(gen_ai_endpoint, version, environment, application_name,
|
|
272
272
|
else:
|
273
273
|
i = 0
|
274
274
|
while i < kwargs["n"] and trace_content is True:
|
275
|
-
attribute_name = f"gen_ai.
|
275
|
+
attribute_name = f"gen_ai.completion.{i}"
|
276
276
|
span.set_attribute(attribute_name,
|
277
277
|
response.choices[i].message.content)
|
278
278
|
i += 1
|
@@ -98,7 +98,7 @@ def text_wrap(gen_ai_endpoint, version, environment, application_name,
|
|
98
98
|
completion_tokens = 0
|
99
99
|
for completion in response:
|
100
100
|
if len(response) > 1:
|
101
|
-
attribute_name = f"gen_ai.
|
101
|
+
attribute_name = f"gen_ai.completion.{i}"
|
102
102
|
else:
|
103
103
|
attribute_name = SemanticConvetion.GEN_AI_CONTENT_COMPLETION
|
104
104
|
if i == 0:
|
@@ -21,7 +21,7 @@ class SemanticConvetion:
|
|
21
21
|
GEN_AI_SYSTEM = "gen_ai.system"
|
22
22
|
GEN_AI_ENVIRONMENT = "gen_ai.environment"
|
23
23
|
GEN_AI_APPLICATION_NAME = "gen_ai.application_name"
|
24
|
-
GEN_AI_TYPE = "gen_ai.
|
24
|
+
GEN_AI_TYPE = "gen_ai.operation.name"
|
25
25
|
GEN_AI_HUB_OWNER = "gen_ai.hub.owner"
|
26
26
|
GEN_AI_HUB_REPO = "gen_ai.hub.repo"
|
27
27
|
GEN_AI_RETRIEVAL_SOURCE = "gen_ai.retrieval.source"
|
@@ -68,8 +68,8 @@ class SemanticConvetion:
|
|
68
68
|
GEN_AI_RESPONSE_IMAGE_STYLE = "gen_ai.request.image_style"
|
69
69
|
|
70
70
|
# GenAI Content
|
71
|
-
GEN_AI_CONTENT_PROMPT = "gen_ai.
|
72
|
-
GEN_AI_CONTENT_COMPLETION = "gen_ai.
|
71
|
+
GEN_AI_CONTENT_PROMPT = "gen_ai.prompt"
|
72
|
+
GEN_AI_CONTENT_COMPLETION = "gen_ai.completion"
|
73
73
|
GEN_AI_CONTENT_REVISED_PROMPT = "gen_ai.content.revised_prompt"
|
74
74
|
|
75
75
|
# GenAI Evaluation Metrics
|
@@ -95,6 +95,7 @@ class SemanticConvetion:
|
|
95
95
|
GEN_AI_SYSTEM_VERTEXAI = "vertexai"
|
96
96
|
GEN_AI_SYSTEM_GROQ = "groq"
|
97
97
|
GEN_AI_SYSTEM_OLLAMA = "ollama"
|
98
|
+
GEN_AI_SYSTEM_GPT4ALL = "gpt4all"
|
98
99
|
GEN_AI_SYSTEM_LANGCHAIN = "langchain"
|
99
100
|
GEN_AI_SYSTEM_LLAMAINDEX = "llama_index"
|
100
101
|
GEN_AI_SYSTEM_HAYSTACK = "haystack"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|