9
9
from sentry_sdk .integrations .opentelemetry .utils import (
10
10
is_sentry_span ,
11
11
convert_from_otel_timestamp ,
12
+ extract_span_attributes ,
12
13
extract_span_data ,
13
14
)
14
15
from sentry_sdk .integrations .opentelemetry .consts import (
15
16
OTEL_SENTRY_CONTEXT ,
17
+ SentrySpanAttribute ,
16
18
)
17
19
from sentry_sdk ._types import TYPE_CHECKING
18
20
@@ -107,9 +109,9 @@ def _root_span_to_transaction_event(self, span):
107
109
# type: (ReadableSpan) -> Optional[Event]
108
110
if not span .context :
109
111
return None
110
- if not span . start_time :
111
- return None
112
- if not span . end_time :
112
+
113
+ event = self . _common_span_transaction_attributes_as_json ( span )
114
+ if event is None :
113
115
return None
114
116
115
117
trace_id = format_trace_id (span .context .trace_id )
@@ -135,25 +137,25 @@ def _root_span_to_transaction_event(self, span):
135
137
if span .resource .attributes :
136
138
contexts [OTEL_SENTRY_CONTEXT ] = {"resource" : dict (span .resource .attributes )}
137
139
138
- event = {
139
- "type" : "transaction" ,
140
- "transaction " : description ,
141
- # TODO-neel-potel tx source based on integration
142
- "transaction_info" : { " source" : "custom" },
143
- "contexts " : contexts ,
144
- "start_timestamp " : convert_from_otel_timestamp ( span . start_time ) ,
145
- "timestamp" : convert_from_otel_timestamp ( span . end_time ),
146
- } # type: Event
140
+ event . update (
141
+ {
142
+ "type " : "transaction" ,
143
+ "transaction" : description ,
144
+ # TODO-neel-potel tx source based on integration
145
+ "transaction_info " : { "source" : "custom" } ,
146
+ "contexts " : contexts ,
147
+ }
148
+ ) # type: Event
147
149
148
150
return event
149
151
150
152
def _span_to_json (self , span ):
151
153
# type: (ReadableSpan) -> Optional[dict[str, Any]]
152
154
if not span .context :
153
155
return None
154
- if not span . start_time :
155
- return None
156
- if not span . end_time :
156
+
157
+ span_json = self . _common_span_transaction_attributes_as_json ( span )
158
+ if span_json is None :
157
159
return None
158
160
159
161
trace_id = format_trace_id (span .context .trace_id )
@@ -162,20 +164,41 @@ def _span_to_json(self, span):
162
164
163
165
(op , description , status , _ , origin ) = extract_span_data (span )
164
166
165
- span_json = {
166
- "trace_id" : trace_id ,
167
- "span_id " : span_id ,
168
- "op " : op ,
169
- "description " : description ,
170
- "status " : status ,
171
- "start_timestamp " : convert_from_otel_timestamp ( span . start_time ) ,
172
- "timestamp " : convert_from_otel_timestamp ( span . end_time ) ,
173
- "origin" : origin or DEFAULT_SPAN_ORIGIN ,
174
- } # type: dict[str, Any]
167
+ span_json . update (
168
+ {
169
+ "trace_id " : trace_id ,
170
+ "span_id " : span_id ,
171
+ "op " : op ,
172
+ "description " : description ,
173
+ "status " : status ,
174
+ "origin " : origin or DEFAULT_SPAN_ORIGIN ,
175
+ }
176
+ )
175
177
176
178
if parent_span_id :
177
179
span_json ["parent_span_id" ] = parent_span_id
180
+
178
181
if span .attributes :
179
182
span_json ["data" ] = dict (span .attributes )
180
183
181
184
return span_json
185
+
186
+ def _common_span_transaction_attributes_as_json (self , span ):
187
+ # type: (ReadableSpan) -> Optional[dict[str, Any]]
188
+ if not span .start_time or not span .end_time :
189
+ return None
190
+
191
+ common_json = {
192
+ "start_timestamp" : convert_from_otel_timestamp (span .start_time ),
193
+ "timestamp" : convert_from_otel_timestamp (span .end_time ),
194
+ } # type: dict[str, Any]
195
+
196
+ measurements = extract_span_attributes (span , SentrySpanAttribute .MEASUREMENT )
197
+ if measurements :
198
+ common_json ["measurements" ] = measurements
199
+
200
+ tags = extract_span_attributes (span , SentrySpanAttribute .TAG )
201
+ if tags :
202
+ common_json ["tags" ] = tags
203
+
204
+ return common_json
0 commit comments