1use crate::otel_to_sentry_v2;
2use crate::otel_trace::Span as OtelSpan;
3use crate::v2_to_v1;
4use relay_event_schema::protocol::Span as EventSpan;
5use relay_protocol::Error;
6
7pub fn otel_to_sentry_span(otel_span: OtelSpan) -> Result<EventSpan, Error> {
27 let span_v2 = otel_to_sentry_v2::otel_to_sentry_span(otel_span)?;
28 Ok(v2_to_v1::span_v2_to_span_v1(span_v2))
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use relay_protocol::{Annotated, SerializableAnnotated};
35
36 #[test]
37 fn parse_span() {
38 let json = r#"{
39 "traceId": "89143b0763095bd9c9955e8175d1fb23",
40 "spanId": "e342abb1214ca181",
41 "parentSpanId": "0c7a7dea069bf5a6",
42 "name": "middleware - fastify -> @fastify/multipart",
43 "kind": 2,
44 "startTimeUnixNano": "1697620454980000000",
45 "endTimeUnixNano": "1697620454980078800",
46 "attributes": [
47 {
48 "key": "http.route", "value": {
49 "stringValue": "/home"
50 }
51 },
52 {
53 "key": "http.request.method",
54 "value": {
55 "stringValue": "GET"
56 }
57 },
58 {
59 "key": "sentry.environment",
60 "value": {
61 "stringValue": "test"
62 }
63 },
64 {
65 "key": "fastify.type",
66 "value": {
67 "stringValue": "middleware"
68 }
69 },
70 {
71 "key": "plugin.name",
72 "value": {
73 "stringValue": "fastify -> @fastify/multipart"
74 }
75 },
76 {
77 "key": "hook.name",
78 "value": {
79 "stringValue": "onResponse"
80 }
81 },
82 {
83 "key": "sentry.sample_rate",
84 "value": {
85 "intValue": "1"
86 }
87 },
88 {
89 "key": "sentry.parentSampled",
90 "value": {
91 "boolValue": true
92 }
93 },
94 {
95 "key": "sentry.exclusive_time_nano",
96 "value": {
97 "intValue": "1000000000"
98 }
99 }
100 ],
101 "droppedAttributesCount": 0,
102 "events": [],
103 "droppedEventsCount": 0,
104 "status": {
105 "code": 0,
106 "message": "test"
107 },
108 "links": [],
109 "droppedLinksCount": 0
110 }"#;
111 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
112 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
113 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
114 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
115 {
116 "timestamp": 1697620454.980079,
117 "start_timestamp": 1697620454.98,
118 "exclusive_time": 1000.0,
119 "op": "http.server",
120 "span_id": "e342abb1214ca181",
121 "parent_span_id": "0c7a7dea069bf5a6",
122 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
123 "status": "ok",
124 "description": "GET /home",
125 "data": {
126 "sentry.environment": "test",
127 "fastify.type": "middleware",
128 "hook.name": "onResponse",
129 "http.request.method": "GET",
130 "http.route": "/home",
131 "plugin.name": "fastify -> @fastify/multipart",
132 "sentry.name": "middleware - fastify -> @fastify/multipart",
133 "sentry.parentSampled": true,
134 "sentry.sample_rate": 1,
135 "sentry.status.message": "test"
136 },
137 "links": [],
138 "kind": "server"
139 }
140 "###);
141 }
142
143 #[test]
144 fn parse_span_with_exclusive_time_nano_attribute() {
145 let json = r#"{
146 "traceId": "89143b0763095bd9c9955e8175d1fb23",
147 "spanId": "e342abb1214ca181",
148 "parentSpanId": "0c7a7dea069bf5a6",
149 "name": "middleware - fastify -> @fastify/multipart",
150 "kind": 1,
151 "startTimeUnixNano": "1697620454980000000",
152 "endTimeUnixNano": "1697620454980078800",
153 "attributes": [
154 {
155 "key": "sentry.exclusive_time_nano",
156 "value": {
157 "intValue": "3200000000"
158 }
159 }
160 ]
161 }"#;
162 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
163 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
164 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
165 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
166 {
167 "timestamp": 1697620454.980079,
168 "start_timestamp": 1697620454.98,
169 "exclusive_time": 3200.0,
170 "op": "default",
171 "span_id": "e342abb1214ca181",
172 "parent_span_id": "0c7a7dea069bf5a6",
173 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
174 "status": "unknown",
175 "description": "middleware - fastify -> @fastify/multipart",
176 "data": {
177 "sentry.name": "middleware - fastify -> @fastify/multipart"
178 },
179 "links": [],
180 "kind": "internal"
181 }
182 "###);
183 }
184
185 #[test]
186 fn parse_span_no_exclusive_time_nano_attribute() {
187 let json = r#"{
188 "traceId": "89143b0763095bd9c9955e8175d1fb23",
189 "spanId": "e342abb1214ca181",
190 "parentSpanId": "0c7a7dea069bf5a6",
191 "name": "middleware - fastify -> @fastify/multipart",
192 "kind": 1,
193 "startTimeUnixNano": "1697620454980000000",
194 "endTimeUnixNano": "1697620454980078800"
195 }"#;
196 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
197 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
198 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
199 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
200 {
201 "timestamp": 1697620454.980079,
202 "start_timestamp": 1697620454.98,
203 "exclusive_time": 0.0788,
204 "op": "default",
205 "span_id": "e342abb1214ca181",
206 "parent_span_id": "0c7a7dea069bf5a6",
207 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
208 "status": "unknown",
209 "description": "middleware - fastify -> @fastify/multipart",
210 "data": {
211 "sentry.name": "middleware - fastify -> @fastify/multipart"
212 },
213 "links": [],
214 "kind": "internal"
215 }
216 "###);
217 }
218
219 #[test]
220 fn parse_span_with_db_attributes() {
221 let json = r#"{
222 "traceId": "89143b0763095bd9c9955e8175d1fb23",
223 "spanId": "e342abb1214ca181",
224 "parentSpanId": "0c7a7dea069bf5a6",
225 "name": "database query",
226 "kind": 3,
227 "startTimeUnixNano": "1697620454980000000",
228 "endTimeUnixNano": "1697620454980078800",
229 "attributes": [
230 {
231 "key" : "db.system",
232 "value": {
233 "stringValue": "mysql"
234 }
235 },
236 {
237 "key" : "db.name",
238 "value": {
239 "stringValue": "database"
240 }
241 },
242 {
243 "key" : "db.type",
244 "value": {
245 "stringValue": "sql"
246 }
247 },
248 {
249 "key" : "db.statement",
250 "value": {
251 "stringValue": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s"
252 }
253 }
254 ]
255 }"#;
256 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
257 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
258 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
259 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
260 {
261 "timestamp": 1697620454.980079,
262 "start_timestamp": 1697620454.98,
263 "exclusive_time": 0.0788,
264 "op": "db",
265 "span_id": "e342abb1214ca181",
266 "parent_span_id": "0c7a7dea069bf5a6",
267 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
268 "status": "unknown",
269 "description": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s",
270 "data": {
271 "db.system": "mysql",
272 "db.name": "database",
273 "db.statement": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s",
274 "db.type": "sql",
275 "sentry.name": "database query"
276 },
277 "links": [],
278 "kind": "client"
279 }
280 "###);
281 }
282
283 #[test]
284 fn parse_span_with_db_attributes_and_description() {
285 let json = r#"{
286 "traceId": "89143b0763095bd9c9955e8175d1fb23",
287 "spanId": "e342abb1214ca181",
288 "parentSpanId": "0c7a7dea069bf5a6",
289 "name": "database query",
290 "kind": 3,
291 "startTimeUnixNano": "1697620454980000000",
292 "endTimeUnixNano": "1697620454980078800",
293 "attributes": [
294 {
295 "key" : "db.name",
296 "value": {
297 "stringValue": "database"
298 }
299 },
300 {
301 "key" : "db.type",
302 "value": {
303 "stringValue": "sql"
304 }
305 },
306 {
307 "key" : "db.statement",
308 "value": {
309 "stringValue": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s"
310 }
311 },
312 {
313 "key": "sentry.description",
314 "value": {
315 "stringValue": "index view query"
316 }
317 }
318 ]
319 }"#;
320 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
321 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
322 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
323 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
324 {
325 "timestamp": 1697620454.980079,
326 "start_timestamp": 1697620454.98,
327 "exclusive_time": 0.0788,
328 "op": "default",
329 "span_id": "e342abb1214ca181",
330 "parent_span_id": "0c7a7dea069bf5a6",
331 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
332 "status": "unknown",
333 "description": "index view query",
334 "data": {
335 "db.name": "database",
336 "db.statement": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s",
337 "db.type": "sql",
338 "sentry.name": "database query"
339 },
340 "links": [],
341 "kind": "client"
342 }
343 "###);
344 }
345
346 #[test]
347 fn parse_span_with_http_attributes() {
348 let json = r#"{
349 "traceId": "89143b0763095bd9c9955e8175d1fb23",
350 "spanId": "e342abb1214ca181",
351 "parentSpanId": "0c7a7dea069bf5a6",
352 "name": "http client request",
353 "kind": 2,
354 "startTimeUnixNano": "1697620454980000000",
355 "endTimeUnixNano": "1697620454980078800",
356 "attributes": [
357 {
358 "key" : "http.request.method",
359 "value": {
360 "stringValue": "GET"
361 }
362 },
363 {
364 "key" : "url.path",
365 "value": {
366 "stringValue": "/api/search?q=foobar"
367 }
368 }
369 ]
370 }"#;
371 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
372 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
373 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
374 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
375 {
376 "timestamp": 1697620454.980079,
377 "start_timestamp": 1697620454.98,
378 "exclusive_time": 0.0788,
379 "op": "http.server",
380 "span_id": "e342abb1214ca181",
381 "parent_span_id": "0c7a7dea069bf5a6",
382 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
383 "status": "unknown",
384 "description": "GET /api/search?q=foobar",
385 "data": {
386 "http.request.method": "GET",
387 "sentry.name": "http client request",
388 "url.path": "/api/search?q=foobar"
389 },
390 "links": [],
391 "kind": "server"
392 }
393 "###);
394 }
395
396 #[test]
397 fn parse_array_attribute() {
398 let json = r#"{
399 "traceId": "4c79f60c11214eb38604f4ae0781bfb2",
400 "spanId": "fa90fdead5f74052",
401 "parentSpanId": "fa90fdead5f74051",
402 "startTimeUnixNano": "123000000000",
403 "endTimeUnixNano": "123500000000",
404 "name": "cmd.run",
405 "status": {"code": 0},
406 "attributes": [
407 {
408 "key": "process.args",
409 "value": {
410 "arrayValue": {
411 "values": [
412 {"stringValue": "node"},
413 {"stringValue": "--require"},
414 {"stringValue": "preflight.cjs"}
415 ]
416 }
417 }
418 },
419 {
420 "key": "process.info",
421 "value": {
422 "arrayValue": {
423 "values": [
424 {"intValue": 41},
425 {
426 "arrayValue": {
427 "values": [
428 {"intValue": 42}
429 ]}
430 }
431 ]
432 }
433 }
434 }
435 ]
436 }"#;
437
438 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
439 let event_span = otel_to_sentry_span(otel_span).unwrap();
440
441 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
442 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r#"
443 {
444 "timestamp": 123.5,
445 "start_timestamp": 123.0,
446 "exclusive_time": 500.0,
447 "op": "default",
448 "span_id": "fa90fdead5f74052",
449 "parent_span_id": "fa90fdead5f74051",
450 "trace_id": "4c79f60c11214eb38604f4ae0781bfb2",
451 "status": "ok",
452 "description": "cmd.run",
453 "data": {
454 "process.args": "[\"node\",\"--require\",\"preflight.cjs\"]",
455 "process.info": "[41]",
456 "sentry.name": "cmd.run"
457 },
458 "links": []
459 }
460 "#);
461 }
462
463 #[test]
465 fn parse_sentry_attributes() {
466 let json = r#"{
467 "traceId": "4c79f60c11214eb38604f4ae0781bfb2",
468 "spanId": "fa90fdead5f74052",
469 "parentSpanId": "fa90fdead5f74051",
470 "startTimeUnixNano": "123000000000",
471 "endTimeUnixNano": "123500000000",
472 "name": "myname",
473 "status": {"code": 0, "message": "foo"},
474 "attributes": [
475 {
476 "key" : "browser.name",
477 "value": {
478 "stringValue": "Chrome"
479 }
480 },
481 {
482 "key" : "sentry.description",
483 "value": {
484 "stringValue": "mydescription"
485 }
486 },
487 {
488 "key" : "sentry.environment",
489 "value": {
490 "stringValue": "prod"
491 }
492 },
493 {
494 "key" : "sentry.op",
495 "value": {
496 "stringValue": "myop"
497 }
498 },
499 {
500 "key" : "sentry.platform",
501 "value": {
502 "stringValue": "php"
503 }
504 },
505 {
506 "key" : "sentry.profile_id",
507 "value": {
508 "stringValue": "a0aaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab"
509 }
510 },
511 {
512 "key" : "sentry.release",
513 "value": {
514 "stringValue": "myapp@1.0.0"
515 }
516 },
517 {
518 "key" : "sentry.sdk.name",
519 "value": {
520 "stringValue": "sentry.php"
521 }
522 },
523 {
524 "key" : "sentry.segment.id",
525 "value": {
526 "stringValue": "FA90FDEAD5F74052"
527 }
528 },
529 {
530 "key" : "sentry.segment.name",
531 "value": {
532 "stringValue": "my 1st transaction"
533 }
534 },
535 {
536 "key": "sentry.metrics_summary.some_metric",
537 "value": {
538 "arrayValue": {
539 "values": [
540 {
541 "kvlistValue": {
542 "values": [
543 {
544 "key": "min",
545 "value": {
546 "doubleValue": 1.0
547 }
548 },
549 {
550 "key": "max",
551 "value": {
552 "doubleValue": 2.0
553 }
554 },
555 {
556 "key": "sum",
557 "value": {
558 "doubleValue": 3.0
559 }
560 },
561 {
562 "key": "count",
563 "value": {
564 "intValue": "2"
565 }
566 },
567 {
568 "key": "tags",
569 "value": {
570 "kvlistValue": {
571 "values": [
572 {
573 "key": "environment",
574 "value": {
575 "stringValue": "test"
576 }
577 }
578 ]
579 }
580 }
581 }
582 ]
583 }
584 }
585 ]
586 }
587 }
588 }
589 ]
590 }"#;
591
592 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
593 let event_span = otel_to_sentry_span(otel_span).unwrap();
594
595 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
596 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
597 {
598 "timestamp": 123.5,
599 "start_timestamp": 123.0,
600 "exclusive_time": 500.0,
601 "op": "myop",
602 "span_id": "fa90fdead5f74052",
603 "parent_span_id": "fa90fdead5f74051",
604 "trace_id": "4c79f60c11214eb38604f4ae0781bfb2",
605 "segment_id": "fa90fdead5f74052",
606 "status": "ok",
607 "description": "mydescription",
608 "profile_id": "a0aaaaaaaaaaaaaaaaaaaaaaaaaaaaab",
609 "data": {
610 "browser.name": "Chrome",
611 "sentry.environment": "prod",
612 "sentry.release": "myapp@1.0.0",
613 "sentry.segment.name": "my 1st transaction",
614 "sentry.sdk.name": "sentry.php",
615 "sentry.metrics_summary.some_metric": "[]",
616 "sentry.name": "myname",
617 "sentry.status.message": "foo"
618 },
619 "links": [],
620 "platform": "php"
621 }
622 "###);
623 }
624
625 #[test]
626 fn parse_span_is_remote() {
627 let json = r#"{
628 "traceId": "89143b0763095bd9c9955e8175d1fb23",
629 "spanId": "e342abb1214ca181",
630 "parentSpanId": "0c7a7dea069bf5a6",
631 "startTimeUnixNano": "123000000000",
632 "endTimeUnixNano": "123500000000",
633 "flags": 768
634 }"#;
635 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
636 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
637 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
638 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
639 {
640 "timestamp": 123.5,
641 "start_timestamp": 123.0,
642 "exclusive_time": 500.0,
643 "op": "default",
644 "span_id": "e342abb1214ca181",
645 "parent_span_id": "0c7a7dea069bf5a6",
646 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
647 "is_remote": true,
648 "status": "unknown",
649 "data": {},
650 "links": []
651 }
652 "###);
653 }
654
655 #[test]
656 fn parse_span_is_not_remote() {
657 let json = r#"{
658 "traceId": "89143b0763095bd9c9955e8175d1fb23",
659 "spanId": "e342abb1214ca181",
660 "parentSpanId": "0c7a7dea069bf5a6",
661 "startTimeUnixNano": "123000000000",
662 "endTimeUnixNano": "123500000000",
663 "flags": 256
664 }"#;
665 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
666 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
667 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
668 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
669 {
670 "timestamp": 123.5,
671 "start_timestamp": 123.0,
672 "exclusive_time": 500.0,
673 "op": "default",
674 "span_id": "e342abb1214ca181",
675 "parent_span_id": "0c7a7dea069bf5a6",
676 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
677 "is_remote": false,
678 "status": "unknown",
679 "data": {},
680 "links": []
681 }
682 "###);
683 }
684
685 #[test]
686 fn extract_span_kind() {
687 let json = r#"{
688 "traceId": "89143b0763095bd9c9955e8175d1fb23",
689 "spanId": "e342abb1214ca181",
690 "parentSpanId": "0c7a7dea069bf5a6",
691 "startTimeUnixNano": "123000000000",
692 "endTimeUnixNano": "123500000000",
693 "kind": 3
694 }"#;
695 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
696 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
697 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
698 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
699 {
700 "timestamp": 123.5,
701 "start_timestamp": 123.0,
702 "exclusive_time": 500.0,
703 "op": "default",
704 "span_id": "e342abb1214ca181",
705 "parent_span_id": "0c7a7dea069bf5a6",
706 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
707 "status": "unknown",
708 "data": {},
709 "links": [],
710 "kind": "client"
711 }
712 "###);
713 }
714
715 #[test]
716 fn parse_link() {
717 let json = r#"{
718 "traceId": "3c79f60c11214eb38604f4ae0781bfb2",
719 "spanId": "e342abb1214ca181",
720 "links": [
721 {
722 "traceId": "4c79f60c11214eb38604f4ae0781bfb2",
723 "spanId": "fa90fdead5f74052",
724 "attributes": [
725 {
726 "key": "str_key",
727 "value": {
728 "stringValue": "str_value"
729 }
730 },
731 {
732 "key": "bool_key",
733 "value": {
734 "boolValue": true
735 }
736 },
737 {
738 "key": "int_key",
739 "value": {
740 "intValue": "123"
741 }
742 },
743 {
744 "key": "double_key",
745 "value": {
746 "doubleValue": 1.23
747 }
748 }
749 ],
750 "flags": 1
751 }
752 ]
753 }"#;
754 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
755 let event_span: EventSpan = otel_to_sentry_span(otel_span).unwrap();
756 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
757
758 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
759 {
760 "timestamp": 0.0,
761 "start_timestamp": 0.0,
762 "exclusive_time": 0.0,
763 "op": "default",
764 "span_id": "e342abb1214ca181",
765 "trace_id": "3c79f60c11214eb38604f4ae0781bfb2",
766 "status": "unknown",
767 "data": {},
768 "links": [
769 {
770 "trace_id": "4c79f60c11214eb38604f4ae0781bfb2",
771 "span_id": "fa90fdead5f74052",
772 "sampled": true,
773 "attributes": {
774 "bool_key": true,
775 "double_key": 1.23,
776 "int_key": 123,
777 "str_key": "str_value"
778 }
779 }
780 ]
781 }
782 "###);
783 }
784
785 #[test]
786 fn parse_span_error_status() {
787 let json = r#"{
788 "traceId": "89143b0763095bd9c9955e8175d1fb23",
789 "spanId": "e342abb1214ca181",
790 "status": {
791 "code": 2,
792 "message": "2 is the error status code"
793 }
794 }"#;
795 let otel_span: OtelSpan = serde_json::from_str(json).unwrap();
796 let event_span = otel_to_sentry_span(otel_span).unwrap();
797 let annotated_span: Annotated<EventSpan> = Annotated::new(event_span);
798 insta::assert_json_snapshot!(SerializableAnnotated(&annotated_span), @r###"
799 {
800 "timestamp": 0.0,
801 "start_timestamp": 0.0,
802 "exclusive_time": 0.0,
803 "op": "default",
804 "span_id": "e342abb1214ca181",
805 "trace_id": "89143b0763095bd9c9955e8175d1fb23",
806 "status": "internal_error",
807 "data": {
808 "sentry.status.message": "2 is the error status code"
809 },
810 "links": []
811 }
812 "###);
813 }
814}