monocle-apptrace 0.3.0b2__py3-none-any.whl → 0.3.0b3__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 (74) hide show
  1. monocle_apptrace/exporters/aws/s3_exporter.py +1 -1
  2. monocle_apptrace/exporters/aws/s3_exporter_opendal.py +126 -0
  3. monocle_apptrace/exporters/azure/blob_exporter_opendal.py +147 -0
  4. monocle_apptrace/exporters/monocle_exporters.py +38 -20
  5. monocle_apptrace/instrumentation/__init__.py +0 -0
  6. monocle_apptrace/instrumentation/common/__init__.py +0 -0
  7. monocle_apptrace/{constants.py → instrumentation/common/constants.py} +13 -0
  8. monocle_apptrace/instrumentation/common/instrumentor.py +208 -0
  9. monocle_apptrace/instrumentation/common/span_handler.py +154 -0
  10. monocle_apptrace/instrumentation/common/utils.py +171 -0
  11. monocle_apptrace/instrumentation/common/wrapper.py +69 -0
  12. monocle_apptrace/instrumentation/common/wrapper_method.py +45 -0
  13. monocle_apptrace/instrumentation/metamodel/__init__.py +0 -0
  14. monocle_apptrace/instrumentation/metamodel/botocore/__init__.py +0 -0
  15. monocle_apptrace/instrumentation/metamodel/botocore/_helper.py +126 -0
  16. monocle_apptrace/instrumentation/metamodel/botocore/entities/__init__.py +0 -0
  17. monocle_apptrace/instrumentation/metamodel/botocore/entities/inference.py +65 -0
  18. monocle_apptrace/instrumentation/metamodel/botocore/methods.py +16 -0
  19. monocle_apptrace/instrumentation/metamodel/haystack/__init__.py +0 -0
  20. monocle_apptrace/instrumentation/metamodel/haystack/_helper.py +127 -0
  21. monocle_apptrace/instrumentation/metamodel/haystack/entities/__init__.py +0 -0
  22. monocle_apptrace/instrumentation/metamodel/haystack/entities/inference.py +76 -0
  23. monocle_apptrace/instrumentation/metamodel/haystack/entities/retrieval.py +61 -0
  24. monocle_apptrace/instrumentation/metamodel/haystack/methods.py +42 -0
  25. monocle_apptrace/instrumentation/metamodel/langchain/__init__.py +0 -0
  26. monocle_apptrace/instrumentation/metamodel/langchain/_helper.py +121 -0
  27. monocle_apptrace/instrumentation/metamodel/langchain/entities/__init__.py +0 -0
  28. monocle_apptrace/instrumentation/metamodel/langchain/entities/inference.py +71 -0
  29. monocle_apptrace/instrumentation/metamodel/langchain/entities/retrieval.py +58 -0
  30. monocle_apptrace/instrumentation/metamodel/langchain/methods.py +105 -0
  31. monocle_apptrace/instrumentation/metamodel/llamaindex/__init__.py +0 -0
  32. monocle_apptrace/instrumentation/metamodel/llamaindex/_helper.py +154 -0
  33. monocle_apptrace/instrumentation/metamodel/llamaindex/entities/__init__.py +0 -0
  34. monocle_apptrace/instrumentation/metamodel/llamaindex/entities/inference.py +71 -0
  35. monocle_apptrace/instrumentation/metamodel/llamaindex/entities/retrieval.py +57 -0
  36. monocle_apptrace/{metamodel/maps/llamaindex_methods.json → instrumentation/metamodel/llamaindex/methods.py} +28 -31
  37. {monocle_apptrace-0.3.0b2.dist-info → monocle_apptrace-0.3.0b3.dist-info}/METADATA +14 -1
  38. monocle_apptrace-0.3.0b3.dist-info/RECORD +48 -0
  39. monocle_apptrace/botocore/__init__.py +0 -9
  40. monocle_apptrace/haystack/__init__.py +0 -9
  41. monocle_apptrace/haystack/wrap_pipeline.py +0 -63
  42. monocle_apptrace/instrumentor.py +0 -121
  43. monocle_apptrace/langchain/__init__.py +0 -9
  44. monocle_apptrace/llamaindex/__init__.py +0 -16
  45. monocle_apptrace/message_processing.py +0 -80
  46. monocle_apptrace/metamodel/README.md +0 -47
  47. monocle_apptrace/metamodel/entities/README.md +0 -77
  48. monocle_apptrace/metamodel/entities/app_hosting_types.json +0 -29
  49. monocle_apptrace/metamodel/entities/entities.json +0 -49
  50. monocle_apptrace/metamodel/entities/inference_types.json +0 -33
  51. monocle_apptrace/metamodel/entities/model_types.json +0 -41
  52. monocle_apptrace/metamodel/entities/vector_store_types.json +0 -25
  53. monocle_apptrace/metamodel/entities/workflow_types.json +0 -22
  54. monocle_apptrace/metamodel/maps/attributes/inference/botocore_entities.json +0 -27
  55. monocle_apptrace/metamodel/maps/attributes/inference/haystack_entities.json +0 -57
  56. monocle_apptrace/metamodel/maps/attributes/inference/langchain_entities.json +0 -57
  57. monocle_apptrace/metamodel/maps/attributes/inference/llamaindex_entities.json +0 -57
  58. monocle_apptrace/metamodel/maps/attributes/retrieval/haystack_entities.json +0 -31
  59. monocle_apptrace/metamodel/maps/attributes/retrieval/langchain_entities.json +0 -31
  60. monocle_apptrace/metamodel/maps/attributes/retrieval/llamaindex_entities.json +0 -31
  61. monocle_apptrace/metamodel/maps/botocore_methods.json +0 -13
  62. monocle_apptrace/metamodel/maps/haystack_methods.json +0 -45
  63. monocle_apptrace/metamodel/maps/langchain_methods.json +0 -129
  64. monocle_apptrace/metamodel/spans/README.md +0 -121
  65. monocle_apptrace/metamodel/spans/span_example.json +0 -140
  66. monocle_apptrace/metamodel/spans/span_format.json +0 -55
  67. monocle_apptrace/metamodel/spans/span_types.json +0 -16
  68. monocle_apptrace/utils.py +0 -252
  69. monocle_apptrace/wrap_common.py +0 -511
  70. monocle_apptrace/wrapper.py +0 -27
  71. monocle_apptrace-0.3.0b2.dist-info/RECORD +0 -48
  72. {monocle_apptrace-0.3.0b2.dist-info → monocle_apptrace-0.3.0b3.dist-info}/WHEEL +0 -0
  73. {monocle_apptrace-0.3.0b2.dist-info → monocle_apptrace-0.3.0b3.dist-info}/licenses/LICENSE +0 -0
  74. {monocle_apptrace-0.3.0b2.dist-info → monocle_apptrace-0.3.0b3.dist-info}/licenses/NOTICE +0 -0
