99//! setting up both is provided in the [crate-level documentation](../).
1010
1111use std:: collections:: HashMap ;
12- use std:: sync:: { Arc , Mutex } ;
12+ use std:: sync:: { Arc , LazyLock , Mutex } ;
1313use std:: time:: SystemTime ;
1414
1515use opentelemetry:: global:: ObjectSafeSpan ;
@@ -31,12 +31,12 @@ use crate::converters::{
3131/// to track OTEL spans across start/end calls.
3232type SpanMap = Arc < Mutex < HashMap < sentry_core:: protocol:: SpanId , TransactionOrSpan > > > ;
3333
34+ static SPAN_MAP : LazyLock < SpanMap > = LazyLock :: new ( || Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ) ;
35+
3436/// An OpenTelemetry SpanProcessor that converts OTEL spans to Sentry spans/transactions and sends
3537/// them to Sentry.
3638#[ derive( Debug , Clone ) ]
37- pub struct SentrySpanProcessor {
38- span_map : SpanMap ,
39- }
39+ pub struct SentrySpanProcessor { }
4040
4141impl SentrySpanProcessor {
4242 /// Creates a new `SentrySpanProcessor`.
@@ -46,10 +46,23 @@ impl SentrySpanProcessor {
4646 // This works as long as all Sentry spans/transactions are managed exclusively through OTEL APIs.
4747 scope. add_event_processor ( |mut event| {
4848 get_active_span ( |otel_span| {
49- let ( span_id, trace_id) = (
50- convert_span_id ( & otel_span. span_context ( ) . span_id ( ) ) ,
51- convert_trace_id ( & otel_span. span_context ( ) . trace_id ( ) ) ,
52- ) ;
49+ let span_map = SPAN_MAP . lock ( ) . unwrap ( ) ;
50+
51+ let Some ( sentry_span) =
52+ span_map. get ( & convert_span_id ( & otel_span. span_context ( ) . span_id ( ) ) )
53+ else {
54+ return ;
55+ } ;
56+
57+ let ( span_id, trace_id) = match sentry_span {
58+ TransactionOrSpan :: Transaction ( transaction) => (
59+ transaction. get_trace_context ( ) . span_id ,
60+ transaction. get_trace_context ( ) . trace_id ,
61+ ) ,
62+ TransactionOrSpan :: Span ( span) => {
63+ ( span. get_span_id ( ) , span. get_trace_context ( ) . trace_id )
64+ }
65+ } ;
5366
5467 if let Some ( sentry_core:: protocol:: Context :: Trace ( trace_context) ) =
5568 event. contexts . get_mut ( "trace" )
@@ -71,9 +84,7 @@ impl SentrySpanProcessor {
7184 Some ( event)
7285 } ) ;
7386 } ) ;
74- Self {
75- span_map : Default :: default ( ) ,
76- }
87+ Self { }
7788 }
7889}
7990
@@ -89,7 +100,7 @@ impl SpanProcessor for SentrySpanProcessor {
89100 let span_id = span. span_context ( ) . span_id ( ) ;
90101 let trace_id = span. span_context ( ) . trace_id ( ) ;
91102
92- let mut span_map = self . span_map . lock ( ) . unwrap ( ) ;
103+ let mut span_map = SPAN_MAP . lock ( ) . unwrap ( ) ;
93104
94105 let mut span_description = String :: new ( ) ;
95106 let mut span_op = String :: new ( ) ;
@@ -123,6 +134,7 @@ impl SpanProcessor for SentrySpanProcessor {
123134 span_description,
124135 span_op,
125136 sentry_trace,
137+ Some ( convert_span_id ( & span_id) ) ,
126138 )
127139 } else {
128140 // start a new trace
@@ -146,7 +158,7 @@ impl SpanProcessor for SentrySpanProcessor {
146158 fn on_end ( & self , data : SpanData ) {
147159 let span_id = data. span_context . span_id ( ) ;
148160
149- let mut span_map = self . span_map . lock ( ) . unwrap ( ) ;
161+ let mut span_map = SPAN_MAP . lock ( ) . unwrap ( ) ;
150162
151163 let Some ( sentry_span) = span_map. remove ( & convert_span_id ( & span_id) ) else {
152164 return ;
0 commit comments