monocle-apptrace 0.1.0__py3-none-any.whl → 0.2.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.

Files changed (41) hide show
  1. monocle_apptrace/README.md +50 -26
  2. monocle_apptrace/exporters/aws/s3_exporter.py +158 -0
  3. monocle_apptrace/exporters/azure/blob_exporter.py +128 -0
  4. monocle_apptrace/exporters/base_exporter.py +47 -0
  5. monocle_apptrace/exporters/exporter_processor.py +19 -0
  6. monocle_apptrace/exporters/monocle_exporters.py +27 -0
  7. monocle_apptrace/exporters/okahu/okahu_exporter.py +115 -0
  8. monocle_apptrace/haystack/__init__.py +4 -4
  9. monocle_apptrace/haystack/wrap_pipeline.py +18 -1
  10. monocle_apptrace/instrumentor.py +15 -18
  11. monocle_apptrace/langchain/__init__.py +6 -3
  12. monocle_apptrace/llamaindex/__init__.py +8 -7
  13. monocle_apptrace/metamodel/README.md +47 -0
  14. monocle_apptrace/metamodel/entities/README.md +77 -0
  15. monocle_apptrace/metamodel/entities/app_hosting_types.json +29 -0
  16. monocle_apptrace/metamodel/entities/entities.json +49 -0
  17. monocle_apptrace/metamodel/entities/inference_types.json +33 -0
  18. monocle_apptrace/metamodel/entities/model_types.json +41 -0
  19. monocle_apptrace/metamodel/entities/vector_store_types.json +25 -0
  20. monocle_apptrace/metamodel/entities/workflow_types.json +22 -0
  21. monocle_apptrace/metamodel/maps/attributes/inference/langchain_entities.json +35 -0
  22. monocle_apptrace/metamodel/maps/attributes/inference/llamaindex_entities.json +35 -0
  23. monocle_apptrace/metamodel/maps/attributes/retrieval/langchain_entities.json +27 -0
  24. monocle_apptrace/metamodel/maps/attributes/retrieval/llamaindex_entities.json +27 -0
  25. monocle_apptrace/{wrapper_config/lang_chain_methods.json → metamodel/maps/langchain_methods.json} +31 -8
  26. monocle_apptrace/{wrapper_config/llama_index_methods.json → metamodel/maps/llamaindex_methods.json} +12 -8
  27. monocle_apptrace/metamodel/spans/README.md +121 -0
  28. monocle_apptrace/metamodel/spans/span_example.json +140 -0
  29. monocle_apptrace/metamodel/spans/span_format.json +55 -0
  30. monocle_apptrace/metamodel/spans/span_types.json +16 -0
  31. monocle_apptrace/utils.py +108 -9
  32. monocle_apptrace/wrap_common.py +247 -98
  33. monocle_apptrace/wrapper.py +3 -1
  34. monocle_apptrace-0.2.0.dist-info/METADATA +115 -0
  35. monocle_apptrace-0.2.0.dist-info/RECORD +44 -0
  36. monocle_apptrace-0.1.0.dist-info/METADATA +0 -77
  37. monocle_apptrace-0.1.0.dist-info/RECORD +0 -22
  38. /monocle_apptrace/{wrapper_config → metamodel/maps}/haystack_methods.json +0 -0
  39. {monocle_apptrace-0.1.0.dist-info → monocle_apptrace-0.2.0.dist-info}/WHEEL +0 -0
  40. {monocle_apptrace-0.1.0.dist-info → monocle_apptrace-0.2.0.dist-info}/licenses/LICENSE +0 -0
  41. {monocle_apptrace-0.1.0.dist-info → monocle_apptrace-0.2.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,4 +1,4 @@
1
- {
1
+ {
2
2
  "wrapper_methods" : [
3
3
  {
4
4
  "package": "langchain.prompts.base",
@@ -19,42 +19,65 @@
19
19
  "object": "BaseChatModel",
20
20
  "method": "invoke",
21
21
  "wrapper_package": "wrap_common",
22
- "wrapper_method": "llm_wrapper"
22
+ "wrapper_method": "llm_wrapper",
23
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
23
24
  },
24
25
  {
25
26
  "package": "langchain.chat_models.base",
26
27
  "object": "BaseChatModel",
27
28
  "method": "ainvoke",
28
29
  "wrapper_package": "wrap_common",
29
- "wrapper_method": "allm_wrapper"
30
+ "wrapper_method": "allm_wrapper",
31
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
30
32
  },
31
33
  {
32
34
  "package": "langchain_core.language_models.llms",
33
35
  "object": "LLM",
34
36
  "method": "_generate",
35
37
  "wrapper_package": "wrap_common",
36
- "wrapper_method": "llm_wrapper"
38
+ "wrapper_method": "llm_wrapper",
39
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
37
40
  },
38
41
  {
39
42
  "package": "langchain_core.language_models.llms",
40
43
  "object": "LLM",
41
44
  "method": "_agenerate",
42
45
  "wrapper_package": "wrap_common",
43
- "wrapper_method": "llm_wrapper"
46
+ "wrapper_method": "allm_wrapper",
47
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
48
+ },
49
+ {
50
+ "package": "langchain_core.language_models.llms",
51
+ "object": "BaseLLM",
52
+ "method": "invoke",
53
+ "wrapper_package": "wrap_common",
54
+ "wrapper_method": "llm_wrapper",
55
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
56
+ },
57
+ {
58
+ "package": "langchain_core.language_models.llms",
59
+ "object": "BaseLLM",
60
+ "method": "ainvoke",
61
+ "wrapper_package": "wrap_common",
62
+ "wrapper_method": "allm_wrapper",
63
+ "output_processor": ["metamodel/maps/attributes/inference/langchain_entities.json"]
44
64
  },
45
65
  {
46
66
  "package": "langchain_core.retrievers",
47
67
  "object": "BaseRetriever",
48
68
  "method": "invoke",
49
69
  "wrapper_package": "wrap_common",
50
- "wrapper_method": "task_wrapper"
70
+ "wrapper_method": "task_wrapper",
71
+ "output_processor": ["metamodel/maps/attributes/retrieval/langchain_entities.json"]
72
+
51
73
  },
52
74
  {
53
75
  "package": "langchain_core.retrievers",
54
76
  "object": "BaseRetriever",
55
77
  "method": "ainvoke",
56
78
  "wrapper_package": "wrap_common",
57
- "wrapper_method": "atask_wrapper"
79
+ "wrapper_method": "atask_wrapper",
80
+ "output_processor": ["metamodel/maps/attributes/retrieval/langchain_entities.json"]
58
81
  },
59
82
  {
60
83
  "package": "langchain.schema",
@@ -103,4 +126,4 @@
103
126
  "wrapper_method": "atask_wrapper"
104
127
  }
105
128
  ]
106
- }
129
+ }
@@ -6,7 +6,8 @@
6
6
  "method": "retrieve",
7
7
  "span_name": "llamaindex.retrieve",
8
8
  "wrapper_package": "wrap_common",
9
- "wrapper_method": "task_wrapper"
9
+ "wrapper_method": "task_wrapper",
10
+ "output_processor": ["metamodel/maps/attributes/retrieval/llamaindex_entities.json"]
10
11
  },
