@@ -11,16 +11,17 @@ use tracing_subscriber::registry::LookupSpan;
11
11
use super :: layer:: SentrySpanData ;
12
12
use crate :: TAGS_PREFIX ;
13
13
14
- /// Converts a [`tracing_core::Level`] to a Sentry [`Level`]
15
- fn convert_tracing_level ( level : & tracing_core:: Level ) -> Level {
16
- match level {
17
- & tracing_core:: Level :: TRACE | & tracing_core:: Level :: DEBUG => Level :: Debug ,
18
- & tracing_core:: Level :: INFO => Level :: Info ,
19
- & tracing_core:: Level :: WARN => Level :: Warning ,
20
- & tracing_core:: Level :: ERROR => Level :: Error ,
14
+ /// Converts a [`tracing_core::Level`] to a Sentry [`Level`].
15
+ fn level_to_sentry_level ( level : & tracing_core:: Level ) -> Level {
16
+ match * level {
17
+ tracing_core:: Level :: TRACE | tracing_core:: Level :: DEBUG => Level :: Debug ,
18
+ tracing_core:: Level :: INFO => Level :: Info ,
19
+ tracing_core:: Level :: WARN => Level :: Warning ,
20
+ tracing_core:: Level :: ERROR => Level :: Error ,
21
21
}
22
22
}
23
23
24
+ /// Converts a [`tracing_core::Level`] to the corresponding Sentry [`Exception::ty`] entry.
24
25
#[ allow( unused) ]
25
26
fn level_to_exception_type ( level : & tracing_core:: Level ) -> & ' static str {
26
27
match * level {
@@ -32,11 +33,16 @@ fn level_to_exception_type(level: &tracing_core::Level) -> &'static str {
32
33
}
33
34
}
34
35
35
- /// Extracts the message and metadata from an event
36
- /// and also optionally from its spans chain.
37
- fn extract_event_data ( event : & tracing_core:: Event ) -> ( Option < String > , FieldVisitor ) {
36
+ /// Extracts the message and metadata from an event.
37
+ fn extract_event_data (
38
+ event : & tracing_core:: Event ,
39
+ store_errors_in_values : bool ,
40
+ ) -> ( Option < String > , FieldVisitor ) {
38
41
// Find message of the event, if any
39
- let mut visitor = FieldVisitor :: default ( ) ;
42
+ let mut visitor = FieldVisitor {
43
+ store_errors_in_values,
44
+ ..Default :: default ( )
45
+ } ;
40
46
event. record ( & mut visitor) ;
41
47
let message = visitor
42
48
. json_values
@@ -52,14 +58,16 @@ fn extract_event_data(event: &tracing_core::Event) -> (Option<String>, FieldVisi
52
58
( message, visitor)
53
59
}
54
60
61
+ /// Extracts the message and metadata from an event, including the data in the current span.
55
62
fn extract_event_data_with_context < S > (
56
63
event : & tracing_core:: Event ,
57
64
ctx : Option < Context < S > > ,
65
+ store_errors_in_values : bool ,
58
66
) -> ( Option < String > , FieldVisitor )
59
67
where
60
68
S : Subscriber + for < ' a > LookupSpan < ' a > ,
61
69
{
62
- let ( message, mut visitor) = extract_event_data ( event) ;
70
+ let ( message, mut visitor) = extract_event_data ( event, store_errors_in_values ) ;
63
71
64
72
// Add the context fields of every parent span.
65
73
let current_span = ctx. as_ref ( ) . and_then ( |ctx| {
72
80
for span in span. scope ( ) {
73
81
let name = span. name ( ) ;
74
82
let ext = span. extensions ( ) ;
83
+
75
84
if let Some ( span_data) = ext. get :: < SentrySpanData > ( ) {
76
85
match & span_data. sentry_span {
77
86
TransactionOrSpan :: Span ( span) => {
@@ -98,11 +107,14 @@ where
98
107
( message, visitor)
99
108
}
100
109
101
- /// Records all fields of [`tracing_core::Event`] for easy access
110
+ /// Records the fields of a [`tracing_core::Event`].
102
111
#[ derive( Default ) ]
103
112
pub ( crate ) struct FieldVisitor {
104
- pub json_values : BTreeMap < String , Value > ,
105
- pub exceptions : Vec < Exception > ,
113
+ pub ( crate ) json_values : BTreeMap < String , Value > ,
114
+ pub ( crate ) exceptions : Vec < Exception > ,
115
+ /// If `true`, stringify and store errors in `self.json_values` under the original field name
116
+ /// else (default), convert to `Exception`s and store in `self.exceptions`.
117
+ store_errors_in_values : bool ,
106
118
}
107
119
108
120
impl FieldVisitor {
@@ -129,10 +141,20 @@ impl Visit for FieldVisitor {
129
141
self . record ( field, value) ;
130
142
}
131
143
132
- fn record_error ( & mut self , _field : & Field , value : & ( dyn Error + ' static ) ) {
144
+ fn record_error ( & mut self , field : & Field , value : & ( dyn Error + ' static ) ) {
133
145
let event = event_from_error ( value) ;
134
- for exception in event. exception {
135
- self . exceptions . push ( exception) ;
146
+ if self . store_errors_in_values {
147
+ let error_chain = event
148
+ . exception
149
+ . iter ( )
150
+ . rev ( )
151
+ . filter_map ( |x| x. value . as_ref ( ) . map ( |v| format ! ( "{}: {}" , x. ty, * v) ) )
152
+ . collect :: < Vec < String > > ( ) ;
153
+ self . record ( field, error_chain) ;
154
+ } else {
155
+ for exception in event. exception {
156
+ self . exceptions . push ( exception) ;
157
+ }
136
158
}
137
159
}
138
160
@@ -141,41 +163,28 @@ impl Visit for FieldVisitor {
141
163
}
142
164
}
143
165
144
- /// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`]
166
+ /// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`].
145
167
pub fn breadcrumb_from_event < ' context , S > (
146
168
event : & tracing_core:: Event ,
147
169
ctx : impl Into < Option < Context < ' context , S > > > ,
148
170
) -> Breadcrumb
149
171
where
150
172
S : Subscriber + for < ' a > LookupSpan < ' a > ,
151
173
{
152
- let ( message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) ) ;
153
-
154
- let FieldVisitor {
155
- exceptions,
156
- mut json_values,
157
- } = visitor;
158
-
159
- let errors = exceptions
160
- . iter ( )
161
- . rev ( )
162
- . filter_map ( |x| x. value . as_ref ( ) . map ( |v| format ! ( "{}: {}" , x. ty, * v) ) )
163
- . collect :: < Vec < String > > ( ) ;
164
- if !errors. is_empty ( ) {
165
- json_values. insert ( "errors" . to_owned ( ) , errors. into ( ) ) ;
166
- }
174
+ let ( message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) , true ) ;
167
175
168
176
Breadcrumb {
169
177
category : Some ( event. metadata ( ) . target ( ) . to_owned ( ) ) ,
170
178
ty : "log" . into ( ) ,
171
- level : convert_tracing_level ( event. metadata ( ) . level ( ) ) ,
179
+ level : level_to_sentry_level ( event. metadata ( ) . level ( ) ) ,
172
180
message,
173
- data : json_values,
181
+ data : visitor . json_values ,
174
182
..Default :: default ( )
175
183
}
176
184
}
177
185
178
- fn tags_from_event ( fields : & mut BTreeMap < String , Value > ) -> BTreeMap < String , String > {
186
+ /// Convert `tracing` fields to the corresponding Sentry tags, removing them from `fields`.
187
+ fn extract_and_remove_tags ( fields : & mut BTreeMap < String , Value > ) -> BTreeMap < String , String > {
179
188
let mut tags = BTreeMap :: new ( ) ;
180
189
181
190
fields. retain ( |key, value| {
@@ -200,6 +209,7 @@ fn tags_from_event(fields: &mut BTreeMap<String, Value>) -> BTreeMap<String, Str
200
209
tags
201
210
}
202
211
212
+ /// Create Sentry Contexts out of the `tracing` event and fields.
203
213
fn contexts_from_event (
204
214
event : & tracing_core:: Event ,
205
215
fields : BTreeMap < String , Value > ,
@@ -232,7 +242,7 @@ fn contexts_from_event(
232
242
context
233
243
}
234
244
235
- /// Creates an [`Event`] (possibly carrying an exception ) from a given [`tracing_core::Event`]
245
+ /// Creates an [`Event`] (possibly carrying exceptions ) from a given [`tracing_core::Event`].
236
246
pub fn event_from_event < ' context , S > (
237
247
event : & tracing_core:: Event ,
238
248
ctx : impl Into < Option < Context < ' context , S > > > ,
@@ -245,10 +255,11 @@ where
245
255
// information for this. However, it may contain a serialized error which we can parse to emit
246
256
// an exception record.
247
257
#[ allow( unused_mut) ]
248
- let ( mut message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) ) ;
258
+ let ( mut message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) , false ) ;
249
259
let FieldVisitor {
250
260
mut exceptions,
251
261
mut json_values,
262
+ store_errors_in_values : _,
252
263
} = visitor;
253
264
254
265
// If there are a message, an exception, and we are capturing stack traces, then add the message
@@ -289,10 +300,10 @@ where
289
300
290
301
Event {
291
302
logger : Some ( event. metadata ( ) . target ( ) . to_owned ( ) ) ,
292
- level : convert_tracing_level ( event. metadata ( ) . level ( ) ) ,
303
+ level : level_to_sentry_level ( event. metadata ( ) . level ( ) ) ,
293
304
message,
294
305
exception : exceptions. into ( ) ,
295
- tags : tags_from_event ( & mut json_values) ,
306
+ tags : extract_and_remove_tags ( & mut json_values) ,
296
307
contexts : contexts_from_event ( event, json_values) ,
297
308
..Default :: default ( )
298
309
}
0 commit comments