monocle-apptrace 0.0.1__py3-none-any.whl → 0.1.0__py3-none-any.whl
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.
Potentially problematic release.
This version of monocle-apptrace might be problematic. Click here for more details.
- monocle_apptrace/README.md +2 -2
- monocle_apptrace/__init__.py +0 -2
- monocle_apptrace/constants.py +22 -0
- monocle_apptrace/exporters/file_exporter.py +63 -0
- monocle_apptrace/haystack/__init__.py +5 -24
- monocle_apptrace/haystack/wrap_node.py +1 -1
- monocle_apptrace/haystack/wrap_openai.py +1 -9
- monocle_apptrace/haystack/wrap_pipeline.py +6 -9
- monocle_apptrace/instrumentor.py +25 -28
- monocle_apptrace/langchain/__init__.py +5 -94
- monocle_apptrace/llamaindex/__init__.py +7 -63
- monocle_apptrace/utils.py +37 -17
- monocle_apptrace/wrap_common.py +97 -43
- monocle_apptrace/wrapper.py +3 -3
- monocle_apptrace/wrapper_config/haystack_methods.json +25 -0
- monocle_apptrace/wrapper_config/lang_chain_methods.json +106 -0
- monocle_apptrace/wrapper_config/llama_index_methods.json +70 -0
- {monocle_apptrace-0.0.1.dist-info → monocle_apptrace-0.1.0.dist-info}/METADATA +3 -2
- monocle_apptrace-0.1.0.dist-info/RECORD +22 -0
- monocle_apptrace-0.0.1.dist-info/RECORD +0 -17
- {monocle_apptrace-0.0.1.dist-info → monocle_apptrace-0.1.0.dist-info}/WHEEL +0 -0
- {monocle_apptrace-0.0.1.dist-info → monocle_apptrace-0.1.0.dist-info}/licenses/LICENSE +0 -0
- {monocle_apptrace-0.0.1.dist-info → monocle_apptrace-0.1.0.dist-info}/licenses/NOTICE +0 -0
monocle_apptrace/README.md
CHANGED
|
@@ -62,13 +62,13 @@ setup_monocle_telemetry(
|
|
|
62
62
|
wrapper_methods=[
|
|
63
63
|
WrapperMethod(
|
|
64
64
|
package="langchain.schema.runnable",
|
|
65
|
-
|
|
65
|
+
object_name="RunnableParallel",
|
|
66
66
|
method="invoke",
|
|
67
67
|
span_name="langchain.workflow",
|
|
68
68
|
wrapper=task_wrapper),
|
|
69
69
|
WrapperMethod(
|
|
70
70
|
package="langchain.schema.runnable",
|
|
71
|
-
|
|
71
|
+
object_name="RunnableParallel",
|
|
72
72
|
method="ainvoke",
|
|
73
73
|
span_name="langchain.workflow",
|
|
74
74
|
wrapper=atask_wrapper)
|
monocle_apptrace/__init__.py
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Azure environment constants
|
|
2
|
+
AZURE_ML_ENDPOINT_ENV_NAME = "AZUREML_ENTRY_SCRIPT"
|
|
3
|
+
AZURE_FUNCTION_WORKER_ENV_NAME = "FUNCTIONS_WORKER_RUNTIME"
|
|
4
|
+
AZURE_APP_SERVICE_ENV_NAME = "WEBSITE_SITE_NAME"
|
|
5
|
+
AWS_LAMBDA_ENV_NAME = "AWS_LAMBDA_RUNTIME_API"
|
|
6
|
+
|
|
7
|
+
# Azure naming reference can be found here
|
|
8
|
+
# https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations
|
|
9
|
+
AZURE_FUNCTION_NAME = "azure.func"
|
|
10
|
+
AZURE_APP_SERVICE_NAME = "azure.asp"
|
|
11
|
+
AZURE_ML_SERVICE_NAME = "azure.mlw"
|
|
12
|
+
AWS_LAMBDA_SERVICE_NAME = "aws.lambda"
|
|
13
|
+
|
|
14
|
+
azure_service_map = {
|
|
15
|
+
AZURE_ML_ENDPOINT_ENV_NAME: AZURE_ML_SERVICE_NAME,
|
|
16
|
+
AZURE_APP_SERVICE_ENV_NAME: AZURE_APP_SERVICE_NAME,
|
|
17
|
+
AZURE_FUNCTION_WORKER_ENV_NAME: AZURE_FUNCTION_NAME
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
aws_service_map = {
|
|
21
|
+
AWS_LAMBDA_ENV_NAME: AWS_LAMBDA_SERVICE_NAME
|
|
22
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#pylint: disable=consider-using-with
|
|
2
|
+
|
|
3
|
+
from os import linesep, path
|
|
4
|
+
from io import TextIOWrapper
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Optional, Callable, Sequence
|
|
7
|
+
from opentelemetry.sdk.trace import ReadableSpan
|
|
8
|
+
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
|
9
|
+
from opentelemetry.sdk.resources import SERVICE_NAME
|
|
10
|
+
|
|
11
|
+
DEFAULT_FILE_PREFIX:str = "monocle_trace_"
|
|
12
|
+
DEFAULT_TIME_FORMAT:str = "%Y-%m-%d_%H.%M.%S"
|
|
13
|
+
|
|
14
|
+
class FileSpanExporter(SpanExporter):
|
|
15
|
+
current_trace_id: int = None
|
|
16
|
+
current_file_path: str = None
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
service_name: Optional[str] = None,
|
|
21
|
+
out_path:str = ".",
|
|
22
|
+
file_prefix = DEFAULT_FILE_PREFIX,
|
|
23
|
+
time_format = DEFAULT_TIME_FORMAT,
|
|
24
|
+
formatter: Callable[
|
|
25
|
+
[ReadableSpan], str
|
|
26
|
+
] = lambda span: span.to_json()
|
|
27
|
+
+ linesep,
|
|
28
|
+
):
|
|
29
|
+
self.out_handle:TextIOWrapper = None
|
|
30
|
+
self.formatter = formatter
|
|
31
|
+
self.service_name = service_name
|
|
32
|
+
self.output_path = out_path
|
|
33
|
+
self.file_prefix = file_prefix
|
|
34
|
+
self.time_format = time_format
|
|
35
|
+
|
|
36
|
+
def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
|
|
37
|
+
for span in spans:
|
|
38
|
+
if span.context.trace_id != self.current_trace_id:
|
|
39
|
+
self.rotate_file(span.resource.attributes[SERVICE_NAME],
|
|
40
|
+
span.context.trace_id)
|
|
41
|
+
self.out_handle.write(self.formatter(span))
|
|
42
|
+
self.out_handle.flush()
|
|
43
|
+
return SpanExportResult.SUCCESS
|
|
44
|
+
|
|
45
|
+
def rotate_file(self, trace_name:str, trace_id:int) -> None:
|
|
46
|
+
self.reset_handle()
|
|
47
|
+
self.current_file_path = path.join(self.output_path,
|
|
48
|
+
self.file_prefix + trace_name + "_" + hex(trace_id) + "_"
|
|
49
|
+
+ datetime.now().strftime(self.time_format) + ".json")
|
|
50
|
+
self.out_handle = open(self.current_file_path, "w", encoding='UTF-8')
|
|
51
|
+
self.current_trace_id = trace_id
|
|
52
|
+
|
|
53
|
+
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
54
|
+
self.out_handle.flush()
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
def reset_handle(self) -> None:
|
|
58
|
+
if self.out_handle is not None:
|
|
59
|
+
self.out_handle.close()
|
|
60
|
+
self.out_handle = None
|
|
61
|
+
|
|
62
|
+
def shutdown(self) -> None:
|
|
63
|
+
self.reset_handle()
|
|
@@ -1,28 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
import os
|
|
3
3
|
import logging
|
|
4
|
-
from monocle_apptrace.
|
|
5
|
-
from monocle_apptrace.haystack.wrap_pipeline import wrap as wrap_pipeline
|
|
4
|
+
from monocle_apptrace.utils import load_wrapper_from_config
|
|
6
5
|
|
|
7
6
|
logger = logging.getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
HAYSTACK_METHODS =
|
|
10
|
-
|
|
11
|
-
"package": "haystack.components.generators.openai",
|
|
12
|
-
"object": "OpenAIGenerator",
|
|
13
|
-
"method": "run",
|
|
14
|
-
"wrapper": wrap_openai,
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"package": "haystack.components.generators.chat.openai",
|
|
18
|
-
"object": "OpenAIChatGenerator",
|
|
19
|
-
"method": "run",
|
|
20
|
-
"wrapper": wrap_openai,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"package": "haystack.core.pipeline.pipeline",
|
|
24
|
-
"object": "Pipeline",
|
|
25
|
-
"method": "run",
|
|
26
|
-
"wrapper": wrap_pipeline,
|
|
27
|
-
},
|
|
28
|
-
]
|
|
7
|
+
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
8
|
+
HAYSTACK_METHODS = load_wrapper_from_config(
|
|
9
|
+
os.path.join(parent_dir, 'wrapper_config', 'haystack_methods.json'))
|
|
@@ -21,7 +21,7 @@ def wrap(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
21
21
|
workflow_name = span.resource.attributes.get("service.name")
|
|
22
22
|
span.set_attribute("workflow_name",workflow_name)
|
|
23
23
|
span.set_attribute("workflow_type", WORKFLOW_TYPE_MAP["haystack"])
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
response = wrapped(*args, **kwargs)
|
|
26
26
|
|
|
27
27
|
return response
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
import logging
|
|
4
2
|
from opentelemetry import context as context_api
|
|
5
3
|
from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY
|
|
@@ -17,9 +15,7 @@ def _set_input_attributes(span, kwargs, instance, args):
|
|
|
17
15
|
|
|
18
16
|
if 'model' in instance.__dict__:
|
|
19
17
|
model_name = instance.__dict__.get("model")
|
|
20
|
-
set_span_attribute(span, "
|
|
21
|
-
|
|
22
|
-
return
|
|
18
|
+
set_span_attribute(span, "model_name", model_name)
|
|
23
19
|
|
|
24
20
|
@dont_throw
|
|
25
21
|
def _set_response_attributes(span, response):
|
|
@@ -39,14 +35,10 @@ def wrap_openai(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
39
35
|
with tracer.start_as_current_span("haystack.openai") as span:
|
|
40
36
|
if span.is_recording():
|
|
41
37
|
_set_input_attributes(span, kwargs, instance, args)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
38
|
response = wrapped(*args, **kwargs)
|
|
46
39
|
|
|
47
40
|
if response:
|
|
48
41
|
if span.is_recording():
|
|
49
42
|
_set_response_attributes(span, response)
|
|
50
|
-
|
|
51
43
|
|
|
52
44
|
return response
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
import logging
|
|
4
2
|
from opentelemetry import context as context_api
|
|
5
3
|
from opentelemetry.context import attach, set_value
|
|
@@ -18,13 +16,12 @@ def wrap(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
18
16
|
name = "haystack_pipeline"
|
|
19
17
|
attach(set_value("workflow_name", name))
|
|
20
18
|
inputs = set()
|
|
21
|
-
|
|
19
|
+
workflow_input = get_workflow_input(args, inputs)
|
|
22
20
|
|
|
23
21
|
with tracer.start_as_current_span(f"{name}.workflow") as span:
|
|
24
|
-
span.set_attribute(PROMPT_INPUT_KEY,
|
|
22
|
+
span.set_attribute(PROMPT_INPUT_KEY, workflow_input)
|
|
25
23
|
workflow_name = span.resource.attributes.get("service.name")
|
|
26
24
|
set_workflow_attributes(span, workflow_name)
|
|
27
|
-
|
|
28
25
|
response = wrapped(*args, **kwargs)
|
|
29
26
|
set_workflow_output(span, response)
|
|
30
27
|
return response
|
|
@@ -37,12 +34,12 @@ def get_workflow_input(args, inputs):
|
|
|
37
34
|
for value in args[0].values():
|
|
38
35
|
for text in value.values():
|
|
39
36
|
inputs.add(text)
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
|
|
38
|
+
workflow_input: str = ""
|
|
42
39
|
|
|
43
40
|
for input_str in inputs:
|
|
44
|
-
|
|
45
|
-
return
|
|
41
|
+
workflow_input = workflow_input + input_str
|
|
42
|
+
return workflow_input
|
|
46
43
|
|
|
47
44
|
def set_workflow_attributes(span, workflow_name):
|
|
48
45
|
span.set_attribute("workflow_name",workflow_name)
|
monocle_apptrace/instrumentor.py
CHANGED
|
@@ -10,25 +10,26 @@ from opentelemetry.sdk.trace import TracerProvider, Span
|
|
|
10
10
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanProcessor
|
|
11
11
|
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
12
12
|
from opentelemetry import trace
|
|
13
|
+
from opentelemetry.context import get_value, attach, set_value
|
|
13
14
|
from monocle_apptrace.wrap_common import CONTEXT_PROPERTIES_KEY
|
|
14
15
|
from monocle_apptrace.wrapper import INBUILT_METHODS_LIST, WrapperMethod
|
|
15
|
-
from
|
|
16
|
+
from monocle_apptrace.exporters.file_exporter import FileSpanExporter
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
20
|
-
_instruments = (
|
|
21
|
+
_instruments = ()
|
|
21
22
|
|
|
22
23
|
class MonocleInstrumentor(BaseInstrumentor):
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
workflow_name: str = ""
|
|
25
26
|
user_wrapper_methods: list[WrapperMethod] = []
|
|
26
27
|
instrumented_method_list: list[object] = []
|
|
27
|
-
|
|
28
|
+
|
|
28
29
|
def __init__(
|
|
29
30
|
self,
|
|
30
|
-
user_wrapper_methods: list[WrapperMethod] =
|
|
31
|
-
self.user_wrapper_methods = user_wrapper_methods
|
|
31
|
+
user_wrapper_methods: list[WrapperMethod] = None) -> None:
|
|
32
|
+
self.user_wrapper_methods = user_wrapper_methods or []
|
|
32
33
|
super().__init__()
|
|
33
34
|
|
|
34
35
|
def instrumentation_dependencies(self) -> Collection[str]:
|
|
@@ -63,11 +64,11 @@ class MonocleInstrumentor(BaseInstrumentor):
|
|
|
63
64
|
self.instrumented_method_list.append(wrapped_method)
|
|
64
65
|
except Exception as ex:
|
|
65
66
|
if wrapped_method in user_method_list:
|
|
66
|
-
logger.error(f"""_instrument wrap Exception: {str(ex)}
|
|
67
|
+
logger.error(f"""_instrument wrap Exception: {str(ex)}
|
|
67
68
|
for package: {wrap_package},
|
|
68
69
|
object:{wrap_object},
|
|
69
70
|
method:{wrap_method}""")
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
|
|
72
73
|
def _uninstrument(self, **kwargs):
|
|
73
74
|
for wrapped_method in self.instrumented_method_list:
|
|
@@ -80,33 +81,33 @@ class MonocleInstrumentor(BaseInstrumentor):
|
|
|
80
81
|
wrap_method,
|
|
81
82
|
)
|
|
82
83
|
except Exception as ex:
|
|
83
|
-
logger.error(f"""_instrument unwrap Exception: {str(ex)}
|
|
84
|
+
logger.error(f"""_instrument unwrap Exception: {str(ex)}
|
|
84
85
|
for package: {wrap_package},
|
|
85
86
|
object:{wrap_object},
|
|
86
87
|
method:{wrap_method}""")
|
|
87
|
-
|
|
88
88
|
|
|
89
89
|
def setup_monocle_telemetry(
|
|
90
90
|
workflow_name: str,
|
|
91
|
-
span_processors: List[SpanProcessor] =
|
|
92
|
-
wrapper_methods: List[WrapperMethod] =
|
|
91
|
+
span_processors: List[SpanProcessor] = None,
|
|
92
|
+
wrapper_methods: List[WrapperMethod] = None):
|
|
93
93
|
resource = Resource(attributes={
|
|
94
94
|
SERVICE_NAME: workflow_name
|
|
95
95
|
})
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
span_processors = span_processors or [BatchSpanProcessor(FileSpanExporter())]
|
|
97
|
+
trace_provider = TracerProvider(resource=resource)
|
|
98
|
+
tracer_provider_default = trace.get_tracer_provider()
|
|
99
|
+
provider_type = type(tracer_provider_default).__name__
|
|
100
|
+
is_proxy_provider = "Proxy" in provider_type
|
|
100
101
|
for processor in span_processors:
|
|
101
102
|
processor.on_start = on_processor_start
|
|
102
|
-
if not
|
|
103
|
-
|
|
103
|
+
if not is_proxy_provider:
|
|
104
|
+
tracer_provider_default.add_span_processor(processor)
|
|
104
105
|
else :
|
|
105
|
-
|
|
106
|
-
if
|
|
107
|
-
trace.set_tracer_provider(
|
|
108
|
-
instrumentor = MonocleInstrumentor(user_wrapper_methods=wrapper_methods)
|
|
109
|
-
instrumentor.app_name = workflow_name
|
|
106
|
+
trace_provider.add_span_processor(processor)
|
|
107
|
+
if is_proxy_provider :
|
|
108
|
+
trace.set_tracer_provider(trace_provider)
|
|
109
|
+
instrumentor = MonocleInstrumentor(user_wrapper_methods=wrapper_methods or [])
|
|
110
|
+
# instrumentor.app_name = workflow_name
|
|
110
111
|
if not instrumentor.is_instrumented_by_opentelemetry:
|
|
111
112
|
instrumentor.instrument()
|
|
112
113
|
|
|
@@ -117,11 +118,7 @@ def on_processor_start(span: Span, parent_context):
|
|
|
117
118
|
for key, value in context_properties.items():
|
|
118
119
|
span.set_attribute(
|
|
119
120
|
f"{CONTEXT_PROPERTIES_KEY}.{key}", value
|
|
120
|
-
)
|
|
121
|
+
)
|
|
121
122
|
|
|
122
123
|
def set_context_properties(properties: dict) -> None:
|
|
123
124
|
attach(set_value(CONTEXT_PROPERTIES_KEY, properties))
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
@@ -1,95 +1,6 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from monocle_apptrace.utils import load_wrapper_from_config
|
|
1
3
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
LANGCHAIN_METHODS = [
|
|
6
|
-
{
|
|
7
|
-
"package": "langchain.prompts.base",
|
|
8
|
-
"object": "BasePromptTemplate",
|
|
9
|
-
"method": "invoke",
|
|
10
|
-
"wrapper": task_wrapper,
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"package": "langchain.prompts.base",
|
|
14
|
-
"object": "BasePromptTemplate",
|
|
15
|
-
"method": "ainvoke",
|
|
16
|
-
"wrapper": atask_wrapper,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"package": "langchain.chat_models.base",
|
|
20
|
-
"object": "BaseChatModel",
|
|
21
|
-
"method": "invoke",
|
|
22
|
-
"wrapper": llm_wrapper,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"package": "langchain.chat_models.base",
|
|
26
|
-
"object": "BaseChatModel",
|
|
27
|
-
"method": "ainvoke",
|
|
28
|
-
"wrapper": allm_wrapper,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"package": "langchain_core.language_models.llms",
|
|
32
|
-
"object": "LLM",
|
|
33
|
-
"method": "_generate",
|
|
34
|
-
"wrapper": llm_wrapper,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"package": "langchain_core.language_models.llms",
|
|
38
|
-
"object": "LLM",
|
|
39
|
-
"method": "_agenerate",
|
|
40
|
-
"wrapper": llm_wrapper,
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"package": "langchain_core.retrievers",
|
|
44
|
-
"object": "BaseRetriever",
|
|
45
|
-
"method": "invoke",
|
|
46
|
-
"wrapper": task_wrapper,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"package": "langchain_core.retrievers",
|
|
50
|
-
"object": "BaseRetriever",
|
|
51
|
-
"method": "ainvoke",
|
|
52
|
-
"wrapper": atask_wrapper,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"package": "langchain.schema",
|
|
56
|
-
"object": "BaseOutputParser",
|
|
57
|
-
"method": "invoke",
|
|
58
|
-
"wrapper": task_wrapper,
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"package": "langchain.schema",
|
|
62
|
-
"object": "BaseOutputParser",
|
|
63
|
-
"method": "ainvoke",
|
|
64
|
-
"wrapper": atask_wrapper,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"package": "langchain.schema.runnable",
|
|
68
|
-
"object": "RunnableSequence",
|
|
69
|
-
"method": "invoke",
|
|
70
|
-
"span_name": "langchain.workflow",
|
|
71
|
-
"wrapper": task_wrapper,
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"package": "langchain.schema.runnable",
|
|
75
|
-
"object": "RunnableSequence",
|
|
76
|
-
"method": "ainvoke",
|
|
77
|
-
"span_name": "langchain.workflow",
|
|
78
|
-
"wrapper": atask_wrapper,
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"package": "langchain.schema.runnable",
|
|
82
|
-
"object": "RunnableParallel",
|
|
83
|
-
"method": "invoke",
|
|
84
|
-
"span_name": "langchain.workflow",
|
|
85
|
-
"wrapper": task_wrapper,
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"package": "langchain.schema.runnable",
|
|
89
|
-
"object": "RunnableParallel",
|
|
90
|
-
"method": "ainvoke",
|
|
91
|
-
"span_name": "langchain.workflow",
|
|
92
|
-
"wrapper": atask_wrapper,
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
]
|
|
4
|
+
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
5
|
+
LANGCHAIN_METHODS = load_wrapper_from_config(
|
|
6
|
+
os.path.join(parent_dir, 'wrapper_config', 'lang_chain_methods.json'))
|
|
@@ -1,71 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
#pylint: disable=protected-access
|
|
3
|
+
import os
|
|
4
|
+
from monocle_apptrace.utils import load_wrapper_from_config
|
|
4
5
|
|
|
5
6
|
def get_llm_span_name_for_openai(instance):
|
|
6
|
-
if (hasattr(instance, "_is_azure_client")
|
|
7
|
+
if (hasattr(instance, "_is_azure_client")
|
|
7
8
|
and callable(getattr(instance, "_is_azure_client"))
|
|
8
9
|
and instance._is_azure_client()):
|
|
9
10
|
return "llamaindex.azure_openai"
|
|
10
11
|
return "llamaindex.openai"
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"object": "BaseRetriever",
|
|
16
|
-
"method": "retrieve",
|
|
17
|
-
"span_name": "llamaindex.retrieve",
|
|
18
|
-
"wrapper": task_wrapper
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"package": "llama_index.core.indices.base_retriever",
|
|
22
|
-
"object": "BaseRetriever",
|
|
23
|
-
"method": "aretrieve",
|
|
24
|
-
"span_name": "llamaindex.retrieve",
|
|
25
|
-
"wrapper": atask_wrapper
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"package": "llama_index.core.base.base_query_engine",
|
|
29
|
-
"object": "BaseQueryEngine",
|
|
30
|
-
"method": "query",
|
|
31
|
-
"span_name": "llamaindex.query",
|
|
32
|
-
"wrapper": task_wrapper,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"package": "llama_index.core.base.base_query_engine",
|
|
36
|
-
"object": "BaseQueryEngine",
|
|
37
|
-
"method": "aquery",
|
|
38
|
-
"span_name": "llamaindex.query",
|
|
39
|
-
"wrapper": atask_wrapper,
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"package": "llama_index.core.llms.custom",
|
|
43
|
-
"object": "CustomLLM",
|
|
44
|
-
"method": "chat",
|
|
45
|
-
"span_name": "llamaindex.llmchat",
|
|
46
|
-
"wrapper": task_wrapper,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"package": "llama_index.core.llms.custom",
|
|
50
|
-
"object": "CustomLLM",
|
|
51
|
-
"method": "achat",
|
|
52
|
-
"span_name": "llamaindex.llmchat",
|
|
53
|
-
"wrapper": atask_wrapper,
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"package": "llama_index.llms.openai.base",
|
|
57
|
-
"object": "OpenAI",
|
|
58
|
-
"method": "chat",
|
|
59
|
-
"span_name": "llamaindex.openai",
|
|
60
|
-
"span_name_getter" : get_llm_span_name_for_openai,
|
|
61
|
-
"wrapper": llm_wrapper,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"package": "llama_index.llms.openai.base",
|
|
65
|
-
"object": "OpenAI",
|
|
66
|
-
"method": "achat",
|
|
67
|
-
"span_name": "llamaindex.openai",
|
|
68
|
-
"wrapper": allm_wrapper,
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
|
|
13
|
+
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
14
|
+
LLAMAINDEX_METHODS = load_wrapper_from_config(
|
|
15
|
+
os.path.join(parent_dir, 'wrapper_config', 'llama_index_methods.json'))
|
monocle_apptrace/utils.py
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
import logging
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import json
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
import os
|
|
5
|
+
from opentelemetry.trace import Span
|
|
6
|
+
from monocle_apptrace.constants import azure_service_map, aws_service_map
|
|
8
7
|
|
|
9
8
|
def set_span_attribute(span, name, value):
|
|
10
9
|
if value is not None:
|
|
11
10
|
if value != "":
|
|
12
11
|
span.set_attribute(name, value)
|
|
13
|
-
return
|
|
14
|
-
|
|
15
12
|
|
|
16
13
|
def dont_throw(func):
|
|
17
14
|
"""
|
|
@@ -22,15 +19,12 @@ def dont_throw(func):
|
|
|
22
19
|
"""
|
|
23
20
|
# Obtain a logger specific to the function's module
|
|
24
21
|
logger = logging.getLogger(func.__module__)
|
|
25
|
-
|
|
22
|
+
# pylint: disable=inconsistent-return-statements
|
|
26
23
|
def wrapper(*args, **kwargs):
|
|
27
24
|
try:
|
|
28
25
|
return func(*args, **kwargs)
|
|
29
|
-
except Exception as
|
|
30
|
-
logger.warning("Failed to execute %s, error: %s", func.__name__, str(
|
|
31
|
-
if Config.exception_logger:
|
|
32
|
-
Config.exception_logger(e)
|
|
33
|
-
|
|
26
|
+
except Exception as ex:
|
|
27
|
+
logger.warning("Failed to execute %s, error: %s", func.__name__, str(ex))
|
|
34
28
|
return wrapper
|
|
35
29
|
|
|
36
30
|
def with_tracer_wrapper(func):
|
|
@@ -44,10 +38,36 @@ def with_tracer_wrapper(func):
|
|
|
44
38
|
|
|
45
39
|
return _with_tracer
|
|
46
40
|
|
|
47
|
-
def resolve_from_alias(
|
|
41
|
+
def resolve_from_alias(my_map, alias):
|
|
48
42
|
"""Find a alias that is not none from list of aliases"""
|
|
49
43
|
|
|
50
44
|
for i in alias:
|
|
51
|
-
if i in
|
|
52
|
-
return
|
|
45
|
+
if i in my_map.keys():
|
|
46
|
+
return my_map[i]
|
|
53
47
|
return None
|
|
48
|
+
|
|
49
|
+
def load_wrapper_from_config(config_file_path: str, module_name: str = None):
|
|
50
|
+
wrapper_methods = []
|
|
51
|
+
with open(config_file_path, encoding='UTF-8') as config_file:
|
|
52
|
+
json_data = json.load(config_file)
|
|
53
|
+
wrapper_methods = json_data["wrapper_methods"]
|
|
54
|
+
for wrapper_method in wrapper_methods:
|
|
55
|
+
wrapper_method["wrapper"] = get_wrapper_method(
|
|
56
|
+
wrapper_method["wrapper_package"], wrapper_method["wrapper_method"])
|
|
57
|
+
if "span_name_getter_method" in wrapper_method :
|
|
58
|
+
wrapper_method["span_name_getter"] = get_wrapper_method(
|
|
59
|
+
wrapper_method["span_name_getter_package"],
|
|
60
|
+
wrapper_method["span_name_getter_method"])
|
|
61
|
+
return wrapper_methods
|
|
62
|
+
|
|
63
|
+
def get_wrapper_method(package_name: str, method_name: str):
|
|
64
|
+
wrapper_module = import_module("monocle_apptrace." + package_name)
|
|
65
|
+
return getattr(wrapper_module, method_name)
|
|
66
|
+
|
|
67
|
+
def update_span_with_infra_name(span: Span, span_key: str):
|
|
68
|
+
for key,val in azure_service_map.items():
|
|
69
|
+
if key in os.environ:
|
|
70
|
+
span.set_attribute(span_key, val)
|
|
71
|
+
for key,val in aws_service_map.items():
|
|
72
|
+
if key in os.environ:
|
|
73
|
+
span.set_attribute(span_key, val)
|
monocle_apptrace/wrap_common.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
#pylint: disable=protected-access
|
|
1
2
|
import logging
|
|
2
3
|
import os
|
|
4
|
+
from urllib.parse import urlparse
|
|
3
5
|
|
|
4
6
|
from opentelemetry.trace import Span, Tracer
|
|
5
|
-
|
|
6
|
-
from monocle_apptrace.utils import resolve_from_alias, with_tracer_wrapper
|
|
7
|
+
from monocle_apptrace.utils import resolve_from_alias, update_span_with_infra_name, with_tracer_wrapper
|
|
7
8
|
|
|
8
9
|
logger = logging.getLogger(__name__)
|
|
9
10
|
WORKFLOW_TYPE_KEY = "workflow_type"
|
|
@@ -15,6 +16,8 @@ QUERY = "question"
|
|
|
15
16
|
RESPONSE = "response"
|
|
16
17
|
TAGS = "tags"
|
|
17
18
|
CONTEXT_PROPERTIES_KEY = "workflow_context_properties"
|
|
19
|
+
INFRA_SERVICE_KEY = "infra_service_name"
|
|
20
|
+
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
WORKFLOW_TYPE_MAP = {
|
|
@@ -37,29 +40,38 @@ def task_wrapper(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
37
40
|
name = to_wrap.get("span_name")
|
|
38
41
|
else:
|
|
39
42
|
name = f"langchain.task.{instance.__class__.__name__}"
|
|
40
|
-
kind = to_wrap.get("kind")
|
|
41
43
|
|
|
42
44
|
with tracer.start_as_current_span(name) as span:
|
|
43
|
-
|
|
44
|
-
update_span_with_prompt_input(to_wrap=to_wrap, wrapped_args=args, span=span)
|
|
45
|
-
|
|
46
|
-
#capture the tags attribute of the instance if present, else ignore
|
|
47
|
-
try:
|
|
48
|
-
span.set_attribute(TAGS, getattr(instance, TAGS))
|
|
49
|
-
except AttributeError:
|
|
50
|
-
pass
|
|
51
|
-
update_span_with_context_input(to_wrap=to_wrap, wrapped_args=args, span=span)
|
|
45
|
+
pre_task_processing(to_wrap, instance, args, span)
|
|
52
46
|
return_value = wrapped(*args, **kwargs)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if is_root_span(span):
|
|
56
|
-
workflow_name = span.resource.attributes.get("service.name")
|
|
57
|
-
span.set_attribute("workflow_name",workflow_name)
|
|
58
|
-
update_span_with_prompt_output(to_wrap=to_wrap, wrapped_args=return_value, span=span)
|
|
59
|
-
update_workflow_type(to_wrap, span)
|
|
47
|
+
post_task_processing(to_wrap, span, return_value)
|
|
60
48
|
|
|
61
49
|
return return_value
|
|
62
50
|
|
|
51
|
+
def post_task_processing(to_wrap, span, return_value):
|
|
52
|
+
update_span_with_context_output(to_wrap=to_wrap, return_value=return_value, span=span)
|
|
53
|
+
|
|
54
|
+
if is_root_span(span):
|
|
55
|
+
workflow_name = span.resource.attributes.get("service.name")
|
|
56
|
+
span.set_attribute("workflow_name",workflow_name)
|
|
57
|
+
update_span_with_prompt_output(to_wrap=to_wrap, wrapped_args=return_value, span=span)
|
|
58
|
+
update_workflow_type(to_wrap, span)
|
|
59
|
+
|
|
60
|
+
def pre_task_processing(to_wrap, instance, args, span):
|
|
61
|
+
if is_root_span(span):
|
|
62
|
+
update_span_with_prompt_input(to_wrap=to_wrap, wrapped_args=args, span=span)
|
|
63
|
+
|
|
64
|
+
update_span_with_infra_name(span, INFRA_SERVICE_KEY)
|
|
65
|
+
|
|
66
|
+
#capture the tags attribute of the instance if present, else ignore
|
|
67
|
+
try:
|
|
68
|
+
update_tags(instance, span)
|
|
69
|
+
except AttributeError:
|
|
70
|
+
pass
|
|
71
|
+
update_span_with_context_input(to_wrap=to_wrap, wrapped_args=args, span=span)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
63
75
|
@with_tracer_wrapper
|
|
64
76
|
async def atask_wrapper(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
65
77
|
"""Instruments and calls every function defined in TO_WRAP."""
|
|
@@ -74,9 +86,10 @@ async def atask_wrapper(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
74
86
|
name = to_wrap.get("span_name")
|
|
75
87
|
else:
|
|
76
88
|
name = f"langchain.task.{instance.__class__.__name__}"
|
|
77
|
-
kind = to_wrap.get("kind")
|
|
78
89
|
with tracer.start_as_current_span(name) as span:
|
|
90
|
+
pre_task_processing(to_wrap, instance, args, span)
|
|
79
91
|
return_value = await wrapped(*args, **kwargs)
|
|
92
|
+
post_task_processing(to_wrap, span, return_value)
|
|
80
93
|
|
|
81
94
|
return return_value
|
|
82
95
|
|
|
@@ -86,7 +99,7 @@ async def allm_wrapper(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
86
99
|
if instance.__class__.__name__ in ("AgentExecutor"):
|
|
87
100
|
return wrapped(*args, **kwargs)
|
|
88
101
|
|
|
89
|
-
if to_wrap.get("span_name_getter"):
|
|
102
|
+
if callable(to_wrap.get("span_name_getter")):
|
|
90
103
|
name = to_wrap.get("span_name_getter")(instance)
|
|
91
104
|
|
|
92
105
|
elif hasattr(instance, "name") and instance.name:
|
|
@@ -95,11 +108,11 @@ async def allm_wrapper(tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
95
108
|
name = to_wrap.get("span_name")
|
|
96
109
|
else:
|
|
97
110
|
name = f"langchain.task.{instance.__class__.__name__}"
|
|
98
|
-
kind = to_wrap.get("kind")
|
|
99
111
|
with tracer.start_as_current_span(name) as span:
|
|
100
112
|
update_llm_endpoint(curr_span= span, instance=instance)
|
|
101
113
|
|
|
102
114
|
return_value = await wrapped(*args, **kwargs)
|
|
115
|
+
update_span_from_llm_response(response = return_value, span = span)
|
|
103
116
|
|
|
104
117
|
return return_value
|
|
105
118
|
|
|
@@ -119,7 +132,6 @@ def llm_wrapper(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
|
|
|
119
132
|
name = to_wrap.get("span_name")
|
|
120
133
|
else:
|
|
121
134
|
name = f"langchain.task.{instance.__class__.__name__}"
|
|
122
|
-
kind = to_wrap.get("kind")
|
|
123
135
|
with tracer.start_as_current_span(name) as span:
|
|
124
136
|
update_llm_endpoint(curr_span= span, instance=instance)
|
|
125
137
|
|
|
@@ -138,24 +150,48 @@ def update_llm_endpoint(curr_span: Span, instance):
|
|
|
138
150
|
curr_span.set_attribute("temperature", temp_val)
|
|
139
151
|
# handling for model name
|
|
140
152
|
model_name = resolve_from_alias(instance.__dict__ , ["model","model_name"])
|
|
141
|
-
curr_span.set_attribute("
|
|
153
|
+
curr_span.set_attribute("model_name", model_name)
|
|
154
|
+
set_provider_name(curr_span, instance)
|
|
142
155
|
# handling AzureOpenAI deployment
|
|
143
|
-
deployment_name = resolve_from_alias(instance.__dict__ , [ "engine", "azure_deployment",
|
|
156
|
+
deployment_name = resolve_from_alias(instance.__dict__ , [ "engine", "azure_deployment",
|
|
144
157
|
"deployment_name", "deployment_id", "deployment"])
|
|
145
158
|
curr_span.set_attribute("az_openai_deployment", deployment_name)
|
|
146
159
|
# handling the inference endpoint
|
|
147
160
|
inference_ep = resolve_from_alias(instance.__dict__,["azure_endpoint","api_base"])
|
|
148
161
|
curr_span.set_attribute("inference_endpoint",inference_ep)
|
|
149
162
|
|
|
163
|
+
def set_provider_name(curr_span, instance):
|
|
164
|
+
provider_url = ""
|
|
165
|
+
|
|
166
|
+
try :
|
|
167
|
+
if isinstance(instance.client._client.base_url.host, str) :
|
|
168
|
+
provider_url = instance. client._client.base_url.host
|
|
169
|
+
except:
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
try :
|
|
173
|
+
if isinstance(instance.api_base, str):
|
|
174
|
+
provider_url = instance.api_base
|
|
175
|
+
except:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
try :
|
|
179
|
+
if len(provider_url) > 0:
|
|
180
|
+
parsed_provider_url = urlparse(provider_url)
|
|
181
|
+
curr_span.set_attribute("provider_name", parsed_provider_url.hostname or provider_url)
|
|
182
|
+
except:
|
|
183
|
+
pass
|
|
184
|
+
|
|
150
185
|
def is_root_span(curr_span: Span) -> bool:
|
|
151
|
-
return curr_span.parent
|
|
186
|
+
return curr_span.parent is None
|
|
152
187
|
|
|
153
188
|
def get_input_from_args(chain_args):
|
|
154
|
-
if len(chain_args) > 0 and
|
|
189
|
+
if len(chain_args) > 0 and isinstance(chain_args[0], str):
|
|
155
190
|
return chain_args[0]
|
|
156
191
|
return ""
|
|
157
192
|
|
|
158
193
|
def update_span_from_llm_response(response, span: Span):
|
|
194
|
+
|
|
159
195
|
# extract token uasge from langchain openai
|
|
160
196
|
if (response is not None and hasattr(response, "response_metadata")):
|
|
161
197
|
response_metadata = response.response_metadata
|
|
@@ -166,15 +202,19 @@ def update_span_from_llm_response(response, span: Span):
|
|
|
166
202
|
span.set_attribute("total_tokens", token_usage.get("total_tokens"))
|
|
167
203
|
# extract token usage from llamaindex openai
|
|
168
204
|
if(response is not None and hasattr(response, "raw")):
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
205
|
+
try:
|
|
206
|
+
if response.raw is not None:
|
|
207
|
+
token_usage = response.raw.get("usage") if isinstance(response.raw, dict) else getattr(response.raw, "usage", None)
|
|
208
|
+
if token_usage is not None:
|
|
209
|
+
if getattr(token_usage, "completion_tokens", None):
|
|
210
|
+
span.set_attribute("completion_tokens", getattr(token_usage, "completion_tokens"))
|
|
211
|
+
if getattr(token_usage, "prompt_tokens", None):
|
|
212
|
+
span.set_attribute("prompt_tokens", getattr(token_usage, "prompt_tokens"))
|
|
213
|
+
if getattr(token_usage, "total_tokens", None):
|
|
214
|
+
span.set_attribute("total_tokens", getattr(token_usage, "total_tokens"))
|
|
215
|
+
except AttributeError:
|
|
216
|
+
token_usage = None
|
|
217
|
+
|
|
178
218
|
|
|
179
219
|
def update_workflow_type(to_wrap, span: Span):
|
|
180
220
|
package_name = to_wrap.get('package')
|
|
@@ -185,30 +225,44 @@ def update_workflow_type(to_wrap, span: Span):
|
|
|
185
225
|
|
|
186
226
|
def update_span_with_context_input(to_wrap, wrapped_args ,span: Span):
|
|
187
227
|
package_name: str = to_wrap.get('package')
|
|
188
|
-
if
|
|
228
|
+
if "langchain_core.retrievers" in package_name:
|
|
189
229
|
input_arg_text = wrapped_args[0]
|
|
190
230
|
span.add_event(CONTEXT_INPUT_KEY, {QUERY:input_arg_text})
|
|
191
|
-
if
|
|
231
|
+
if "llama_index.core.indices.base_retriever" in package_name:
|
|
192
232
|
input_arg_text = wrapped_args[0].query_str
|
|
193
233
|
span.add_event(CONTEXT_INPUT_KEY, {QUERY:input_arg_text})
|
|
194
234
|
|
|
195
235
|
def update_span_with_context_output(to_wrap, return_value ,span: Span):
|
|
196
236
|
package_name: str = to_wrap.get('package')
|
|
197
|
-
if
|
|
237
|
+
if "llama_index.core.indices.base_retriever" in package_name:
|
|
198
238
|
output_arg_text = return_value[0].text
|
|
199
239
|
span.add_event(CONTEXT_OUTPUT_KEY, {RESPONSE:output_arg_text})
|
|
200
240
|
|
|
201
241
|
def update_span_with_prompt_input(to_wrap, wrapped_args ,span: Span):
|
|
202
242
|
input_arg_text = wrapped_args[0]
|
|
203
|
-
|
|
243
|
+
|
|
204
244
|
if isinstance(input_arg_text, dict):
|
|
205
245
|
span.add_event(PROMPT_INPUT_KEY,input_arg_text)
|
|
206
|
-
else:
|
|
246
|
+
else:
|
|
207
247
|
span.add_event(PROMPT_INPUT_KEY,{QUERY:input_arg_text})
|
|
208
248
|
|
|
209
249
|
def update_span_with_prompt_output(to_wrap, wrapped_args ,span: Span):
|
|
210
250
|
package_name: str = to_wrap.get('package')
|
|
211
|
-
if
|
|
251
|
+
if isinstance(wrapped_args, str):
|
|
212
252
|
span.add_event(PROMPT_OUTPUT_KEY, {RESPONSE:wrapped_args})
|
|
213
|
-
if
|
|
253
|
+
if "llama_index.core.base.base_query_engine" in package_name:
|
|
214
254
|
span.add_event(PROMPT_OUTPUT_KEY, {RESPONSE:wrapped_args.response})
|
|
255
|
+
|
|
256
|
+
def update_tags(instance, span):
|
|
257
|
+
try:
|
|
258
|
+
# copy tags as is from langchain
|
|
259
|
+
span.set_attribute(TAGS, getattr(instance, TAGS))
|
|
260
|
+
except:
|
|
261
|
+
pass
|
|
262
|
+
try:
|
|
263
|
+
# extract embed model and vector store names for llamaindex
|
|
264
|
+
model_name = instance.retriever._embed_model.model_name
|
|
265
|
+
vector_store_name = type(instance.retriever._vector_store).__name__
|
|
266
|
+
span.set_attribute(TAGS, [model_name, vector_store_name])
|
|
267
|
+
except:
|
|
268
|
+
pass
|
monocle_apptrace/wrapper.py
CHANGED
|
@@ -5,20 +5,20 @@ from monocle_apptrace.langchain import LANGCHAIN_METHODS
|
|
|
5
5
|
from monocle_apptrace.llamaindex import LLAMAINDEX_METHODS
|
|
6
6
|
from monocle_apptrace.wrap_common import task_wrapper
|
|
7
7
|
|
|
8
|
+
# pylint: disable=too-few-public-methods
|
|
8
9
|
class WrapperMethod:
|
|
9
10
|
def __init__(
|
|
10
11
|
self,
|
|
11
12
|
package: str,
|
|
12
|
-
|
|
13
|
+
object_name: str,
|
|
13
14
|
method: str,
|
|
14
15
|
span_name: str = None,
|
|
15
16
|
wrapper = task_wrapper
|
|
16
17
|
):
|
|
17
18
|
self.package = package
|
|
18
|
-
self.object =
|
|
19
|
+
self.object = object_name
|
|
19
20
|
self.method = method
|
|
20
21
|
self.span_name = span_name
|
|
21
22
|
self.wrapper = wrapper
|
|
22
23
|
|
|
23
24
|
INBUILT_METHODS_LIST = LANGCHAIN_METHODS + LLAMAINDEX_METHODS + HAYSTACK_METHODS
|
|
24
|
-
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"wrapper_methods" : [
|
|
3
|
+
{
|
|
4
|
+
"package": "haystack.components.generators.openai",
|
|
5
|
+
"object": "OpenAIGenerator",
|
|
6
|
+
"method": "run",
|
|
7
|
+
"wrapper_package": "haystack.wrap_openai",
|
|
8
|
+
"wrapper_method": "wrap_openai"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"package": "haystack.components.generators.chat.openai",
|
|
12
|
+
"object": "OpenAIChatGenerator",
|
|
13
|
+
"method": "run",
|
|
14
|
+
"wrapper_package": "haystack.wrap_openai",
|
|
15
|
+
"wrapper_method": "wrap_openai"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"package": "haystack.core.pipeline.pipeline",
|
|
19
|
+
"object": "Pipeline",
|
|
20
|
+
"method": "run",
|
|
21
|
+
"wrapper_package": "haystack.wrap_pipeline",
|
|
22
|
+
"wrapper_method": "wrap"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"wrapper_methods" : [
|
|
3
|
+
{
|
|
4
|
+
"package": "langchain.prompts.base",
|
|
5
|
+
"object": "BasePromptTemplate",
|
|
6
|
+
"method": "invoke",
|
|
7
|
+
"wrapper_package": "wrap_common",
|
|
8
|
+
"wrapper_method": "task_wrapper"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"package": "langchain.prompts.base",
|
|
12
|
+
"object": "BasePromptTemplate",
|
|
13
|
+
"method": "ainvoke",
|
|
14
|
+
"wrapper_package": "wrap_common",
|
|
15
|
+
"wrapper_method": "atask_wrapper"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"package": "langchain.chat_models.base",
|
|
19
|
+
"object": "BaseChatModel",
|
|
20
|
+
"method": "invoke",
|
|
21
|
+
"wrapper_package": "wrap_common",
|
|
22
|
+
"wrapper_method": "llm_wrapper"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"package": "langchain.chat_models.base",
|
|
26
|
+
"object": "BaseChatModel",
|
|
27
|
+
"method": "ainvoke",
|
|
28
|
+
"wrapper_package": "wrap_common",
|
|
29
|
+
"wrapper_method": "allm_wrapper"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"package": "langchain_core.language_models.llms",
|
|
33
|
+
"object": "LLM",
|
|
34
|
+
"method": "_generate",
|
|
35
|
+
"wrapper_package": "wrap_common",
|
|
36
|
+
"wrapper_method": "llm_wrapper"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"package": "langchain_core.language_models.llms",
|
|
40
|
+
"object": "LLM",
|
|
41
|
+
"method": "_agenerate",
|
|
42
|
+
"wrapper_package": "wrap_common",
|
|
43
|
+
"wrapper_method": "llm_wrapper"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"package": "langchain_core.retrievers",
|
|
47
|
+
"object": "BaseRetriever",
|
|
48
|
+
"method": "invoke",
|
|
49
|
+
"wrapper_package": "wrap_common",
|
|
50
|
+
"wrapper_method": "task_wrapper"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"package": "langchain_core.retrievers",
|
|
54
|
+
"object": "BaseRetriever",
|
|
55
|
+
"method": "ainvoke",
|
|
56
|
+
"wrapper_package": "wrap_common",
|
|
57
|
+
"wrapper_method": "atask_wrapper"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"package": "langchain.schema",
|
|
61
|
+
"object": "BaseOutputParser",
|
|
62
|
+
"method": "invoke",
|
|
63
|
+
"wrapper_package": "wrap_common",
|
|
64
|
+
"wrapper_method": "task_wrapper"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"package": "langchain.schema",
|
|
68
|
+
"object": "BaseOutputParser",
|
|
69
|
+
"method": "ainvoke",
|
|
70
|
+
"wrapper_package": "wrap_common",
|
|
71
|
+
"wrapper_method": "atask_wrapper"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"package": "langchain.schema.runnable",
|
|
75
|
+
"object": "RunnableSequence",
|
|
76
|
+
"method": "invoke",
|
|
77
|
+
"span_name": "langchain.workflow",
|
|
78
|
+
"wrapper_package": "wrap_common",
|
|
79
|
+
"wrapper_method": "task_wrapper"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"package": "langchain.schema.runnable",
|
|
83
|
+
"object": "RunnableSequence",
|
|
84
|
+
"method": "ainvoke",
|
|
85
|
+
"span_name": "langchain.workflow",
|
|
86
|
+
"wrapper_package": "wrap_common",
|
|
87
|
+
"wrapper_method": "atask_wrapper"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"package": "langchain.schema.runnable",
|
|
91
|
+
"object": "RunnableParallel",
|
|
92
|
+
"method": "invoke",
|
|
93
|
+
"span_name": "langchain.workflow",
|
|
94
|
+
"wrapper_package": "wrap_common",
|
|
95
|
+
"wrapper_method": "task_wrapper"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"package": "langchain.schema.runnable",
|
|
99
|
+
"object": "RunnableParallel",
|
|
100
|
+
"method": "ainvoke",
|
|
101
|
+
"span_name": "langchain.workflow",
|
|
102
|
+
"wrapper_package": "wrap_common",
|
|
103
|
+
"wrapper_method": "atask_wrapper"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"wrapper_methods" : [
|
|
3
|
+
{
|
|
4
|
+
"package": "llama_index.core.indices.base_retriever",
|
|
5
|
+
"object": "BaseRetriever",
|
|
6
|
+
"method": "retrieve",
|
|
7
|
+
"span_name": "llamaindex.retrieve",
|
|
8
|
+
"wrapper_package": "wrap_common",
|
|
9
|
+
"wrapper_method": "task_wrapper"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"package": "llama_index.core.indices.base_retriever",
|
|
13
|
+
"object": "BaseRetriever",
|
|
14
|
+
"method": "aretrieve",
|
|
15
|
+
"span_name": "llamaindex.retrieve",
|
|
16
|
+
"wrapper_package": "wrap_common",
|
|
17
|
+
"wrapper_method": "atask_wrapper"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"package": "llama_index.core.base.base_query_engine",
|
|
21
|
+
"object": "BaseQueryEngine",
|
|
22
|
+
"method": "query",
|
|
23
|
+
"span_name": "llamaindex.query",
|
|
24
|
+
"wrapper_package": "wrap_common",
|
|
25
|
+
"wrapper_method": "task_wrapper"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"package": "llama_index.core.base.base_query_engine",
|
|
29
|
+
"object": "BaseQueryEngine",
|
|
30
|
+
"method": "aquery",
|
|
31
|
+
"span_name": "llamaindex.query",
|
|
32
|
+
"wrapper_package": "wrap_common",
|
|
33
|
+
"wrapper_method": "atask_wrapper"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"package": "llama_index.core.llms.custom",
|
|
37
|
+
"object": "CustomLLM",
|
|
38
|
+
"method": "chat",
|
|
39
|
+
"span_name": "llamaindex.llmchat",
|
|
40
|
+
"wrapper_package": "wrap_common",
|
|
41
|
+
"wrapper_method": "task_wrapper"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"package": "llama_index.core.llms.custom",
|
|
45
|
+
"object": "CustomLLM",
|
|
46
|
+
"method": "achat",
|
|
47
|
+
"span_name": "llamaindex.llmchat",
|
|
48
|
+
"wrapper_package": "wrap_common",
|
|
49
|
+
"wrapper_method": "atask_wrapper"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"package": "llama_index.llms.openai.base",
|
|
53
|
+
"object": "OpenAI",
|
|
54
|
+
"method": "chat",
|
|
55
|
+
"span_name": "llamaindex.openai",
|
|
56
|
+
"wrapper_package": "wrap_common",
|
|
57
|
+
"wrapper_method": "llm_wrapper",
|
|
58
|
+
"span_name_getter_package" : "llamaindex",
|
|
59
|
+
"span_name_getter_mothod" : "get_llm_span_name_for_openai"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"package": "llama_index.llms.openai.base",
|
|
63
|
+
"object": "OpenAI",
|
|
64
|
+
"method": "achat",
|
|
65
|
+
"span_name": "llamaindex.openai",
|
|
66
|
+
"wrapper_package": "wrap_common",
|
|
67
|
+
"wrapper_method": "allm_wrapper"
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: monocle_apptrace
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: package with monocle genAI tracing
|
|
5
5
|
Project-URL: Homepage, https://github.com/monocle2ai/monocle
|
|
6
6
|
Project-URL: Issues, https://github.com/monocle2ai/monocle/issues
|
|
@@ -27,6 +27,7 @@ Requires-Dist: llama-index-embeddings-huggingface==0.2.0; extra == 'dev'
|
|
|
27
27
|
Requires-Dist: llama-index-vector-stores-chroma==0.1.9; extra == 'dev'
|
|
28
28
|
Requires-Dist: llama-index==0.10.30; extra == 'dev'
|
|
29
29
|
Requires-Dist: numpy==1.26.4; extra == 'dev'
|
|
30
|
+
Requires-Dist: parameterized==0.9.0; extra == 'dev'
|
|
30
31
|
Requires-Dist: pytest==8.0.0; extra == 'dev'
|
|
31
32
|
Requires-Dist: sentence-transformers==2.6.1; extra == 'dev'
|
|
32
33
|
Requires-Dist: types-requests==2.31.0.20240106; extra == 'dev'
|
|
@@ -63,7 +64,7 @@ The traces are compatible with OpenTelemetry format. They are further enriched t
|
|
|
63
64
|
```
|
|
64
65
|
- Enable Monocle tracing in your app by adding following
|
|
65
66
|
```
|
|
66
|
-
|
|
67
|
+
setup_monocle_telemetry(workflow_name="your-app-name")
|
|
67
68
|
```
|
|
68
69
|
Please refer to [Monocle user guide](Monocle_User_Guide.md) for more details
|
|
69
70
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
monocle_apptrace/README.md,sha256=OVJgf1_HAm5L2-FSDZ-3AYfBjSxiT4fhE_CgKVaDVuQ,3104
|
|
2
|
+
monocle_apptrace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
monocle_apptrace/constants.py,sha256=wjObbmMTFL201x-bf3EOXevYygwkFH_1ng5dDrpE3z0,810
|
|
4
|
+
monocle_apptrace/instrumentor.py,sha256=IDCuqzvTLzYKBzHGX3q1gbiboq07LMkdOA8DhOUTEEU,5051
|
|
5
|
+
monocle_apptrace/utils.py,sha256=VMiWscPCNjp29IQE3ahprXjkfiMw160DbCo8WrjQCXk,2658
|
|
6
|
+
monocle_apptrace/wrap_common.py,sha256=zbYlhL7V655exfdE0h_aT6-THmmHL1ltzsm4cBZ4jq8,10875
|
|
7
|
+
monocle_apptrace/wrapper.py,sha256=cNUdfciAXNYAhvtOA2O4ONRvuT2bbHb4ax_7pALijEI,734
|
|
8
|
+
monocle_apptrace/exporters/file_exporter.py,sha256=gN9pJ_X5pcstVVsyivgHsjWhr443eRa6Y6Hx1rGLQAM,2280
|
|
9
|
+
monocle_apptrace/haystack/__init__.py,sha256=zcluKUIu1M9g_B3s_ZfzRS_vr7yMz5gj-6rqQ7bJ5B0,318
|
|
10
|
+
monocle_apptrace/haystack/wrap_node.py,sha256=IK07Wn3Lk1Os9URsyrmB1HXOH2FNdzK9fNLlR8TZdYc,908
|
|
11
|
+
monocle_apptrace/haystack/wrap_openai.py,sha256=Yp916DhOl0WI6virRi3L43snfsQm7PhI28wlDsg19v8,1536
|
|
12
|
+
monocle_apptrace/haystack/wrap_pipeline.py,sha256=xRYMRzxvFPdcJ64E0bbMdMuWO_p3V1T7eIvb3-Um5DE,1661
|
|
13
|
+
monocle_apptrace/langchain/__init__.py,sha256=HhvRJ_rl9cX4M8ckiOkJC7QHbklrttaY9RvDC51m1l4,268
|
|
14
|
+
monocle_apptrace/llamaindex/__init__.py,sha256=3zmSNoVDjB-hh_M4eUr-hUP0bup7HKmWFVv_3xPAwsA,570
|
|
15
|
+
monocle_apptrace/wrapper_config/haystack_methods.json,sha256=JmngkaKICAzOyrWNTWEOLYFrp99l5wcERYKE_SQRNxE,698
|
|
16
|
+
monocle_apptrace/wrapper_config/lang_chain_methods.json,sha256=HaOhhxb3PkI7tXPxXhWR4cnWrnEHU--k5pOY9RS0Uew,3119
|
|
17
|
+
monocle_apptrace/wrapper_config/llama_index_methods.json,sha256=qpODnBHkaDjPBYZNd7clwmp_2subTu-fmI08Ky5OWdg,2192
|
|
18
|
+
monocle_apptrace-0.1.0.dist-info/METADATA,sha256=sQfm_x1NFthDhfMKX_ZDE0E5bDLSxUOtV1v6yXt0Wpc,5699
|
|
19
|
+
monocle_apptrace-0.1.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
20
|
+
monocle_apptrace-0.1.0.dist-info/licenses/LICENSE,sha256=ay9trLiP5I7ZsFXo6AqtkLYdRqe5S9r-DrPOvsNlZrg,9136
|
|
21
|
+
monocle_apptrace-0.1.0.dist-info/licenses/NOTICE,sha256=9jn4xtwM_uUetJMx5WqGnhrR7MIhpoRlpokjSTlyt8c,112
|
|
22
|
+
monocle_apptrace-0.1.0.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
monocle_apptrace/README.md,sha256=C0JfJtNC7LOlr_iHSxOwuZn89vuoZ2RbyeGB7ACu4iY,3094
|
|
2
|
-
monocle_apptrace/__init__.py,sha256=daEdpEyAJIa8b2VkCqSKcw8PaExcB6Qro80XNes_sHA,2
|
|
3
|
-
monocle_apptrace/instrumentor.py,sha256=T-g0OpR2VYm7lswyiFoBlBeRPKHX6a-mhH8q7rE-o2g,4927
|
|
4
|
-
monocle_apptrace/utils.py,sha256=KZwwXK8NTbVjQo4BkFwPdccE6hzvBzawPp6an44Gmz8,1366
|
|
5
|
-
monocle_apptrace/wrap_common.py,sha256=Qxwq2drHOovd0CMd7YiQbe_4FqGL07RLfu4Vek1Z-SU,9107
|
|
6
|
-
monocle_apptrace/wrapper.py,sha256=95Yg_dwGv5T6qtNv-ozhXRGaDVI0P27exU2901Pw2ps,684
|
|
7
|
-
monocle_apptrace/haystack/__init__.py,sha256=GspHWTmqMDxQhpTgl91xighNL8MHaWs6BF0YzzZayuE,714
|
|
8
|
-
monocle_apptrace/haystack/wrap_node.py,sha256=96qUlDZtNOVIPrrDZzjJ7ZDCi70mYbd7bIEX41e-RH0,916
|
|
9
|
-
monocle_apptrace/haystack/wrap_openai.py,sha256=9ecWsOUXNjTKrQjNZz1GCgkCAN9GChhasMRDmZMuANE,1585
|
|
10
|
-
monocle_apptrace/haystack/wrap_pipeline.py,sha256=eVxJ4-yS4gFxInwaWy5oxNcNl44X2M7_dhBpKVFmI6Q,1622
|
|
11
|
-
monocle_apptrace/langchain/__init__.py,sha256=PrZl6vxX5WsYfsPFVhumVmUGkwddAgPBFs1hpifbmZw,2519
|
|
12
|
-
monocle_apptrace/llamaindex/__init__.py,sha256=iMaboVDeM5yGR01cEqCD8MotCj2FuY4QjSZmFBv4f2o,2094
|
|
13
|
-
monocle_apptrace-0.0.1.dist-info/METADATA,sha256=uYd9O71FeKzrkLq6DmJYp9F62QxxZ7UfSAaGa5dPVm8,5645
|
|
14
|
-
monocle_apptrace-0.0.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
15
|
-
monocle_apptrace-0.0.1.dist-info/licenses/LICENSE,sha256=ay9trLiP5I7ZsFXo6AqtkLYdRqe5S9r-DrPOvsNlZrg,9136
|
|
16
|
-
monocle_apptrace-0.0.1.dist-info/licenses/NOTICE,sha256=9jn4xtwM_uUetJMx5WqGnhrR7MIhpoRlpokjSTlyt8c,112
|
|
17
|
-
monocle_apptrace-0.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|