monocle-apptrace 0.4.2__py3-none-any.whl → 0.5.0b1__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 (72) hide show
  1. monocle_apptrace/__main__.py +1 -1
  2. monocle_apptrace/exporters/file_exporter.py +123 -36
  3. monocle_apptrace/instrumentation/common/__init__.py +16 -1
  4. monocle_apptrace/instrumentation/common/constants.py +6 -1
  5. monocle_apptrace/instrumentation/common/instrumentor.py +19 -152
  6. monocle_apptrace/instrumentation/common/method_wrappers.py +380 -0
  7. monocle_apptrace/instrumentation/common/span_handler.py +39 -24
  8. monocle_apptrace/instrumentation/common/utils.py +20 -14
  9. monocle_apptrace/instrumentation/common/wrapper.py +10 -9
  10. monocle_apptrace/instrumentation/common/wrapper_method.py +39 -1
  11. monocle_apptrace/instrumentation/metamodel/a2a/__init__.py +0 -0
  12. monocle_apptrace/instrumentation/metamodel/a2a/_helper.py +37 -0
  13. monocle_apptrace/instrumentation/metamodel/a2a/entities/__init__.py +0 -0
  14. monocle_apptrace/instrumentation/metamodel/a2a/entities/inference.py +112 -0
  15. monocle_apptrace/instrumentation/metamodel/a2a/methods.py +22 -0
  16. monocle_apptrace/instrumentation/metamodel/aiohttp/_helper.py +6 -11
  17. monocle_apptrace/instrumentation/metamodel/anthropic/_helper.py +35 -18
  18. monocle_apptrace/instrumentation/metamodel/anthropic/entities/inference.py +14 -10
  19. monocle_apptrace/instrumentation/metamodel/azfunc/_helper.py +13 -11
  20. monocle_apptrace/instrumentation/metamodel/azfunc/entities/http.py +5 -0
  21. monocle_apptrace/instrumentation/metamodel/azureaiinference/_helper.py +88 -8
  22. monocle_apptrace/instrumentation/metamodel/azureaiinference/entities/inference.py +22 -8
  23. monocle_apptrace/instrumentation/metamodel/botocore/_helper.py +92 -16
  24. monocle_apptrace/instrumentation/metamodel/botocore/entities/inference.py +13 -8
  25. monocle_apptrace/instrumentation/metamodel/botocore/handlers/botocore_span_handler.py +1 -1
  26. monocle_apptrace/instrumentation/metamodel/fastapi/__init__.py +0 -0
  27. monocle_apptrace/instrumentation/metamodel/fastapi/_helper.py +82 -0
  28. monocle_apptrace/instrumentation/metamodel/fastapi/entities/__init__.py +0 -0
  29. monocle_apptrace/instrumentation/metamodel/fastapi/entities/http.py +44 -0
  30. monocle_apptrace/instrumentation/metamodel/fastapi/methods.py +23 -0
  31. monocle_apptrace/instrumentation/metamodel/finish_types.py +387 -0
  32. monocle_apptrace/instrumentation/metamodel/flask/_helper.py +6 -11
  33. monocle_apptrace/instrumentation/metamodel/gemini/_helper.py +51 -7
  34. monocle_apptrace/instrumentation/metamodel/gemini/entities/inference.py +17 -9
  35. monocle_apptrace/instrumentation/metamodel/gemini/entities/retrieval.py +43 -0
  36. monocle_apptrace/instrumentation/metamodel/gemini/methods.py +10 -0
  37. monocle_apptrace/instrumentation/metamodel/haystack/_helper.py +15 -8
  38. monocle_apptrace/instrumentation/metamodel/haystack/entities/inference.py +5 -10
  39. monocle_apptrace/instrumentation/metamodel/haystack/methods.py +7 -0
  40. monocle_apptrace/instrumentation/metamodel/lambdafunc/_helper.py +78 -0
  41. monocle_apptrace/instrumentation/metamodel/lambdafunc/entities/http.py +51 -0
  42. monocle_apptrace/instrumentation/metamodel/lambdafunc/methods.py +23 -0
  43. monocle_apptrace/instrumentation/metamodel/lambdafunc/wrapper.py +23 -0
  44. monocle_apptrace/instrumentation/metamodel/langchain/_helper.py +127 -19
  45. monocle_apptrace/instrumentation/metamodel/langchain/entities/inference.py +15 -10
  46. monocle_apptrace/instrumentation/metamodel/langgraph/_helper.py +67 -10
  47. monocle_apptrace/instrumentation/metamodel/langgraph/entities/inference.py +127 -20
  48. monocle_apptrace/instrumentation/metamodel/langgraph/langgraph_processor.py +43 -0
  49. monocle_apptrace/instrumentation/metamodel/langgraph/methods.py +29 -5
  50. monocle_apptrace/instrumentation/metamodel/llamaindex/_helper.py +227 -16
  51. monocle_apptrace/instrumentation/metamodel/llamaindex/entities/agent.py +127 -10
  52. monocle_apptrace/instrumentation/metamodel/llamaindex/entities/inference.py +13 -8
  53. monocle_apptrace/instrumentation/metamodel/llamaindex/llamaindex_processor.py +51 -0
  54. monocle_apptrace/instrumentation/metamodel/llamaindex/methods.py +68 -1
  55. monocle_apptrace/instrumentation/metamodel/mcp/__init__.py +0 -0
  56. monocle_apptrace/instrumentation/metamodel/mcp/_helper.py +118 -0
  57. monocle_apptrace/instrumentation/metamodel/mcp/entities/__init__.py +0 -0
  58. monocle_apptrace/instrumentation/metamodel/mcp/entities/inference.py +48 -0
  59. monocle_apptrace/instrumentation/metamodel/mcp/mcp_processor.py +13 -0
  60. monocle_apptrace/instrumentation/metamodel/mcp/methods.py +21 -0
  61. monocle_apptrace/instrumentation/metamodel/openai/_helper.py +83 -16
  62. monocle_apptrace/instrumentation/metamodel/openai/entities/inference.py +103 -92
  63. monocle_apptrace/instrumentation/metamodel/openai/entities/retrieval.py +1 -1
  64. monocle_apptrace/instrumentation/metamodel/teamsai/_helper.py +41 -22
  65. monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/actionplanner_output_processor.py +1 -1
  66. monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/teamsai_output_processor.py +5 -9
  67. monocle_apptrace/instrumentation/metamodel/teamsai/sample.json +0 -4
  68. {monocle_apptrace-0.4.2.dist-info → monocle_apptrace-0.5.0b1.dist-info}/METADATA +14 -3
  69. {monocle_apptrace-0.4.2.dist-info → monocle_apptrace-0.5.0b1.dist-info}/RECORD +72 -47
  70. {monocle_apptrace-0.4.2.dist-info → monocle_apptrace-0.5.0b1.dist-info}/WHEEL +0 -0
  71. {monocle_apptrace-0.4.2.dist-info → monocle_apptrace-0.5.0b1.dist-info}/licenses/LICENSE +0 -0
  72. {monocle_apptrace-0.4.2.dist-info → monocle_apptrace-0.5.0b1.dist-info}/licenses/NOTICE +0 -0
