opentelemetry-instrumentation-llamaindex 0.9.3__tar.gz → 0.49.1__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.
- {opentelemetry_instrumentation_llamaindex-0.9.3 → opentelemetry_instrumentation_llamaindex-0.49.1}/PKG-INFO +20 -6
- {opentelemetry_instrumentation_llamaindex-0.9.3 → opentelemetry_instrumentation_llamaindex-0.49.1}/README.md +8 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/__init__.py +134 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/base_agent_instrumentor.py +80 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/base_embedding_instrumentor.py +68 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/base_retriever_instrumentor.py +73 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/base_synthesizer_instrumentor.py +72 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/base_tool_instrumentor.py +82 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/config.py +9 -0
- {opentelemetry_instrumentation_llamaindex-0.9.3 → opentelemetry_instrumentation_llamaindex-0.49.1}/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py +73 -21
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/dispatcher_wrapper.py +297 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/event_emitter.py +161 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/event_models.py +41 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/llamaparse_instrumentor.py +169 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/query_pipeline_instrumentor.py +80 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/retriever_query_engine_instrumentor.py +81 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/span_utils.py +151 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/utils.py +104 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/version.py +1 -0
- opentelemetry_instrumentation_llamaindex-0.49.1/pyproject.toml +67 -0
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/__init__.py +0 -39
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/base_embedding_instrumentor.py +0 -43
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/base_retriever_instrumentor.py +0 -39
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/base_synthesizer_instrumentor.py +0 -39
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/retriever_query_engine_instrumentor.py +0 -48
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/utils.py +0 -27
- opentelemetry_instrumentation_llamaindex-0.9.3/opentelemetry/instrumentation/llamaindex/version.py +0 -1
- opentelemetry_instrumentation_llamaindex-0.9.3/pyproject.toml +0 -39
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: opentelemetry-instrumentation-llamaindex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.49.1
|
|
4
4
|
Summary: OpenTelemetry LlamaIndex instrumentation
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Author: Gal Kleinman
|
|
7
7
|
Author-email: gal@traceloop.com
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.9,<4
|
|
9
9
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Provides-Extra: instruments
|
|
18
|
+
Provides-Extra: llamaparse
|
|
15
19
|
Requires-Dist: inflection (>=0.5.1,<0.6.0)
|
|
16
|
-
Requires-Dist: opentelemetry-api (>=1.
|
|
17
|
-
Requires-Dist: opentelemetry-instrumentation (
|
|
18
|
-
Requires-Dist: opentelemetry-semantic-conventions
|
|
20
|
+
Requires-Dist: opentelemetry-api (>=1.38.0,<2.0.0)
|
|
21
|
+
Requires-Dist: opentelemetry-instrumentation (>=0.59b0)
|
|
22
|
+
Requires-Dist: opentelemetry-semantic-conventions (>=0.59b0)
|
|
23
|
+
Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.4.13,<0.5.0)
|
|
24
|
+
Project-URL: Repository, https://github.com/traceloop/openllmetry/tree/main/packages/opentelemetry-instrumentation-llamaindex
|
|
19
25
|
Description-Content-Type: text/markdown
|
|
20
26
|
|
|
21
27
|
# OpenTelemetry LlamaIndex Instrumentation
|
|
@@ -32,6 +38,14 @@ This library allows tracing complete LLM applications built with [LlamaIndex](ht
|
|
|
32
38
|
pip install opentelemetry-instrumentation-llamaindex
|
|
33
39
|
```
|
|
34
40
|
|
|
41
|
+
## Example usage
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from opentelemetry.instrumentation.llamaindex import LlamaIndexInstrumentor
|
|
45
|
+
|
|
46
|
+
LlamaIndexInstrumentor().instrument()
|
|
47
|
+
```
|
|
48
|
+
|
|
35
49
|
## Privacy
|
|
36
50
|
|
|
37
51
|
**By default, this instrumentation logs prompts, completions, and embeddings to span attributes**. This gives you a clear visibility into how your LLM application is working, and can make it easy to debug and evaluate the quality of the outputs.
|
|
@@ -12,6 +12,14 @@ This library allows tracing complete LLM applications built with [LlamaIndex](ht
|
|
|
12
12
|
pip install opentelemetry-instrumentation-llamaindex
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Example usage
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from opentelemetry.instrumentation.llamaindex import LlamaIndexInstrumentor
|
|
19
|
+
|
|
20
|
+
LlamaIndexInstrumentor().instrument()
|
|
21
|
+
```
|
|
22
|
+
|
|
15
23
|
## Privacy
|
|
16
24
|
|
|
17
25
|
**By default, this instrumentation logs prompts, completions, and embeddings to span attributes**. This gives you a clear visibility into how your LLM application is working, and can make it easy to debug and evaluate the quality of the outputs.
|
opentelemetry_instrumentation_llamaindex-0.49.1/opentelemetry/instrumentation/llamaindex/__init__.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""OpenTelemetry LlamaIndex instrumentation"""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from importlib.metadata import version as import_version
|
|
5
|
+
from typing import Collection
|
|
6
|
+
|
|
7
|
+
from opentelemetry._logs import get_logger
|
|
8
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
9
|
+
from opentelemetry.instrumentation.llamaindex.base_agent_instrumentor import (
|
|
10
|
+
BaseAgentInstrumentor,
|
|
11
|
+
)
|
|
12
|
+
from opentelemetry.instrumentation.llamaindex.base_embedding_instrumentor import (
|
|
13
|
+
BaseEmbeddingInstrumentor,
|
|
14
|
+
)
|
|
15
|
+
from opentelemetry.instrumentation.llamaindex.base_retriever_instrumentor import (
|
|
16
|
+
BaseRetrieverInstrumentor,
|
|
17
|
+
)
|
|
18
|
+
from opentelemetry.instrumentation.llamaindex.base_synthesizer_instrumentor import (
|
|
19
|
+
BaseSynthesizerInstrumentor,
|
|
20
|
+
)
|
|
21
|
+
from opentelemetry.instrumentation.llamaindex.base_tool_instrumentor import (
|
|
22
|
+
BaseToolInstrumentor,
|
|
23
|
+
)
|
|
24
|
+
from opentelemetry.instrumentation.llamaindex.config import Config
|
|
25
|
+
from opentelemetry.instrumentation.llamaindex.custom_llm_instrumentor import (
|
|
26
|
+
CustomLLMInstrumentor,
|
|
27
|
+
)
|
|
28
|
+
from opentelemetry.instrumentation.llamaindex.dispatcher_wrapper import (
|
|
29
|
+
instrument_with_dispatcher,
|
|
30
|
+
)
|
|
31
|
+
from opentelemetry.instrumentation.llamaindex.llamaparse_instrumentor import (
|
|
32
|
+
LlamaParseInstrumentor,
|
|
33
|
+
)
|
|
34
|
+
from opentelemetry.instrumentation.llamaindex.query_pipeline_instrumentor import (
|
|
35
|
+
QueryPipelineInstrumentor,
|
|
36
|
+
)
|
|
37
|
+
from opentelemetry.instrumentation.llamaindex.retriever_query_engine_instrumentor import (
|
|
38
|
+
RetrieverQueryEngineInstrumentor,
|
|
39
|
+
)
|
|
40
|
+
from opentelemetry.instrumentation.llamaindex.version import __version__
|
|
41
|
+
from opentelemetry.trace import get_tracer
|
|
42
|
+
|
|
43
|
+
logger = logging.getLogger(__name__)
|
|
44
|
+
|
|
45
|
+
_core_instruments = ("llama-index-core >= 0.7.0",)
|
|
46
|
+
_full_instruments = ("llama-index >= 0.7.0",)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LlamaIndexInstrumentor(BaseInstrumentor):
|
|
50
|
+
"""An instrumentor for both: core and legacy LlamaIndex SDK."""
|
|
51
|
+
|
|
52
|
+
def __init__(self, exception_logger=None, use_legacy_attributes=True):
|
|
53
|
+
self.legacy = LlamaIndexInstrumentorFull(exception_logger)
|
|
54
|
+
self.core = LlamaIndexInstrumentorCore(exception_logger)
|
|
55
|
+
Config.use_legacy_attributes = use_legacy_attributes
|
|
56
|
+
|
|
57
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
|
58
|
+
return ()
|
|
59
|
+
|
|
60
|
+
def _instrument(self, **kwargs):
|
|
61
|
+
# Try to use the legacy entry point for instrumentation
|
|
62
|
+
if self.legacy._check_dependency_conflicts() is None:
|
|
63
|
+
self.legacy.instrument(**kwargs)
|
|
64
|
+
if not self.legacy._is_instrumented_by_opentelemetry:
|
|
65
|
+
# it didn't work -> try the new package
|
|
66
|
+
if self.core._check_dependency_conflicts() is None:
|
|
67
|
+
self.core.instrument(**kwargs)
|
|
68
|
+
|
|
69
|
+
def _uninstrument(self, **kwargs):
|
|
70
|
+
self.legacy.uninstrument(**kwargs)
|
|
71
|
+
self.core.uninstrument(**kwargs)
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def apply_instrumentation(name, **kwargs):
|
|
75
|
+
tracer_provider = kwargs.get("tracer_provider")
|
|
76
|
+
tracer = get_tracer(__name__, __version__, tracer_provider)
|
|
77
|
+
|
|
78
|
+
if not Config.use_legacy_attributes:
|
|
79
|
+
logger_provider = kwargs.get("logger_provider")
|
|
80
|
+
Config.event_logger = get_logger(
|
|
81
|
+
__name__, __version__, logger_provider=logger_provider
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if import_version(name) >= "0.10.20":
|
|
85
|
+
instrument_with_dispatcher(tracer)
|
|
86
|
+
else:
|
|
87
|
+
RetrieverQueryEngineInstrumentor(tracer).instrument()
|
|
88
|
+
BaseRetrieverInstrumentor(tracer).instrument()
|
|
89
|
+
BaseSynthesizerInstrumentor(tracer).instrument()
|
|
90
|
+
BaseEmbeddingInstrumentor(tracer).instrument()
|
|
91
|
+
CustomLLMInstrumentor(tracer).instrument()
|
|
92
|
+
QueryPipelineInstrumentor(tracer).instrument()
|
|
93
|
+
BaseAgentInstrumentor(tracer).instrument()
|
|
94
|
+
BaseToolInstrumentor(tracer).instrument()
|
|
95
|
+
|
|
96
|
+
# LlamaParse instrumentation doesn't work for all versions
|
|
97
|
+
try:
|
|
98
|
+
LlamaParseInstrumentor(tracer).instrument()
|
|
99
|
+
except Exception:
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class LlamaIndexInstrumentorCore(BaseInstrumentor):
|
|
104
|
+
"""An instrumentor for core LlamaIndex SDK."""
|
|
105
|
+
|
|
106
|
+
def __init__(self, exception_logger=None):
|
|
107
|
+
super().__init__()
|
|
108
|
+
Config.exception_logger = exception_logger
|
|
109
|
+
|
|
110
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
|
111
|
+
return _core_instruments
|
|
112
|
+
|
|
113
|
+
def _instrument(self, **kwargs):
|
|
114
|
+
LlamaIndexInstrumentor.apply_instrumentation("llama-index-core", **kwargs)
|
|
115
|
+
|
|
116
|
+
def _uninstrument(self, **kwargs):
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class LlamaIndexInstrumentorFull(BaseInstrumentor):
|
|
121
|
+
"""An instrumentor for legacy LlamaIndex SDK."""
|
|
122
|
+
|
|
123
|
+
def __init__(self, exception_logger=None):
|
|
124
|
+
super().__init__()
|
|
125
|
+
Config.exception_logger = exception_logger
|
|
126
|
+
|
|
127
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
|
128
|
+
return _full_instruments
|
|
129
|
+
|
|
130
|
+
def _instrument(self, **kwargs):
|
|
131
|
+
LlamaIndexInstrumentor.apply_instrumentation("llama-index", **kwargs)
|
|
132
|
+
|
|
133
|
+
def _uninstrument(self, **kwargs):
|
|
134
|
+
pass
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from importlib.metadata import version as package_version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from wrapt import wrap_function_wrapper
|
|
4
|
+
|
|
5
|
+
from opentelemetry.instrumentation.llamaindex.utils import (
|
|
6
|
+
_with_tracer_wrapper,
|
|
7
|
+
process_request,
|
|
8
|
+
process_response,
|
|
9
|
+
start_as_current_span_async,
|
|
10
|
+
)
|
|
11
|
+
from opentelemetry.semconv_ai import SpanAttributes, TraceloopSpanKindValues
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
TO_INSTRUMENT = [
|
|
15
|
+
{
|
|
16
|
+
"class": "AgentRunner",
|
|
17
|
+
"v10_module": "llama_index.core.agent.runner.base",
|
|
18
|
+
"v10_legacy_module": "llama_index.legacy.agent.runner.base",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"class": "OpenAIAssistantAgent",
|
|
22
|
+
"v10_module": "llama_index.agent.openai.openai_assistant_agent",
|
|
23
|
+
"v10_legacy_module": "llama_index.legacy.agent.openai_assistant_agent",
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BaseAgentInstrumentor:
|
|
29
|
+
def __init__(self, tracer):
|
|
30
|
+
self._tracer = tracer
|
|
31
|
+
|
|
32
|
+
def instrument(self):
|
|
33
|
+
for module in TO_INSTRUMENT:
|
|
34
|
+
try:
|
|
35
|
+
package_version("llama-index-core")
|
|
36
|
+
self._instrument_module(module["v10_module"], module["class"])
|
|
37
|
+
self._instrument_module(module["v10_legacy_module"], module["class"])
|
|
38
|
+
|
|
39
|
+
except PackageNotFoundError:
|
|
40
|
+
pass # not supported before v10
|
|
41
|
+
|
|
42
|
+
def _instrument_module(self, module_name, class_name):
|
|
43
|
+
wrap_function_wrapper(
|
|
44
|
+
module_name, f"{class_name}.chat", query_wrapper(self._tracer)
|
|
45
|
+
)
|
|
46
|
+
wrap_function_wrapper(
|
|
47
|
+
module_name, f"{class_name}.achat", aquery_wrapper(self._tracer)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@_with_tracer_wrapper
|
|
52
|
+
def query_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
53
|
+
name = instance.__class__.__name__
|
|
54
|
+
with tracer.start_as_current_span(f"{name}.agent") as span:
|
|
55
|
+
span.set_attribute(
|
|
56
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
57
|
+
TraceloopSpanKindValues.AGENT.value,
|
|
58
|
+
)
|
|
59
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, name)
|
|
60
|
+
|
|
61
|
+
process_request(span, args, kwargs)
|
|
62
|
+
res = wrapped(*args, **kwargs)
|
|
63
|
+
process_response(span, res)
|
|
64
|
+
return res
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@_with_tracer_wrapper
|
|
68
|
+
async def aquery_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
69
|
+
name = instance.__class__.__name__
|
|
70
|
+
async with start_as_current_span_async(tracer=tracer, name=f"{name}.agent") as span:
|
|
71
|
+
span.set_attribute(
|
|
72
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
73
|
+
TraceloopSpanKindValues.AGENT.value,
|
|
74
|
+
)
|
|
75
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, name)
|
|
76
|
+
|
|
77
|
+
process_request(span, args, kwargs)
|
|
78
|
+
res = await wrapped(*args, **kwargs)
|
|
79
|
+
process_response(span, res)
|
|
80
|
+
return res
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from importlib.metadata import version as package_version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from wrapt import wrap_function_wrapper
|
|
4
|
+
|
|
5
|
+
from opentelemetry.instrumentation.llamaindex.utils import (
|
|
6
|
+
_with_tracer_wrapper,
|
|
7
|
+
start_as_current_span_async,
|
|
8
|
+
)
|
|
9
|
+
from opentelemetry.semconv_ai import SpanAttributes, TraceloopSpanKindValues
|
|
10
|
+
|
|
11
|
+
V9_MODULE_NAME = "llama_index.embeddings.base"
|
|
12
|
+
V10_MODULE_NAME = "llama_index.core.embeddings"
|
|
13
|
+
V10_LEGACY_MODULE_NAME = "llama_index.legacy.embeddings.base"
|
|
14
|
+
|
|
15
|
+
CLASS_NAME = "BaseEmbedding"
|
|
16
|
+
TASK_NAME = "get_query_embedding"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BaseEmbeddingInstrumentor:
|
|
20
|
+
def __init__(self, tracer):
|
|
21
|
+
self._tracer = tracer
|
|
22
|
+
|
|
23
|
+
def instrument(self):
|
|
24
|
+
try:
|
|
25
|
+
package_version("llama-index-core")
|
|
26
|
+
self._instrument_module(V10_MODULE_NAME)
|
|
27
|
+
self._instrument_module(V10_LEGACY_MODULE_NAME)
|
|
28
|
+
|
|
29
|
+
except PackageNotFoundError:
|
|
30
|
+
self._instrument_module(V9_MODULE_NAME)
|
|
31
|
+
|
|
32
|
+
def _instrument_module(self, module_name):
|
|
33
|
+
wrap_function_wrapper(
|
|
34
|
+
module_name,
|
|
35
|
+
f"{CLASS_NAME}.get_query_embedding",
|
|
36
|
+
get_query_embedding_wrapper(self._tracer),
|
|
37
|
+
)
|
|
38
|
+
wrap_function_wrapper(
|
|
39
|
+
module_name,
|
|
40
|
+
f"{CLASS_NAME}.aget_query_embedding",
|
|
41
|
+
aget_query_embedding_wrapper(self._tracer),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@_with_tracer_wrapper
|
|
46
|
+
def get_query_embedding_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
47
|
+
with tracer.start_as_current_span(f"{TASK_NAME}.task") as span:
|
|
48
|
+
span.set_attribute(
|
|
49
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
50
|
+
TraceloopSpanKindValues.TASK.value,
|
|
51
|
+
)
|
|
52
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
53
|
+
|
|
54
|
+
return wrapped(*args, **kwargs)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@_with_tracer_wrapper
|
|
58
|
+
async def aget_query_embedding_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
59
|
+
async with start_as_current_span_async(
|
|
60
|
+
tracer=tracer, name=f"{TASK_NAME}.task"
|
|
61
|
+
) as span:
|
|
62
|
+
span.set_attribute(
|
|
63
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
64
|
+
TraceloopSpanKindValues.TASK.value,
|
|
65
|
+
)
|
|
66
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
67
|
+
|
|
68
|
+
return await wrapped(*args, **kwargs)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from importlib.metadata import version as package_version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from wrapt import wrap_function_wrapper
|
|
4
|
+
|
|
5
|
+
from opentelemetry.instrumentation.llamaindex.utils import (
|
|
6
|
+
_with_tracer_wrapper,
|
|
7
|
+
process_request,
|
|
8
|
+
process_response,
|
|
9
|
+
start_as_current_span_async,
|
|
10
|
+
)
|
|
11
|
+
from opentelemetry.semconv_ai import SpanAttributes, TraceloopSpanKindValues
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
V9_MODULE_NAME = "llama_index.indices.base_retriever"
|
|
15
|
+
V10_MODULE_NAME = "llama_index.core.indices.base_retriever"
|
|
16
|
+
V10_LEGACY_MODULE_NAME = "llama_index.legacy.indices.base_retriever"
|
|
17
|
+
|
|
18
|
+
CLASS_NAME = "BaseRetriever"
|
|
19
|
+
TASK_NAME = "retrieve"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BaseRetrieverInstrumentor:
|
|
23
|
+
def __init__(self, tracer):
|
|
24
|
+
self._tracer = tracer
|
|
25
|
+
|
|
26
|
+
def instrument(self):
|
|
27
|
+
try:
|
|
28
|
+
package_version("llama-index-core")
|
|
29
|
+
self._instrument_module(V10_MODULE_NAME)
|
|
30
|
+
self._instrument_module(V10_LEGACY_MODULE_NAME)
|
|
31
|
+
|
|
32
|
+
except PackageNotFoundError:
|
|
33
|
+
self._instrument_module(V9_MODULE_NAME)
|
|
34
|
+
|
|
35
|
+
def _instrument_module(self, module_name):
|
|
36
|
+
wrap_function_wrapper(
|
|
37
|
+
module_name, f"{CLASS_NAME}.retrieve", retrieve_wrapper(self._tracer)
|
|
38
|
+
)
|
|
39
|
+
wrap_function_wrapper(
|
|
40
|
+
module_name, f"{CLASS_NAME}.aretrieve", aretrieve_wrapper(self._tracer)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@_with_tracer_wrapper
|
|
45
|
+
def retrieve_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
46
|
+
with tracer.start_as_current_span(f"{TASK_NAME}.task") as span:
|
|
47
|
+
span.set_attribute(
|
|
48
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
49
|
+
TraceloopSpanKindValues.TASK.value,
|
|
50
|
+
)
|
|
51
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
52
|
+
|
|
53
|
+
process_request(span, args, kwargs)
|
|
54
|
+
res = wrapped(*args, **kwargs)
|
|
55
|
+
process_response(span, res)
|
|
56
|
+
return res
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@_with_tracer_wrapper
|
|
60
|
+
async def aretrieve_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
61
|
+
async with start_as_current_span_async(
|
|
62
|
+
tracer=tracer, name=f"{TASK_NAME}.task"
|
|
63
|
+
) as span:
|
|
64
|
+
span.set_attribute(
|
|
65
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
66
|
+
TraceloopSpanKindValues.TASK.value,
|
|
67
|
+
)
|
|
68
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
69
|
+
|
|
70
|
+
process_request(span, args, kwargs)
|
|
71
|
+
res = await wrapped(*args, **kwargs)
|
|
72
|
+
process_response(span, res)
|
|
73
|
+
return res
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from importlib.metadata import version as package_version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from wrapt import wrap_function_wrapper
|
|
4
|
+
|
|
5
|
+
from opentelemetry.instrumentation.llamaindex.utils import (
|
|
6
|
+
_with_tracer_wrapper,
|
|
7
|
+
process_request,
|
|
8
|
+
process_response,
|
|
9
|
+
start_as_current_span_async,
|
|
10
|
+
)
|
|
11
|
+
from opentelemetry.semconv_ai import SpanAttributes, TraceloopSpanKindValues
|
|
12
|
+
|
|
13
|
+
V9_MODULE_NAME = "llama_index.response_synthesizers"
|
|
14
|
+
V10_MODULE_NAME = "llama_index.core.response_synthesizers"
|
|
15
|
+
V10_LEGACY_MODULE_NAME = "llama_index.legacy.response_synthesizers.base"
|
|
16
|
+
|
|
17
|
+
CLASS_NAME = "BaseSynthesizer"
|
|
18
|
+
TASK_NAME = "synthesize"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class BaseSynthesizerInstrumentor:
|
|
22
|
+
def __init__(self, tracer):
|
|
23
|
+
self._tracer = tracer
|
|
24
|
+
|
|
25
|
+
def instrument(self):
|
|
26
|
+
try:
|
|
27
|
+
package_version("llama-index-core")
|
|
28
|
+
self._instrument_module(V10_MODULE_NAME)
|
|
29
|
+
self._instrument_module(V10_LEGACY_MODULE_NAME)
|
|
30
|
+
|
|
31
|
+
except PackageNotFoundError:
|
|
32
|
+
self._instrument_module(V9_MODULE_NAME)
|
|
33
|
+
|
|
34
|
+
def _instrument_module(self, module_name):
|
|
35
|
+
wrap_function_wrapper(
|
|
36
|
+
module_name, f"{CLASS_NAME}.synthesize", synthesize_wrapper(self._tracer)
|
|
37
|
+
)
|
|
38
|
+
wrap_function_wrapper(
|
|
39
|
+
module_name, f"{CLASS_NAME}.asynthesize", asynthesize_wrapper(self._tracer)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@_with_tracer_wrapper
|
|
44
|
+
def synthesize_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
45
|
+
with tracer.start_as_current_span(f"{TASK_NAME}.task") as span:
|
|
46
|
+
span.set_attribute(
|
|
47
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
48
|
+
TraceloopSpanKindValues.TASK.value,
|
|
49
|
+
)
|
|
50
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
51
|
+
|
|
52
|
+
process_request(span, args, kwargs)
|
|
53
|
+
res = wrapped(*args, **kwargs)
|
|
54
|
+
process_response(span, res)
|
|
55
|
+
return res
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@_with_tracer_wrapper
|
|
59
|
+
async def asynthesize_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
60
|
+
async with start_as_current_span_async(
|
|
61
|
+
tracer=tracer, name=f"{TASK_NAME}.task"
|
|
62
|
+
) as span:
|
|
63
|
+
span.set_attribute(
|
|
64
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
65
|
+
TraceloopSpanKindValues.TASK.value,
|
|
66
|
+
)
|
|
67
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, TASK_NAME)
|
|
68
|
+
|
|
69
|
+
process_request(span, args, kwargs)
|
|
70
|
+
res = await wrapped(*args, **kwargs)
|
|
71
|
+
process_response(span, res)
|
|
72
|
+
return res
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from importlib.metadata import version as package_version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from wrapt import wrap_function_wrapper
|
|
4
|
+
|
|
5
|
+
from opentelemetry.instrumentation.llamaindex.utils import (
|
|
6
|
+
_with_tracer_wrapper,
|
|
7
|
+
process_request,
|
|
8
|
+
process_response,
|
|
9
|
+
start_as_current_span_async,
|
|
10
|
+
)
|
|
11
|
+
from opentelemetry.semconv_ai import SpanAttributes, TraceloopSpanKindValues
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
TO_INSTRUMENT = [
|
|
15
|
+
{
|
|
16
|
+
"class": "FunctionTool",
|
|
17
|
+
"v9_module": "llama_index.tools.function_tool",
|
|
18
|
+
"v10_module": "llama_index.core.tools.function_tool",
|
|
19
|
+
"v10_legacy_module": "llama_index.legacy.tools.function_tool",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"class": "QueryEngineTool",
|
|
23
|
+
"v9_module": "llama_index.tools.query_engine",
|
|
24
|
+
"v10_module": "llama_index.core.tools.query_engine",
|
|
25
|
+
"v10_legacy_module": "llama_index.legacy.tools.query_engine",
|
|
26
|
+
},
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BaseToolInstrumentor:
|
|
31
|
+
def __init__(self, tracer):
|
|
32
|
+
self._tracer = tracer
|
|
33
|
+
|
|
34
|
+
def instrument(self):
|
|
35
|
+
for module in TO_INSTRUMENT:
|
|
36
|
+
try:
|
|
37
|
+
package_version("llama-index-core")
|
|
38
|
+
self._instrument_module(module["v10_module"], module["class"])
|
|
39
|
+
self._instrument_module(module["v10_legacy_module"], module["class"])
|
|
40
|
+
|
|
41
|
+
except PackageNotFoundError:
|
|
42
|
+
self._instrument_module(module["v9_module"], module["class"])
|
|
43
|
+
|
|
44
|
+
def _instrument_module(self, module_name, class_name):
|
|
45
|
+
wrap_function_wrapper(
|
|
46
|
+
module_name, f"{class_name}.call", query_wrapper(self._tracer)
|
|
47
|
+
)
|
|
48
|
+
wrap_function_wrapper(
|
|
49
|
+
module_name, f"{class_name}.acall", aquery_wrapper(self._tracer)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@_with_tracer_wrapper
|
|
54
|
+
def query_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
55
|
+
name = instance.__class__.__name__
|
|
56
|
+
with tracer.start_as_current_span(f"{name}.tool") as span:
|
|
57
|
+
span.set_attribute(
|
|
58
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
59
|
+
TraceloopSpanKindValues.TOOL.value,
|
|
60
|
+
)
|
|
61
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, name)
|
|
62
|
+
|
|
63
|
+
process_request(span, args, kwargs)
|
|
64
|
+
res = wrapped(*args, **kwargs)
|
|
65
|
+
process_response(span, res)
|
|
66
|
+
return res
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@_with_tracer_wrapper
|
|
70
|
+
async def aquery_wrapper(tracer, wrapped, instance, args, kwargs):
|
|
71
|
+
name = instance.__class__.__name__
|
|
72
|
+
async with start_as_current_span_async(tracer=tracer, name=f"{name}.tool") as span:
|
|
73
|
+
span.set_attribute(
|
|
74
|
+
SpanAttributes.TRACELOOP_SPAN_KIND,
|
|
75
|
+
TraceloopSpanKindValues.TOOL.value,
|
|
76
|
+
)
|
|
77
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, name)
|
|
78
|
+
|
|
79
|
+
process_request(span, args, kwargs)
|
|
80
|
+
res = await wrapped(*args, **kwargs)
|
|
81
|
+
process_response(span, res)
|
|
82
|
+
return res
|