9
9
//! setting up both is provided in the [crate-level documentation](../).
10
10
11
11
use std:: collections:: HashMap ;
12
- use std:: sync:: { Arc , Mutex } ;
12
+ use std:: sync:: { Arc , LazyLock , Mutex } ;
13
13
use std:: time:: SystemTime ;
14
14
15
15
use opentelemetry:: global:: ObjectSafeSpan ;
@@ -31,12 +31,12 @@ use crate::converters::{
31
31
/// to track OTEL spans across start/end calls.
32
32
type SpanMap = Arc < Mutex < HashMap < sentry_core:: protocol:: SpanId , TransactionOrSpan > > > ;
33
33
34
+ static SPAN_MAP : LazyLock < SpanMap > = LazyLock :: new ( || Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ) ;
35
+
34
36
/// An OpenTelemetry SpanProcessor that converts OTEL spans to Sentry spans/transactions and sends
35
37
/// them to Sentry.
36
38
#[ derive( Debug , Clone ) ]
37
- pub struct SentrySpanProcessor {
38
- span_map : SpanMap ,
39
- }
39
+ pub struct SentrySpanProcessor { }
40
40
41
41
impl SentrySpanProcessor {
42
42
/// Creates a new `SentrySpanProcessor`.
@@ -46,10 +46,23 @@ impl SentrySpanProcessor {
46
46
// This works as long as all Sentry spans/transactions are managed exclusively through OTEL APIs.
47
47
scope. add_event_processor ( |mut event| {
48
48
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
+ } ;
53
66
54
67
if let Some ( sentry_core:: protocol:: Context :: Trace ( trace_context) ) =
55
68
event. contexts . get_mut ( "trace" )
@@ -71,9 +84,7 @@ impl SentrySpanProcessor {
71
84
Some ( event)
72
85
} ) ;
73
86
} ) ;
74
- Self {
75
- span_map : Default :: default ( ) ,
76
- }
87
+ Self { }
77
88
}
78
89
}
79
90
@@ -89,7 +100,7 @@ impl SpanProcessor for SentrySpanProcessor {
89
100
let span_id = span. span_context ( ) . span_id ( ) ;
90
101
let trace_id = span. span_context ( ) . trace_id ( ) ;
91
102
92
- let mut span_map = self . span_map . lock ( ) . unwrap ( ) ;
103
+ let mut span_map = SPAN_MAP . lock ( ) . unwrap ( ) ;
93
104
94
105
let mut span_description = String :: new ( ) ;
95
106
let mut span_op = String :: new ( ) ;
@@ -123,6 +134,7 @@ impl SpanProcessor for SentrySpanProcessor {
123
134
span_description,
124
135
span_op,
125
136
sentry_trace,
137
+ Some ( convert_span_id ( & span_id) ) ,
126
138
)
127
139
} else {
128
140
// start a new trace
@@ -146,7 +158,7 @@ impl SpanProcessor for SentrySpanProcessor {
146
158
fn on_end ( & self , data : SpanData ) {
147
159
let span_id = data. span_context . span_id ( ) ;
148
160
149
- let mut span_map = self . span_map . lock ( ) . unwrap ( ) ;
161
+ let mut span_map = SPAN_MAP . lock ( ) . unwrap ( ) ;
150
162
151
163
let Some ( sentry_span) = span_map. remove ( & convert_span_id ( & span_id) ) else {
152
164
return ;
0 commit comments