@@ -1,6 +1,6 @@
1
1
  import sys, os
2
2
  import runpy
3
- from monocle_apptrace.instrumentation.common.instrumentor import setup_monocle_telemetry
3
+ from monocle_apptrace import setup_monocle_telemetry
4
4
 
5
5
  def main():
6
6
  if len(sys.argv) < 2 or not sys.argv[1].endswith(".py"):
@@ -3,7 +3,7 @@
3
3
  from os import linesep, path
4
4
  from io import TextIOWrapper
5
5
  from datetime import datetime
6
- from typing import Optional, Callable, Sequence
6
+ from typing import Optional, Callable, Sequence, Dict, Tuple
7
7
  from opentelemetry.sdk.trace import ReadableSpan
8
8
  from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
9
9
  from opentelemetry.sdk.resources import SERVICE_NAME
@@ -12,11 +12,9 @@ from monocle_apptrace.exporters.exporter_processor import ExportTaskProcessor
12
12
 
13
13
  DEFAULT_FILE_PREFIX:str = "monocle_trace_"
14
14
  DEFAULT_TIME_FORMAT:str = "%Y-%m-%d_%H.%M.%S"
15
+ HANDLE_TIMEOUT_SECONDS: int = 60 # 1 minute timeout
15
16
 
16
17
  class FileSpanExporter(SpanExporterBase):