11
12
  {
12
13
  "package": "llama_index.core.indices.base_retriever",
@@ -14,7 +15,8 @@
14
15
  "method": "aretrieve",
15
16
  "span_name": "llamaindex.retrieve",
16
17
  "wrapper_package": "wrap_common",
17
- "wrapper_method": "atask_wrapper"
18
+ "wrapper_method": "atask_wrapper",
19
+ "output_processor": ["metamodel/maps/attributes/retrieval/llamaindex_entities.json"]
18
20
  },
19
21
  {
20
22
  "package": "llama_index.core.base.base_query_engine",
@@ -38,7 +40,8 @@
38
40
  "method": "chat",
39
41
  "span_name": "llamaindex.llmchat",
40
42
  "wrapper_package": "wrap_common",
41
- "wrapper_method": "task_wrapper"
43
+ "wrapper_method": "task_wrapper",
44
+ "output_processor": ["metamodel/maps/attributes/inference/llamaindex_entities.json"]
42
45
  },
43
46
  {
44
47
  "package": "llama_index.core.llms.custom",
@@ -46,7 +49,8 @@
46
49
  "method": "achat",
47
50
  "span_name": "llamaindex.llmchat",
48
51
  "wrapper_package": "wrap_common",
49
- "wrapper_method": "atask_wrapper"
52
+ "wrapper_method": "atask_wrapper",
53
+ "output_processor": ["metamodel/maps/attributes/inference/llamaindex_entities.json"]
50
54
  },
