@@ -9,7 +9,7 @@ use tracing_subscriber::layer::Context;
9
9
use tracing_subscriber:: registry:: LookupSpan ;
10
10
11
11
use super :: layer:: SentrySpanData ;
12
- use crate :: TAGS_PREFIX ;
12
+ use crate :: { SpanPropagation , TAGS_PREFIX } ;
13
13
14
14
/// Converts a [`tracing_core::Level`] to a Sentry [`Level`]
15
15
fn convert_tracing_level ( level : & tracing_core:: Level ) -> Level {
@@ -54,39 +54,55 @@ fn extract_event_data(event: &tracing_core::Event) -> (Option<String>, FieldVisi
54
54
55
55
fn extract_event_data_with_context < S > (
56
56
event : & tracing_core:: Event ,
57
- ctx : Option < Context < S > > ,
57
+ ctx : Context < S > ,
58
+ propagation : Option < SpanPropagation > ,
58
59
) -> ( Option < String > , FieldVisitor )
59
60
where
60
61
S : Subscriber + for < ' a > LookupSpan < ' a > ,
61
62
{
62
63
let ( message, mut visitor) = extract_event_data ( event) ;
63
64
64
- // Add the context fields of every parent span.
65
- let current_span = ctx . as_ref ( ) . and_then ( |ctx | {
65
+ // Add the context fields of every parent span, if propagation is enabled
66
+ let propagation_span = propagation . and_then ( |propagation | {
66
67
event
67
68
. parent ( )
68
- . and_then ( |id| ctx. span ( id) )
69
- . or_else ( || ctx. lookup_current ( ) )
69
+ . and_then ( |id| ctx. span ( id) . map ( |span| ( propagation , span ) ) )
70
+ . or_else ( || ctx. lookup_current ( ) . map ( |span| ( propagation , span ) ) )
70
71
} ) ;
71
- if let Some ( span) = current_span {
72
+ if let Some ( ( propagation , span) ) = propagation_span {
72
73
for span in span. scope ( ) {
73
74
let name = span. name ( ) ;
74
75
let ext = span. extensions ( ) ;
75
76
if let Some ( span_data) = ext. get :: < SentrySpanData > ( ) {
76
77
match & span_data. sentry_span {
77
78
TransactionOrSpan :: Span ( span) => {
78
- for ( key, value) in span. data ( ) . iter ( ) {
79
- if key != "message" {
80
- let key = format ! ( "{}:{}" , name, key) ;
81
- visitor. json_values . insert ( key, value. clone ( ) ) ;
79
+ let tags = span. tags ( ) ;
80
+
81
+ if propagation. is_tags_enabled ( ) {
82
+ for ( key, value) in tags. iter ( ) {
83
+ visitor. propagate_span_tag ( key, value) ;
84
+ }
85
+ }
86
+
87
+ if propagation. is_attrs_enabled ( ) {
88
+ for ( key, value) in tags. into_data ( ) . iter ( ) {
89
+ visitor. propagate_span_attr ( key, value, name) ;
82
90
}
83
91
}
84
92
}
85
93
TransactionOrSpan :: Transaction ( transaction) => {
86
- for ( key, value) in transaction. data ( ) . iter ( ) {
87
- if key != "message" {
88
- let key = format ! ( "{}:{}" , name, key) ;
89
- visitor. json_values . insert ( key, value. clone ( ) ) ;
94
+ let tags = transaction. tags ( ) ;
95
+ if propagation. is_tags_enabled ( ) {
96
+ if let Some ( tags) = tags. iter ( ) {
97
+ for ( key, value) in tags {
98
+ visitor. propagate_span_tag ( key, value) ;
99
+ }
100
+ }
101
+ }
102
+
103
+ if propagation. is_attrs_enabled ( ) {
104
+ for ( key, value) in tags. into_data ( ) . iter ( ) {
105
+ visitor. propagate_span_attr ( key, value, name) ;
90
106
}
91
107
}
92
108
}
@@ -106,6 +122,19 @@ pub(crate) struct FieldVisitor {
106
122
}
107
123
108
124
impl FieldVisitor {
125
+ fn propagate_span_tag ( & mut self , key : & str , value : & str ) {
126
+ //Propagate tags as it is, it will be extracted later on
127
+ let tag = format ! ( "{TAGS_PREFIX}{key}" ) ;
128
+ self . json_values . entry ( tag) . or_insert_with ( || value. into ( ) ) ;
129
+ }
130
+
131
+ fn propagate_span_attr ( & mut self , key : & str , value : & Value , span_name : & str ) {
132
+ if key != "message" {
133
+ let key = format ! ( "{}:{}" , span_name, key) ;
134
+ self . json_values . insert ( key, value. clone ( ) ) ;
135
+ }
136
+ }
137
+
109
138
fn record < T : Into < Value > > ( & mut self , field : & Field , value : T ) {
110
139
self . json_values
111
140
. insert ( field. name ( ) . to_owned ( ) , value. into ( ) ) ;
@@ -144,12 +173,19 @@ impl Visit for FieldVisitor {
144
173
/// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`]
145
174
pub fn breadcrumb_from_event < ' context , S > (
146
175
event : & tracing_core:: Event ,
147
- ctx : impl Into < Option < Context < ' context , S > > > ,
176
+ ctx : Context < ' context , S > ,
177
+ mut propagation : Option < SpanPropagation > ,
148
178
) -> Breadcrumb
149
179
where
150
180
S : Subscriber + for < ' a > LookupSpan < ' a > ,
151
181
{
152
- let ( message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) ) ;
182
+ if let Some ( propagation) = propagation. as_mut ( ) {
183
+ if propagation. is_attrs_enabled ( ) {
184
+ //Breadcrumb has no tags, so propagate only attributes
185
+ * propagation = SpanPropagation :: Attributes ;
186
+ }
187
+ }
188
+ let ( message, visitor) = extract_event_data_with_context ( event, ctx, propagation) ;
153
189
154
190
let FieldVisitor {
155
191
exceptions,
@@ -232,10 +268,11 @@ fn contexts_from_event(
232
268
context
233
269
}
234
270
235
- /// Creates an [`Event`] (possibly carrying an exception) from a given [`tracing_core::Event`]
271
+ /// Creates an [`Event`] from a given [`tracing_core::Event`]
236
272
pub fn event_from_event < ' context , S > (
237
273
event : & tracing_core:: Event ,
238
- ctx : impl Into < Option < Context < ' context , S > > > ,
274
+ ctx : Context < ' context , S > ,
275
+ propagation : Option < SpanPropagation > ,
239
276
) -> Event < ' static >
240
277
where
241
278
S : Subscriber + for < ' a > LookupSpan < ' a > ,
@@ -245,7 +282,7 @@ where
245
282
// information for this. However, it may contain a serialized error which we can parse to emit
246
283
// an exception record.
247
284
#[ allow( unused_mut) ]
248
- let ( mut message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) ) ;
285
+ let ( mut message, visitor) = extract_event_data_with_context ( event, ctx, propagation ) ;
249
286
let FieldVisitor {
250
287
mut exceptions,
251
288
mut json_values,
0 commit comments