17
- current_trace_id: int = None
18
- current_file_path: str = None
19
-
20
18
  def __init__(
21
19
  self,
22
20
  service_name: Optional[str] = None,
@@ -30,13 +28,15 @@ class FileSpanExporter(SpanExporterBase):
30
28
  task_processor: Optional[ExportTaskProcessor] = None
31
29
  ):
32
30
  super().__init__()
33
- self.out_handle:TextIOWrapper = None
31
+ # Dictionary to store file handles: {trace_id: (file_handle, file_path, creation_time, first_span)}
32
+ self.file_handles: Dict[int, Tuple[TextIOWrapper, str, datetime, bool]] = {}
34
33
  self.formatter = formatter
35
34
  self.service_name = service_name
36
35
  self.output_path = out_path
37
36
  self.file_prefix = file_prefix
38
37
  self.time_format = time_format
39
38
  self.task_processor = task_processor
39
+ self.is_first_span_in_file = True # Track if this is the first span in the current file
40
40
  if self.task_processor is not None:
41
41
  self.task_processor.start()
42
42
 
@@ -49,46 +49,133 @@ class FileSpanExporter(SpanExporterBase):
49
49
  else:
50
50
  return self._process_spans(spans, is_root_span=is_root_span)
51
51
 
52
+ def _cleanup_expired_handles(self) -> None:
53
+ """Close and remove file handles that have exceeded the timeout."""
54
+ current_time = datetime.now()
55
+ expired_trace_ids = []
56
+
57
+ for trace_id, (handle, file_path, creation_time, _) in self.file_handles.items():
58
+ if (current_time - creation_time).total_seconds() > HANDLE_TIMEOUT_SECONDS:
59
+ expired_trace_ids.append(trace_id)
60
+
61
+ for trace_id in expired_trace_ids:
62
+ self._close_trace_handle(trace_id)
63
+
64
+ def _get_or_create_handle(self, trace_id: int, service_name: str) -> Tuple[TextIOWrapper, str, bool]:
65
+ """Get existing handle or create new one for the trace_id."""
66
+ self._cleanup_expired_handles()
67
+
68
+ if trace_id in self.file_handles:
69
+ handle, file_path, creation_time, first_span = self.file_handles[trace_id]
70
+ return handle, file_path, first_span
71
+
72
+ # Create new handle
73
+ file_path = path.join(self.output_path,
74
+ self.file_prefix + service_name + "_" + hex(trace_id) + "_"
75
+ + datetime.now().strftime(self.time_format) + ".json")
76
+
77
+ try:
78
+ handle = open(file_path, "w", encoding='UTF-8')
79
+ handle.write("[")
80
+ self.file_handles[trace_id] = (handle, file_path, datetime.now(), True)
81
+ return handle, file_path, True
82
+ except Exception as e:
83
+ print(f"Error creating file {file_path}: {e}")
84
+ return None, file_path, True
85
+
86
+ def _close_trace_handle(self, trace_id: int) -> None:
87
+ """Close and remove a specific trace handle."""
88
+ if trace_id in self.file_handles:
89
+ handle, file_path, creation_time, _ = self.file_handles[trace_id]
90
+ try:
91
+ if handle is not None:
92
+ handle.write("]")
93
+ handle.close()
94
+ except Exception as e:
95
+ print(f"Error closing file {file_path}: {e}")
96
+ finally:
97
+ del self.file_handles[trace_id]
98
+
99
+ def _mark_span_written(self, trace_id: int) -> None:
100
+ """Mark that a span has been written for this trace (no longer first span)."""
101
+ if trace_id in self.file_handles:
102
+ handle, file_path, creation_time, _ = self.file_handles[trace_id]
103
+ self.file_handles[trace_id] = (handle, file_path, creation_time, False)
104
+
52
105
  def _process_spans(self, spans: Sequence[ReadableSpan], is_root_span: bool = False) -> SpanExportResult:
53
- first_span:bool = True
106
+ # Group spans by trace_id for efficient processing
107
+ spans_by_trace = {}
108
+ root_span_traces = set()
109
+
54
110
  for span in spans:
55
111
  if self.skip_export(span):
56
112
  continue
57
- if span.context.trace_id != self.current_trace_id:
58
- self.rotate_file(span.resource.attributes[SERVICE_NAME],
59
- span.context.trace_id)
60
- first_span = True
61
- if first_span:
62
- first_span = False
63
- else:
64
- self.out_handle.write(",")
65
- self.out_handle.write(self.formatter(span))
66
- if is_root_span:
67
- self.reset_handle()
68
- else:
69
- self.out_handle.flush()
113
+
114
+ trace_id = span.context.trace_id
115
+ if trace_id not in spans_by_trace:
116
+ spans_by_trace[trace_id] = []
117
+ spans_by_trace[trace_id].append(span)
118
+
119
+ # Check if this span is a root span
120
+ if not span.parent:
121
+ root_span_traces.add(trace_id)
122
+
123
+ # Process spans for each trace
124
+ for trace_id, trace_spans in spans_by_trace.items():
125
+ service_name = trace_spans[0].resource.attributes.get(SERVICE_NAME, "unknown")
126
+ handle, file_path, is_first_span = self._get_or_create_handle(trace_id, service_name)
127
+
128
+ if handle is None:
129
+ continue
130
+
131
+ for span in trace_spans:
132
+ if not is_first_span:
133
+ try:
134
+ handle.write(",")
135
+ except Exception as e:
136
+ print(f"Error writing comma to file {file_path} for span {span.context.span_id}: {e}")
137
+ continue
138
+
139
+ try:
140
+ handle.write(self.formatter(span))
141
+ if is_first_span:
142
+ self._mark_span_written(trace_id)
143
+ is_first_span = False
144
+ except Exception as e:
145
+ print(f"Error formatting span {span.context.span_id}: {e}")
146
+ continue
147
+
148
+ # Close handles for traces with root spans
149
+ for trace_id in root_span_traces:
150
+ self._close_trace_handle(trace_id)
151
+
152
+ # Flush remaining handles
153
+ for trace_id, (handle, file_path, _, _) in self.file_handles.items():
154
+ if trace_id not in root_span_traces:
155
+ try:
156
+ if handle is not None:
157
+ handle.flush()
158
+ except Exception as e:
159
+ print(f"Error flushing file {file_path}: {e}")
160
+
70
161
  return SpanExportResult.SUCCESS
71
162
 
72
- def rotate_file(self, trace_name:str, trace_id:int) -> None:
73
- self.reset_handle()
74
- self.current_file_path = path.join(self.output_path,
75
- self.file_prefix + trace_name + "_" + hex(trace_id) + "_"
76
- + datetime.now().strftime(self.time_format) + ".json")
77
- self.out_handle = open(self.current_file_path, "w", encoding='UTF-8')
78
- self.out_handle.write("[")
79
- self.current_trace_id = trace_id
80
-
81
163
  def force_flush(self, timeout_millis: int = 30000) -> bool:
82
- self.out_handle.flush()
164
+ """Flush all open file handles."""
165
+ for trace_id, (handle, file_path, _, _) in self.file_handles.items():
166
+ try:
167
+ if handle is not None:
168
+ handle.flush()
169
+ except Exception as e:
170
+ print(f"Error flushing file {file_path}: {e}")
83
171
  return True
84
172
 
85
- def reset_handle(self) -> None:
86
- if self.out_handle is not None:
87
- self.out_handle.write("]")
88
- self.out_handle.close()
89
- self.out_handle = None
90
-
91
173
  def shutdown(self) -> None:
174
+ """Close all file handles and stop task processor."""
92
175
  if hasattr(self, 'task_processor') and self.task_processor is not None:
93
176
  self.task_processor.stop()
94
- self.reset_handle()
177
+
178
+ # Close all remaining file handles
179
+ trace_ids_to_close = list(self.file_handles.keys())
180
+ for trace_id in trace_ids_to_close:
181
+ self._close_trace_handle(trace_id)
@@ -1,2 +1,17 @@
1
- from .instrumentor import setup_monocle_telemetry, start_trace, stop_trace, start_scope, stop_scope, http_route_handler, monocle_trace_scope, monocle_trace_scope_method, monocle_trace
1
+ from .instrumentor import (
2
+ setup_monocle_telemetry,
3
+ start_trace,
4
+ stop_trace,
5
+ start_scope,
6
+ stop_scope,
7
+ http_route_handler,
8
+ monocle_trace_scope,
9
+ amonocle_trace_scope,
10
+ monocle_trace_scope_method,
11
+ monocle_trace,
12
+ amonocle_trace,
13
+ monocle_trace_method,
14
+ monocle_trace_http_route,
15
+ is_valid_trace_id_uuid
16
+ )
2
17
  from .utils import MonocleSpanException
@@ -57,6 +57,10 @@ llm_type_map = {
57
57
  "chatcompletionsclient": "azure_ai_inference",
58
58
  "embeddingsclient": "azure_ai_inference",
59
59
  "imageembeddingsclient": "azure_ai_inference",
60
+ "chatbedrockconverse": "aws_bedrock",
61
+ "googleaigeminichatgenerator": "gemini",
62
+ "gemini": "gemini",
63
+ "chatgooglegenerativeai": "gemini",
60
64
  }
61
65
 
62
66
  MONOCLE_INSTRUMENTOR = "monocle_apptrace"
@@ -81,4 +85,5 @@ WORKFLOW_TYPE_GENERIC = "workflow.generic"
81
85
  MONOCLE_SDK_VERSION = "monocle_apptrace.version"
82
86
  MONOCLE_SDK_LANGUAGE = "monocle_apptrace.language"
83
87
  MONOCLE_DETECTED_SPAN_ERROR = "monocle_apptrace.detected_span_error"
84
- HTTP_SUCCESS_CODES = ('200', '201', '202', '204', '205', '206')
88
+ HTTP_SUCCESS_CODES = ('200', '201', '202', '204', '205', '206')
89
+ CHILD_ERROR_CODE = "child.error.code"
@@ -1,23 +1,19 @@
1
1
  import logging
2
2
  import inspect
3
3
  from typing import Collection, Dict, List, Union
4
- import random
5
4
  import uuid
6
5
  import inspect
7
6
  from opentelemetry import trace
8
- from contextlib import contextmanager
9
- from opentelemetry.context import attach, get_value, set_value, get_current, detach
7
+ from opentelemetry.context import attach, get_value, set_value
10
8
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
11
9
  from opentelemetry.instrumentation.utils import unwrap
12
- from opentelemetry.trace import SpanContext
13
- from opentelemetry.sdk.trace import TracerProvider, Span, id_generator
10
+ from opentelemetry.sdk.trace import TracerProvider, Span
14
11
  from opentelemetry.sdk.resources import SERVICE_NAME, Resource
15
12
  from opentelemetry.sdk.trace import Span, TracerProvider