51
55
  {
52
56
  "package": "llama_index.llms.openai.base",
@@ -55,8 +59,7 @@
55
59
  "span_name": "llamaindex.openai",
56
60
  "wrapper_package": "wrap_common",
57
61
  "wrapper_method": "llm_wrapper",
58
- "span_name_getter_package" : "llamaindex",
59
- "span_name_getter_mothod" : "get_llm_span_name_for_openai"
62
+ "output_processor": ["metamodel/maps/attributes/inference/llamaindex_entities.json"]
60
63
  },
61
64
  {
62
65
  "package": "llama_index.llms.openai.base",
@@ -64,7 +67,8 @@
64
67
  "method": "achat",
65
68
  "span_name": "llamaindex.openai",
66
69
  "wrapper_package": "wrap_common",
67
- "wrapper_method": "allm_wrapper"
70
+ "wrapper_method": "allm_wrapper",
71
+ "output_processor": ["metamodel/maps/attributes/inference/llamaindex_entities.json"]
68
72
  }
69
73
  ]
70
- }
74
+ }
@@ -0,0 +1,121 @@
1
+ # Monocle Span format
2
+ Monocle generates [traces](../../../../Monocle_User_Guide.md#traces) which comprises of [spans](../../../../Monocle_User_Guide.md#spans). Note that Monocle trace is [OpenTelemetry format](https://opentelemetry.io/docs/concepts/signals/traces/) compatible. Each span is essentially a step in the execution that interacts with one of more GenAI technology components. This document explains the [span format](./span_format.json) that Monocle generates for GenAI application tracing.
3
+
4
+ Per the OpenTelemetry convention, each span contains an attribute section and event section. In Monocle generated trace, the attribute sections includes details of GenAI entities used in the span. The event section includes the input, output and metadata related to the execution of that span.
5
+
6
+ ## Attributes
7
+ The attribute sections includes details of GenAI entities used in the span. For each entity used in the span in includes the entity name and entity type. For every type of entity, there are required and optional attributes listed below.
8
+ ### Json format
9
+ ```json
10
+ attributes:
11
+ "span.type": "Monocle-span-type",
12
+ "entity.count": "count-of-entities",
13
+
14
+ "entity.<index>.name": "Monocle-Entity-name",
15
+ "entity.<index>.type": "MonocleEntity.<entity-type>"
16
+ ...
17
+ ```
18
+ The ```entity.count``` indicates total number of entities used in the given span. For each entity, the details are captured in ```entity.<index>.X```. For example,
19
+ ```json
20
+ "attributes": {
21
+ "span.type": "Inference",
22
+ "entity.count": 2,
23
+ "entity.1.name": "AzureOpenAI",
24
+ "entity.1.type": "Inference.Azure_oai",
25
+ "entity.2.name": "gpt-35-turbo",
26
+ "entity.2.type": "Model.LLM",
27
+ "entity.2.model_name": "gpt-35-turbo",
28
+ ```
29
+
30
+ ### Entity type specific attributes
31
+ #### MonocleEntity.Workflow
32
+ | Name | Description | Values | Required |
33
+ | - | - | - | - |
34
+ | name | Entity name generated by Monocle | Name String | Required |
35
+ | type | Monocle Entity type | MonocleEntity.Workflow | Required |
36
+ | optional-attribute | Additional attribute specific to entity | | Optional |
37
+
38
+ ### MonocleEntity.Model
39
+ | Name | Description | Values | Required |
40
+ | - | - | - | - |
41
+ | name | Entity name generated by Monocle | Name String | Required |
42
+ | type | Monocle Entity type | MonocleEntity.Model | Required |
43
+ | model_name | Name of model | String | Required |
44
+ | optional-attribute | Additional attribute specific to entity | | Optional |
45
+
46
+ ### MonocleEntity.AppHosting
47
+ | Name | Description | Values | Required |
48
+ | - | - | - | - |
49
+ | name | Entity name generated by Monocle | Name String | Required |
50
+ | type | Monocle Entity type | MonocleEntity.AppHosting | Required |
51
+ | optional-attribute | Additional attribute specific to entity | | Optional |
52
+
53
+ ### MonocleEntity.Inference
54
+ | Name | Description | Values | Required |
55
+ | - | - | - | - |
56
+ | name | Entity name generated by Monocle | Name String | Required |
57
+ | type | Monocle Entity type | MonocleEntity.Inference | Required |
58
+ | optional-attribute | Additional attribute specific to entity | | Optional |
59
+
60
+ ### MonocleEntity.VectorDB
61
+ | Name | Description | Values | Required |
62
+ | - | - | - | - |
63
+ | name | Entity name generated by Monocle | Name String | Required |
64
+ | type | Monocle Entity type | MonocleEntity.VectorDB | Required |
65
+ | optional-attribute | Additional attribute specific to entity | | Optional |
66
+
67
+ ## Events
68
+ The event section includes the input, output and metadata generated by that span execution. For each type of span, there are required and option input, output and metadata items listed below. If there's no data genearated in the space, the events will be an empty array.
69
+
70
+ ### Json format
71
+ ```json
72
+ "events" : [
73
+ {
74
+ "name": "data.input",
75
+ "timestamp": "UTC timestamp",
76
+ "attributes": {
77
+ "input_attribute": "value"
78
+ }
79
+ },
80
+ {
81
+ "name": "data.output",
82
+ "timestamp": "UTC timestamp",
83
+ "attributes": {
84
+ "output_attribute": "value"
85
+ }
86
+ },
87
+ {
88
+ "name": "metadata",
89
+ "timestamp": "UTC timestamp",
90
+ "attributes": {
91
+ "metadata_attribute": "value"
92
+ }
93
+ }
94
+ ]
95
+ ```
96
+
97
+ ## Span types and events
98
+ The ```span.type``` captured in ```attributes``` section of the span dectates the format of the ```events```
99
+ ### SpanType.Retrieval
100
+ | Name | Description | Values | Required |
101
+ | - | - | - | - |
102
+ | name | event name | data.input or data.output or metadata | Required |
103
+ | timestamp | timestap when the event occurred | UTC timestamp | Required |
104
+ | attributes | input/output/metadata attributes generated in span | Dictionary | Required |
105
+
106
+ ### SpanType.Inference
107
+ | Name | Description | Values | Required |
108
+ | - | - | - | - |
109
+ | name | event name | data.input or data.output or metadata | Required |
110
+ | timestamp | timestap when the event occurred | UTC timestamp | Required |
111
+ | attributes | input/output/metadata attributes generated in span | Dictionary | Required |
112
+
113
+ ### SpanType.Workflow
114
+ | Name | Description | Values | Required |
115
+ | - | - | - | - |
116
+ | name | event name | data.input or data.output or metadata | Required |
117
+ | timestamp | timestap when the event occurred | UTC timestamp | Required |
118
+ | attributes | input/output/metadata attributes generated in span | Dictionary | Required |
119
+
120
+ ### SpanType.Internal
121
+ Events will be empty
@@ -0,0 +1,140 @@
1
+ {
2
+ "name": "llamaindex.retrieve",
3
+ "context": {
4
+ "trace_id": "0x93cd0bf865b3ffcc3cf9c075dc3e3797",
5
+ "span_id": "0x5d3f839e900bda24",
6
+ "trace_state": "[]"
7
+ },
8
+ "kind": "SpanKind.CLIENT",
9
+ "parent_id": "0x7a63d63e42ccac60",
10
+ "start_time": "2024-09-09T14:38:45.237182Z",
11
+ "end_time": "2024-09-09T14:38:45.620112Z",
12
+ "status": {
13
+ "status_code": "OK"
14
+ },
15
+ "attributes": {
16
+ "span.type": "retrieval",
17
+ "entity.count": 2,
18
+ "entity.1.name": "ChromaVectorStore",
19
+ "entity.1.type": "vectorstore.chroma",
20
+ "entity.1.embedding-model-name": "BAAI/bge-small-en-v1.5",
21
+ "entity.2.name": "BAAI/bge-small-en-v1.5",
22
+ "entity.2.type": "model.embedding",
23
+ "entity.2.model_name": "BAAI/bge-small-en-v1.5"
24
+ },
25
+ "events": [
26
+ {
27
+ "name": "data.input",
28
+ "timestamp": "timestamp",
29
+ "attributes": {
30
+ "context_input": "question: What is an americano?"
31
+ }
32
+ },
33
+ {
34
+ "name": "data.output",
35
+ "timestamp": "timestamp",
36
+ "attributes": {
37
+ "context_output": "Coffee is a hot drink made from the roasted and ground seeds (coffee beans) of a tropical shrub\nA latte consists of one or more shots of espresso, served in a glass (or sometimes a cup), into which hot steamed milk is added\nAmericano is a type of coffee drink prepared by diluting an espresso shot with hot water at a 1:3 to 1:4 ratio, resulting in a drink that retains the complex flavors of espresso, but in a lighter way"
38
+ }
39
+ }
40
+
41
+ ],
42
+ "links": [],
43
+ "resource": {
44
+ "attributes": {
45
+ "service.name": "coffee-bot"
46
+ },
47
+ "schema_url": ""
48
+ }
49
+ },
50
+ {
51
+ "name": "llamaindex.openai",
52
+ "context": {
53
+ "trace_id": "0x93cd0bf865b3ffcc3cf9c075dc3e3797",
54
+ "span_id": "0x8b6363e1937a4d7b",
55
+ "trace_state": "[]"
56
+ },
57
+ "kind": "SpanKind.CLIENT",
58
+ "parent_id": "0x7a63d63e42ccac60",
59
+ "start_time": "2024-09-09T14:38:45.622174Z",
60
+ "end_time": "2024-09-09T14:38:46.514120Z",
61
+ "status": {
62
+ "status_code": "OK"
63
+ },
64
+ "attributes": {
65
+ "span.type": "inference",
66
+ "entity.count": 2,
67
+ "entity.1.name": "AzureOpenAI",
68
+ "entity.1.type": "inference.azure_oai",
69
+ "entity.1.provider_name": "openai.azure.com",
70
+ "entity.1.deployment": "kshitiz-gpt",
71
+ "entity.1.inference_endpoint": "https://okahu-openai-dev.openai.azure.com/",
72
+
73
+ "entity.2.name": "gpt-35-turbo",
74
+ "entity.2.type": "model.llm",
75
+ "entity.2.model_name": "gpt-35-turbo"
76
+ },
77
+ "events": [
78
+ {
79
+ "name": "data.input",
80
+ "timestamp": "timestamp",
81
+ "attributes": {
82
+ "question": "What is an americano?",
83
+ }
84
+ },
85
+ {
86
+ "name": "data.output",
87
+ "timestamp": "timestamp",
88
+ "attributes": {
89
+ "response": "An americano is a type of coffee drink that is made by diluting an espresso shot with hot water at a 1:3 to 1:4 ratio, resulting in a drink that retains the complex flavors of espresso, but in a lighter way.",
90
+ }
91
+ },
92
+ {
93
+ "name": "metadata",
94
+ "timestamp": "timestamp",
95
+ "attributes": {
96
+ "temperature": 0.1,
97
+ "completion_tokens": 52,
98
+ "prompt_tokens": 233,
99
+ "total_tokens": 285
100
+ }
101
+ }
102
+ ],
103
+ "links": [],
104
+ "resource": {
105
+ "attributes": {
106
+ "service.name": "coffee-bot"
107
+ },
108
+ "schema_url": ""
109
+ }
110
+ }
111
+ {
112
+ "name": "llamaindex.query",
113
+ "context": {
114
+ "trace_id": "0x93cd0bf865b3ffcc3cf9c075dc3e3797",
115
+ "span_id": "0x7a63d63e42ccac60",
116
+ "trace_state": "[]"
117
+ },
118
+ "kind": "SpanKind.CLIENT",
119
+ "parent_id": null,
120
+ "start_time": "2024-09-09T14:38:45.236627Z",
121
+ "end_time": "2024-09-09T14:38:46.514442Z",
122
+ "status": {
123
+ "status_code": "OK"
124
+ },
125
+ "attributes": {
126
+ "span.type": "workflow",
127
+ "entity.count": 1,
128
+ "entity.1.name": "coffee-bot",
129
+ "entity.1.type": "workflow.llama_index"
130
+ },
131
+ "events": [
132
+ ],
133
+ "links": [],
134
+ "resource": {
135
+ "attributes": {
136
+ "service.name": "coffee-bot"
137
+ },
138
+ "schema_url": ""
139
+ }
140
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "span-name",
3
+ "context": {
4
+ "trace_id": "trace-id",
5
+ "span_id": "span-id",
6
+ "trace_state": "[]"
7
+ },
8
+ "kind": "SpanKind.CLIENT",
9
+ "parent_id": "parent-id or None (for root span)",
10
+ "start_time": "UTC timestamp",
11
+ "end_time": "UTC timestamp",
12
+ "status": {
13
+ "status_code": "OK or Error"
14
+ },
15
+ "attributes": {
16
+ "description": "List of AI component entities used in this span, eg Model, Inference hosting service. Needs to be one of the supported entity types.",
17
+
18
+ "span.type": "Monocle-span-type",
19
+ "entity.count": "count-of-entities",
20
+
21
+ "entity.<index>.name": "Monocle-Entity-name",
22
+ "entity.<index>.type": "Monocle-Entity-Type",
23
+ "entity.<index>.<attribute>": "Value"
24
+ },
25
+ "events" : [
26
+ {
27
+ "name": "data.input",
28
+ "timestamp": "UTC timestamp",
29
+ "attributes": {
30
+ "input_attribute": "value"
31
+ }
32
+ },
33
+ {
34
+ "name": "data.output",
35
+ "timestamp": "UTC timestamp",
36
+ "attributes": {
37
+ "output_attribute": "value"
38
+ }
39
+ },
40
+ {
41
+ "name": "metadata",
42
+ "timestamp": "UTC timestamp",
43
+ "attributes": {
44
+ "metadata_attribute": "value"
45
+ }
46
+ }
47
+ ],
48
+ "links": [],
49
+ "resource": {
50
+ "attributes": {
51
+ "service.name": "top-workflow-name"
52
+ },
53
+ "schema_url": ""
54
+ }
55
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "span_types" : [
3
+ {
4
+ "type": "inference",
5
+ "description": "Model inference span"
6
+ },
7
+ {
8
+ "type": "retrieval",
9
+ "description": "vector embedding retrieval"
10
+ },
11
+ {
12
+ "type": "workflow",
13
+ "description": "workflow orchetraction at top level"
14
+ }
15
+ ]
16
+ }
monocle_apptrace/utils.py CHANGED
@@ -3,7 +3,12 @@ import json
3
3
  from importlib import import_module
4
4
  import os
5
5
  from opentelemetry.trace import Span
6
+ from opentelemetry.context import attach, set_value, get_value
6
7
  from monocle_apptrace.constants import azure_service_map, aws_service_map
8
+ from json.decoder import JSONDecodeError
9
+ logger = logging.getLogger(__name__)
10
+
11
+ embedding_model_context = {}
7
12
 
8
13
  def set_span_attribute(span, name, value):
9
14
  if value is not None:
@@ -19,12 +24,14 @@ def dont_throw(func):
19
24
  """
20
25
  # Obtain a logger specific to the function's module
21
26
  logger = logging.getLogger(func.__module__)
27
+
22
28
  # pylint: disable=inconsistent-return-statements
23
29
  def wrapper(*args, **kwargs):
24
30
  try:
25
31
  return func(*args, **kwargs)
26
32
  except Exception as ex:
27
33
  logger.warning("Failed to execute %s, error: %s", func.__name__, str(ex))
34
+
28
35
  return wrapper
29
36
 
30
37
  def with_tracer_wrapper(func):
@@ -46,28 +53,120 @@ def resolve_from_alias(my_map, alias):
46
53
  return my_map[i]
47
54
  return None
48
55
 
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:
56
+ def load_output_processor(wrapper_method, attributes_config_base_path):
57
+ """Load the output processor from a file if the file path is provided and valid."""
58
+ logger = logging.getLogger()
59
+ output_processor_file_path = wrapper_method["output_processor"][0]
60
+ logger.info(f'Output processor file path is: {output_processor_file_path}')
61
+
62
+ if isinstance(output_processor_file_path, str) and output_processor_file_path: # Combined condition
63
+ if not attributes_config_base_path:
64
+ absolute_file_path = os.path.abspath(output_processor_file_path)
65
+ else:
66
+ absolute_file_path = os.path.join(attributes_config_base_path, output_processor_file_path)
67
+
68
+ logger.info(f'Absolute file path is: {absolute_file_path}')
69
+ try:
70
+ with open(absolute_file_path, encoding='UTF-8') as op_file:
71
+ wrapper_method["output_processor"] = json.load(op_file)
72
+ logger.info('Output processor loaded successfully.')
73
+ except FileNotFoundError:
74
+ logger.error(f"Error: File not found at {absolute_file_path}.")
75
+ except JSONDecodeError:
76
+ logger.error(f"Error: Invalid JSON content in the file {absolute_file_path}.")
77
+ except Exception as e:
78
+ logger.error(f"Error: An unexpected error occurred: {e}")
79
+ else:
80
+ logger.error("Invalid or missing output processor file path.")
81
+
82
+ def get_wrapper_methods_config(
83
+ wrapper_methods_config_path: str,
84
+ attributes_config_base_path: str = None
85
+ ):
86
+ parent_dir = os.path.dirname(os.path.join(os.path.dirname(__file__), '..'))
87
+ wrapper_methods_config = load_wrapper_methods_config_from_file(
88
+ wrapper_methods_config_path=os.path.join(parent_dir, wrapper_methods_config_path))
89
+ process_wrapper_method_config(
90
+ wrapper_methods_config=wrapper_methods_config,
91
+ attributes_config_base_path=attributes_config_base_path)
92
+ return wrapper_methods_config
93
+
94
+ def load_wrapper_methods_config_from_file(
95
+ wrapper_methods_config_path: str):
96
+ json_data = {}
97
+
98
+ with open(wrapper_methods_config_path, encoding='UTF-8') as config_file:
52
99
  json_data = json.load(config_file)
53
- wrapper_methods = json_data["wrapper_methods"]
54
- for wrapper_method in wrapper_methods:
100
+
101
+ return json_data["wrapper_methods"]
102
+
103
+ def process_wrapper_method_config(
104
+ wrapper_methods_config: str,
105
+ attributes_config_base_path: str = ""):
106
+ for wrapper_method in wrapper_methods_config:
107
+ if "wrapper_package" in wrapper_method and "wrapper_method" in wrapper_method:
55
108
  wrapper_method["wrapper"] = get_wrapper_method(
56
109
  wrapper_method["wrapper_package"], wrapper_method["wrapper_method"])
57
- if "span_name_getter_method" in wrapper_method :
110
+ if "span_name_getter_method" in wrapper_method:
58
111
  wrapper_method["span_name_getter"] = get_wrapper_method(
59
112
  wrapper_method["span_name_getter_package"],
60
113
  wrapper_method["span_name_getter_method"])
61
- return wrapper_methods
114
+ if "output_processor" in wrapper_method and wrapper_method["output_processor"]:
115
+ load_output_processor(wrapper_method, attributes_config_base_path)
62
116
 
63
117
  def get_wrapper_method(package_name: str, method_name: str):
64
118
  wrapper_module = import_module("monocle_apptrace." + package_name)
65
119
  return getattr(wrapper_module, method_name)
66
120
 
67
121
  def update_span_with_infra_name(span: Span, span_key: str):
68
- for key,val in azure_service_map.items():
122
+ for key, val in azure_service_map.items():
69
123
  if key in os.environ:
70
124
  span.set_attribute(span_key, val)
71
- for key,val in aws_service_map.items():
125
+ for key, val in aws_service_map.items():
72
126
  if key in os.environ:
73
127
  span.set_attribute(span_key, val)
128
+
129
+ def set_embedding_model(model_name: str):
130
+ """
131
+ Sets the embedding model in the global context.
132
+
133
+ @param model_name: The name of the embedding model to set
134
+ """
135
+ embedding_model_context['embedding_model'] = model_name
136
+
137
+ def get_embedding_model() -> str:
138
+ """
139
+ Retrieves the embedding model from the global context.
140
+
141
+ @return: The name of the embedding model, or 'unknown' if not set
142
+ """
143
+ return embedding_model_context.get('embedding_model', 'unknown')
144
+
145
+ def set_attribute(key: str, value: str):
146
+ """
147
+ Set a value in the global context for a given key.
148
+
149
+ Args:
150
+ key: The key for the context value to set.
151
+ value: The value to set for the given key.
152
+ """
153
+ attach(set_value(key, value))
154
+
155
+ def get_attribute(key: str) -> str:
156
+ """
157
+ Retrieve a value from the global context for a given key.
158
+
159
+ Args:
160
+ key: The key for the context value to retrieve.
161
+
162
+ Returns:
163
+ The value associated with the given key.
164
+ """
165
+ return get_value(key)
166
+
167
+ def get_workflow_name(span: Span) -> str:
168
+ try:
169
+ return get_value("workflow_name") or span.resource.attributes.get("service.name")
170
+ except Exception as e:
171
+ logger.exception(f"Error getting workflow name: {e}")
172
+ return None