Duibonduil commited on
Commit
cccccb0
·
verified ·
1 Parent(s): 7a3c0ee

Upload __init__.py

Browse files
Files changed (1) hide show
  1. aworld/trace/__init__.py +135 -0
aworld/trace/__init__.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf-8
2
+ # Copyright (c) 2025 inclusionAI.
3
+ import typing
4
+ from os import linesep
5
+ from aworld.trace.base import Span
6
+ from aworld.trace.span_cosumer import SpanConsumer, get_span_consumers
7
+ from opentelemetry.sdk.trace import ReadableSpan
8
+ from opentelemetry.sdk.trace.export import SpanExportResult, SpanExporter
9
+ from aworld.logs.util import logger
10
+
11
+
12
+ class FileSpanExporter(SpanExporter):
13
+ """Implementation of :class:`SpanExporter` that prints spans to the
14
+ console.
15
+
16
+ This class can be used for diagnostic purposes. It prints the exported
17
+ spans to the console STDOUT.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ file_path: str = None,
23
+ formatter: typing.Callable[
24
+ [ReadableSpan], str
25
+ ] = lambda span: span.to_json() + linesep,
26
+ ):
27
+ self.formatter = formatter
28
+ self.file_path = file_path
29
+
30
+ def export(self, spans: typing.Sequence[ReadableSpan]) -> SpanExportResult:
31
+ try:
32
+ with open(self.file_path, 'a') as f:
33
+ for span in spans:
34
+ f.write(self.formatter(span))
35
+
36
+ return SpanExportResult.SUCCESS
37
+ except Exception as e:
38
+ logger.error(e)
39
+ return SpanExportResult.FAILURE
40
+
41
+ def force_flush(self, timeout_millis: int = 30000) -> bool:
42
+ return True
43
+
44
+
45
+ class ReadOnlySpan(Span, ReadableSpan):
46
+ """Implementation of :class:`Span` that wraps a :class:`ReadableSpan`.
47
+ This class can be used to wrap a :class:`ReadableSpan` to make it
48
+ read-only.
49
+ Args:
50
+ span: The span to wrap.
51
+ """
52
+
53
+ def __init__(self, span: ReadableSpan):
54
+ self._span = span
55
+
56
+ if not typing.TYPE_CHECKING:
57
+ def __getattr__(self, name: str) -> typing.Any:
58
+ return getattr(self._span, name)
59
+
60
+ def end(self, end_time: typing.Optional[int] = None) -> None:
61
+ pass
62
+
63
+ def set_attribute(self, key: str, value: typing.Any) -> None:
64
+ pass
65
+
66
+ def set_attributes(self, attributes: dict[str, typing.Any]) -> None:
67
+ pass
68
+
69
+ def is_recording(self) -> bool:
70
+ return False
71
+
72
+ def record_exception(
73
+ self,
74
+ exception: BaseException,
75
+ attributes: dict[str, typing.Any] = None,
76
+ timestamp: typing.Optional[int] = None,
77
+ escaped: bool = False,
78
+ ) -> None:
79
+ pass
80
+
81
+ def get_trace_id(self) -> str:
82
+ return f"{self._span.get_span_context().trace_id:032x}"
83
+
84
+ def get_span_id(self) -> str:
85
+ return f"{self._span.get_span_context().span_id:016x}"
86
+
87
+
88
+ class SpanConsumerExporter(SpanExporter):
89
+ """Implementation of :class:`SpanExporter` that exports spans to
90
+ multiple span consumers.
91
+ This class can be used for exporting spans to multiple span consumers.
92
+ It exports the spans to the span consumers in the order they are passed
93
+ in the constructor.
94
+ Args:
95
+ span_consumers: A sequence of span consumers to export spans to.
96
+ """
97
+
98
+ def __init__(
99
+ self,
100
+ span_consumers: typing.Sequence[SpanConsumer] = None,
101
+ ):
102
+ self._span_consumers = span_consumers or []
103
+ self._loaded = False
104
+
105
+ def _load_span_consumers(self):
106
+ if not self._loaded:
107
+ self._span_consumers.extend(get_span_consumers())
108
+ self._loaded = True
109
+
110
+ def export(
111
+ self, spans: typing.Sequence[ReadableSpan]
112
+ ) -> SpanExportResult:
113
+ self._load_span_consumers()
114
+ span_batches = []
115
+ for span in spans:
116
+ span_batches.append(ReadOnlySpan(span))
117
+ for span_consumer in self._span_consumers:
118
+ try:
119
+ span_consumer.consume(span_batches)
120
+ except Exception as e:
121
+ logger.error(
122
+ f"Error consume spans: {e}, span_consumer: {span_consumer.__class__.__name__}")
123
+ return SpanExportResult.SUCCESS
124
+
125
+
126
+ class NoOpSpanExporter(SpanExporter):
127
+ """Implementation of :class:`SpanExporter` that does not export spans."""
128
+
129
+ def export(
130
+ self, spans: typing.Sequence[ReadableSpan]
131
+ ) -> SpanExportResult:
132
+ return SpanExportResult.SUCCESS
133
+
134
+ def force_flush(self, timeout_millis: int = 30000) -> bool:
135
+ return True