16
13
  from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanProcessor
17
14
  from opentelemetry.sdk.trace.export import SpanExporter
18
15
  from opentelemetry.trace import get_tracer
19
16
  from wrapt import wrap_function_wrapper
20
- from opentelemetry.trace.propagation import set_span_in_context, _SPAN_KEY
21
17
  from monocle_apptrace.exporters.monocle_exporters import get_monocle_exporter
22
18
  from monocle_apptrace.instrumentation.common.span_handler import SpanHandler, NonFrameworkSpanHandler
23
19
  from monocle_apptrace.instrumentation.common.wrapper_method import (
@@ -27,10 +23,11 @@ from monocle_apptrace.instrumentation.common.wrapper_method import (
27
23
  )
28
24
  from monocle_apptrace.instrumentation.common.wrapper import scope_wrapper, ascope_wrapper, monocle_wrapper, amonocle_wrapper
29
25
  from monocle_apptrace.instrumentation.common.utils import (
30
- set_scope, remove_scope, http_route_handler, load_scopes, http_async_route_handler
26
+ load_scopes
31
27
  )
32
- from monocle_apptrace.instrumentation.common.constants import MONOCLE_INSTRUMENTOR, WORKFLOW_TYPE_GENERIC
28
+ from monocle_apptrace.instrumentation.common.constants import MONOCLE_INSTRUMENTOR
33
29
  from functools import wraps
30
+
34
31
  logger = logging.getLogger(__name__)
35
32
 
36
33
  SESSION_PROPERTIES_KEY = "session"
@@ -229,49 +226,6 @@ def on_processor_start(span: Span, parent_context):
229
226
  def set_context_properties(properties: dict) -> None:
230
227
  attach(set_value(SESSION_PROPERTIES_KEY, properties))
231
228
 
232
- def start_trace():
233
- """
234
- Starts a new trace. All the spans created after this call will be part of the same trace.
235
- Returns:
236
- Token: A token representing the attached context for the workflow span.
237
- This token is to be used later to stop the current trace.
238
- Returns None if tracing fails.
239
-
240
- Raises:
241
- Exception: The function catches all exceptions internally and logs a warning.
242
- """
243
- try:
244
- tracer = get_tracer(instrumenting_module_name= MONOCLE_INSTRUMENTOR, tracer_provider= get_tracer_provider())
245
- span = tracer.start_span(name = "workflow")
246
- updated_span_context = set_span_in_context(span=span)
247
- SpanHandler.set_default_monocle_attributes(span)
248
- SpanHandler.set_workflow_properties(span)
249
- token = attach(updated_span_context)
250
- return token
251
- except Exception as e:
252
- logger.warning("Failed to start trace {e}")
253
- return None
254
-
255
- def stop_trace(token) -> None:
256
- """
257
- Stop the active trace and detach workflow type if token is provided. All the spans created after this will not be part of the trace.
258
- Args:
259
- token: The token that was returned when the trace was started. Used to detach
260
- workflow type. Can be None in which case only the span is ended.
261
- Returns:
262
- None
263
- """
264
- try:
265
- _parent_span_context = get_current()
266
- if _parent_span_context is not None:
267
- parent_span: Span = _parent_span_context.get(_SPAN_KEY, None)
268
- if parent_span is not None:
269
- parent_span.end()
270
- if token is not None:
271
- detach(token)
272
- except:
273
- logger.warning("Failed to stop trace")
274
-
275
229
  def is_valid_trace_id_uuid(traceId: str) -> bool:
276
230
  try:
277
231
  uuid.UUID(traceId)
@@ -280,105 +234,18 @@ def is_valid_trace_id_uuid(traceId: str) -> bool:
280
234
  pass
281
235
  return False
282
236
 
283
- def start_scope(scope_name: str, scope_value:str = None) -> object:
284
- """
285
- Start a new scope with the given name and and optional value. If no value is provided, a random UUID will be generated.
286
- All the spans, across traces created after this call will have the scope attached until the scope is stopped.
287
- Args:
288
- scope_name: The name of the scope.
289
- scope_value: Optional value of the scope. If None, a random UUID will be generated.
290
- Returns:
291
- Token: A token representing the attached context for the scope. This token is to be used later to stop the current scope.
292
- """
293
- return set_scope(scope_name, scope_value)
294
-
295
- def stop_scope(token:object) -> None:
296
- """
297
- Stop the active scope. All the spans created after this will not have the scope attached.
298
- Args:
299
- token: The token that was returned when the scope was started.
300
- Returns:
301
- None
302
- """
303
- remove_scope(token)
304
- return
305
-
306
- @contextmanager
307
- def monocle_trace():
308
- """
309
- Context manager to start and stop a scope. All the spans, across traces created within the encapsulated code will have same trace ID
310
- """
311
- token = start_trace()
312
- try:
313
- yield
314
- finally:
315
- stop_trace(token)
316
-
317
- @contextmanager
318
- def monocle_trace_scope(scope_name: str, scope_value:str = None):
319
- """
320
- Context manager to start and stop a scope. All the spans, across traces created within the encapsulated code will have the scope attached.
321
- Args:
322
- scope_name: The name of the scope.
323
- scope_value: Optional value of the scope. If None, a random UUID will be generated."""
324
- token = start_scope(scope_name, scope_value)
325
- try:
326
- yield
327
- finally:
328
- stop_scope(token)
329
-
330
- def monocle_trace_scope_method(scope_name: str, scope_value:str=None):
331
- """
332
- Decorator to start and stop a scope for a method. All the spans, across traces created in the method will have the scope attached.
333
- """
334
- def decorator(func):
335
- if inspect.iscoroutinefunction(func):
336
- @wraps(func)
337
- async def wrapper(*args, **kwargs):
338
- token = start_scope(scope_name, scope_value)
339
- try:
340
- result = await func(*args, **kwargs)
341
- return result
342
- finally:
343
- stop_scope(token)
344
- return wrapper
345
- else:
346
- @wraps(func)
347
- def wrapper(*args, **kwargs):
348
- token = start_scope(scope_name, scope_value)
349
- try:
350
- result = func(*args, **kwargs)
351
- return result
352
- finally:
353
- stop_scope(token)
354
- return wrapper
355
- return decorator
356
-
357
- def monocle_trace_http_route(func):
358
- """
359
- Decorator to start and stop a continue traces and scope for a http route. It will also initiate new scopes from the http headers if configured in ``monocle_scopes.json``
360
- All the spans, across traces created in the route will have the scope attached.
361
- """
362
- if inspect.iscoroutinefunction(func):
363
- @wraps(func)
364
- async def wrapper(*args, **kwargs):
365
- return await http_async_route_handler(func, *args, **kwargs)
366
- return wrapper
367
- else:
368
- @wraps(func)
369
- def wrapper(*args, **kwargs):
370
- return http_route_handler(func, *args, **kwargs)
371
- return wrapper
372
-
373
- class FixedIdGenerator(id_generator.IdGenerator):
374
- def __init__(
375
- self,
376
- trace_id: int) -> None:
377
- self.trace_id = trace_id
378
-
379
- def generate_span_id(self) -> int:
380
- return random.getrandbits(64)
381
-
382
- def generate_trace_id(self) -> int:
383
- return self.trace_id
237
+ from monocle_apptrace.instrumentation.common.method_wrappers import (
238
+ monocle_trace_scope_method,
239
+ amonocle_trace_scope,
240
+ monocle_trace,
241
+ amonocle_trace,
242
+ monocle_trace_method,
243
+ monocle_trace_http_route,
244
+ start_scope,
245
+ stop_scope,
246
+ start_trace,
247
+ stop_trace,
248
+ http_route_handler,
249
+ monocle_trace_scope,
250
+ )
384
251