@@ -1,55 +0,0 @@
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
- }
@@ -1,16 +0,0 @@
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 DELETED
@@ -1,252 +0,0 @@
1
- import logging
2
- import json
3
- from importlib import import_module
4
- import os
5
- from opentelemetry.trace import NonRecordingSpan,Span
6
- from opentelemetry.trace.propagation import _SPAN_KEY
7
- from opentelemetry.context import (attach, detach,get_current)
8
- from opentelemetry.context import attach, set_value, get_value
9
- from monocle_apptrace.constants import service_name_map, service_type_map
10
- from json.decoder import JSONDecodeError
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- embedding_model_context = {}
15
-
16
- def set_span_attribute(span, name, value):
17
- if value is not None:
18
- if value != "":
19
- span.set_attribute(name, value)
20
-
21
- def dont_throw(func):
22
- """
23
- A decorator that wraps the passed in function and logs exceptions instead of throwing them.
24
-
25
- @param func: The function to wrap
26
- @return: The wrapper function
27
- """
28
- # Obtain a logger specific to the function's module
29
- logger = logging.getLogger(func.__module__)
30
-
31
- # pylint: disable=inconsistent-return-statements
32
- def wrapper(*args, **kwargs):
33
- try:
34
- return func(*args, **kwargs)
35
- except Exception as ex:
36
- logger.warning("Failed to execute %s, error: %s", func.__name__, str(ex))
37
-
38
- return wrapper
39
-
40
- def with_tracer_wrapper(func):
41
- """Helper for providing tracer for wrapper functions."""
42
-
43
- def _with_tracer(tracer, to_wrap):
44
- def wrapper(wrapped, instance, args, kwargs):
45
- token = None
46
- try:
47
- _parent_span_context = get_current()
48
- if _parent_span_context is not None and _parent_span_context.get(_SPAN_KEY, None):
49
- parent_span: Span = _parent_span_context.get(_SPAN_KEY, None)
50
- is_invalid_span = isinstance(parent_span, NonRecordingSpan)
51
- if is_invalid_span:
52
- token = attach(context={})
53
- except Exception as e:
54
- logger.error("Exception in attaching parent context: %s", e)
55
-
56
- val = func(tracer, to_wrap, wrapped, instance, args, kwargs)
57
- # Detach the token if it was set
58
- if token:
59
- try:
60
- detach(token=token)
61
- except Exception as e:
62
- logger.error("Exception in detaching parent context: %s", e)
63
- return val
64
- return wrapper
65
-
66
- return _with_tracer
67
-
68
- def resolve_from_alias(my_map, alias):
69
- """Find a alias that is not none from list of aliases"""
70
-
71
- for i in alias:
72
- if i in my_map.keys():
73
- return my_map[i]
74
- return None
75
-
76
- def load_output_processor(wrapper_method, attributes_config_base_path):
77
- """Load the output processor from a file if the file path is provided and valid."""
78
- logger = logging.getLogger()
79
- output_processor_file_path = wrapper_method["output_processor"][0]
80
- logger.info(f'Output processor file path is: {output_processor_file_path}')
81
-
82
- if isinstance(output_processor_file_path, str) and output_processor_file_path: # Combined condition
83
- if not attributes_config_base_path:
84
- absolute_file_path = os.path.abspath(output_processor_file_path)
85
- else:
86
- absolute_file_path = os.path.join(attributes_config_base_path, output_processor_file_path)
87
-
88
- logger.info(f'Absolute file path is: {absolute_file_path}')
89
- try:
90
- with open(absolute_file_path, encoding='UTF-8') as op_file:
91
- wrapper_method["output_processor"] = json.load(op_file)
92
- logger.info('Output processor loaded successfully.')
93
- except FileNotFoundError:
94
- logger.error(f"Error: File not found at {absolute_file_path}.")
95
- except JSONDecodeError:
96
- logger.error(f"Error: Invalid JSON content in the file {absolute_file_path}.")
97
- except Exception as e:
98
- logger.error(f"Error: An unexpected error occurred: {e}")
99
- else:
100
- logger.error("Invalid or missing output processor file path.")
101
-
102
- def get_wrapper_methods_config(
103
- wrapper_methods_config_path: str,
104
- attributes_config_base_path: str = None
105
- ):
106
- parent_dir = os.path.dirname(os.path.join(os.path.dirname(__file__), '..'))
107
- wrapper_methods_config = load_wrapper_methods_config_from_file(
108
- wrapper_methods_config_path=os.path.join(parent_dir, wrapper_methods_config_path))
109
- process_wrapper_method_config(
110
- wrapper_methods_config=wrapper_methods_config,
111
- attributes_config_base_path=attributes_config_base_path)
112
- return wrapper_methods_config
113
-
114
- def load_wrapper_methods_config_from_file(
115
- wrapper_methods_config_path: str):
116
- json_data = {}
117
-
118
- with open(wrapper_methods_config_path, encoding='UTF-8') as config_file:
119
- json_data = json.load(config_file)
120
-
121
- return json_data["wrapper_methods"]
122
-
123
- def process_wrapper_method_config(
124
- wrapper_methods_config: str,
125
- attributes_config_base_path: str = ""):
126
- for wrapper_method in wrapper_methods_config:
127
- if "wrapper_package" in wrapper_method and "wrapper_method" in wrapper_method:
128
- wrapper_method["wrapper"] = get_wrapper_method(
129
- wrapper_method["wrapper_package"], wrapper_method["wrapper_method"])
130
- if "span_name_getter_method" in wrapper_method:
131
- wrapper_method["span_name_getter"] = get_wrapper_method(
132
- wrapper_method["span_name_getter_package"],
133
- wrapper_method["span_name_getter_method"])
134
- if "output_processor" in wrapper_method and wrapper_method["output_processor"]:
135
- load_output_processor(wrapper_method, attributes_config_base_path)
136
-
137
- def get_wrapper_method(package_name: str, method_name: str):
138
- wrapper_module = import_module("monocle_apptrace." + package_name)
139
- return getattr(wrapper_module, method_name)
140
-
141
- def set_app_hosting_identifier_attribute(span, span_index):
142
- return_value = 0
143
- # Search env to indentify the infra service type, if found check env for service name if possible
144
- for type_env, type_name in service_type_map.items():
145
- if type_env in os.environ:
146
- return_value = 1
147
- span.set_attribute(f"entity.{span_index}.type", f"app_hosting.{type_name}")
148
- entity_name_env = service_name_map.get(type_name, "unknown")
149
- span.set_attribute(f"entity.{span_index}.name", os.environ.get(entity_name_env, "generic"))
150
- return return_value
151
-
152
- def set_embedding_model(model_name: str):
153
- """
154
- Sets the embedding model in the global context.
155
-
156
- @param model_name: The name of the embedding model to set
157
- """
158
- embedding_model_context['embedding_model'] = model_name
159
-
160
- def get_embedding_model() -> str:
161
- """
162
- Retrieves the embedding model from the global context.
163
-
164
- @return: The name of the embedding model, or 'unknown' if not set
165
- """
166
- return embedding_model_context.get('embedding_model', 'unknown')
167
-
168
- def set_attribute(key: str, value: str):
169
- """
170
- Set a value in the global context for a given key.
171
-
172
- Args:
173
- key: The key for the context value to set.
174
- value: The value to set for the given key.
175
- """
176
- attach(set_value(key, value))
177
-
178
- def get_attribute(key: str) -> str:
179
- """
180
- Retrieve a value from the global context for a given key.
181
-
182
- Args:
183
- key: The key for the context value to retrieve.
184
-
185
- Returns:
186
- The value associated with the given key.
187
- """
188
- return get_value(key)
189
-
190
- def flatten_dict(d, parent_key='', sep='_'):
191
- items = []
192
- for k, v in d.items():
193
- new_key = f"{parent_key}{sep}{k}" if parent_key else k
194
- if isinstance(v, dict):
195
- items.extend(flatten_dict(v, new_key, sep=sep).items())
196
- else:
197
- items.append((new_key, v))
198
- return dict(items)
199
-
200
- def get_fully_qualified_class_name(instance):
201
- if instance is None:
202
- return None
203
- module_name = instance.__class__.__module__
204
- qualname = instance.__class__.__qualname__
205
- return f"{module_name}.{qualname}"
206
-
207
- # returns json path like key probe in a dictionary
208
- def get_nested_value(data, keys):
209
- for key in keys:
210
- if isinstance(data, dict) and key in data:
211
- data = data[key]
212
- elif hasattr(data, key):
213
- data = getattr(data, key)
214
- else:
215
- return None
216
- return data
217
-
218
- def get_workflow_name(span: Span) -> str:
219
- try:
220
- return get_value("workflow_name") or span.resource.attributes.get("service.name")
221
- except Exception as e:
222
- logger.exception(f"Error getting workflow name: {e}")
223
- return None
224
-
225
- def get_vectorstore_deployment(my_map):
226
- if isinstance(my_map, dict):
227
- if '_client_settings' in my_map:
228
- client = my_map['_client_settings'].__dict__
229
- host, port = get_keys_as_tuple(client, 'host', 'port')
230
- if host:
231
- return f"{host}:{port}" if port else host
232
- keys_to_check = ['client', '_client']
233
- host = get_host_from_map(my_map, keys_to_check)
234
- if host:
235
- return host
236
- else:
237
- if hasattr(my_map, 'client') and '_endpoint' in my_map.client.__dict__:
238
- return my_map.client.__dict__['_endpoint']
239
- host, port = get_keys_as_tuple(my_map.__dict__, 'host', 'port')
240
- if host:
241
- return f"{host}:{port}" if port else host
242
- return None
243
-
244
- def get_keys_as_tuple(dictionary, *keys):
245
- return tuple(next((value for key, value in dictionary.items() if key.endswith(k) and value is not None), None) for k in keys)
246
-
247
- def get_host_from_map(my_map, keys_to_check):
248
- for key in keys_to_check:
249
- seed_connections = get_nested_value(my_map, [key, 'transport', 'seed_connections'])
250
- if seed_connections and 'host' in seed_connections[0].__dict__:
251
- return seed_connections[0].__dict__['host']
252
- return None