@@ -2,12 +2,14 @@ use std::collections::BTreeMap;
2
2
use std:: error:: Error ;
3
3
4
4
use sentry_core:: protocol:: { Event , Exception , Mechanism , Thread , Value } ;
5
- use sentry_core:: { event_from_error, Breadcrumb , Level } ;
5
+ use sentry_core:: { event_from_error, Breadcrumb , Level , TransactionOrSpan } ;
6
6
use tracing_core:: field:: { Field , Visit } ;
7
7
use tracing_core:: { span, Subscriber } ;
8
8
use tracing_subscriber:: layer:: Context ;
9
9
use tracing_subscriber:: registry:: LookupSpan ;
10
10
11
+ use super :: layer:: SentrySpanData ;
12
+
11
13
/// Converts a [`tracing_core::Level`] to a Sentry [`Level`]
12
14
fn convert_tracing_level ( level : & tracing_core:: Level ) -> Level {
13
15
match level {
@@ -29,6 +31,7 @@ fn level_to_exception_type(level: &tracing_core::Level) -> &'static str {
29
31
}
30
32
31
33
/// Extracts the message and metadata from an event
34
+ /// and also optionally from its spans chain.
32
35
fn extract_event_data ( event : & tracing_core:: Event ) -> ( Option < String > , FieldVisitor ) {
33
36
// Find message of the event, if any
34
37
let mut visitor = FieldVisitor :: default ( ) ;
@@ -44,6 +47,52 @@ fn extract_event_data(event: &tracing_core::Event) -> (Option<String>, FieldVisi
44
47
( message, visitor)
45
48
}
46
49
50
+ fn extract_event_data_with_context < S > (
51
+ event : & tracing_core:: Event ,
52
+ ctx : Option < Context < S > > ,
53
+ ) -> ( Option < String > , FieldVisitor )
54
+ where
55
+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
56
+ {
57
+ let ( message, mut visitor) = extract_event_data ( event) ;
58
+
59
+ // Add the context fields of every parent span.
60
+ let current_span = ctx. as_ref ( ) . and_then ( |ctx| {
61
+ event
62
+ . parent ( )
63
+ . and_then ( |id| ctx. span ( id) )
64
+ . or_else ( || ctx. lookup_current ( ) )
65
+ } ) ;
66
+ if let Some ( span) = current_span {
67
+ for span in span. scope ( ) {
68
+ let name = span. name ( ) ;
69
+ let ext = span. extensions ( ) ;
70
+ if let Some ( span_data) = ext. get :: < SentrySpanData > ( ) {
71
+ match & span_data. sentry_span {
72
+ TransactionOrSpan :: Span ( span) => {
73
+ for ( key, value) in span. data ( ) . iter ( ) {
74
+ if key != "message" {
75
+ let key = format ! ( "{}:{}" , name, key) ;
76
+ visitor. json_values . insert ( key, value. clone ( ) ) ;
77
+ }
78
+ }
79
+ }
80
+ TransactionOrSpan :: Transaction ( transaction) => {
81
+ for ( key, value) in transaction. data ( ) . iter ( ) {
82
+ if key != "message" {
83
+ let key = format ! ( "{}:{}" , name, key) ;
84
+ visitor. json_values . insert ( key, value. clone ( ) ) ;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ ( message, visitor)
94
+ }
95
+
47
96
/// Extracts the message and metadata from a span
48
97
pub ( crate ) fn extract_span_data (
49
98
attrs : & span:: Attributes ,
@@ -174,11 +223,14 @@ fn contexts_from_event(
174
223
}
175
224
176
225
/// Creates an [`Event`] from a given [`tracing_core::Event`]
177
- pub fn event_from_event < S > ( event : & tracing_core:: Event , _ctx : Context < S > ) -> Event < ' static >
226
+ pub fn event_from_event < ' context , S > (
227
+ event : & tracing_core:: Event ,
228
+ ctx : impl Into < Option < Context < ' context , S > > > ,
229
+ ) -> Event < ' static >
178
230
where
179
231
S : Subscriber + for < ' a > LookupSpan < ' a > ,
180
232
{
181
- let ( message, mut visitor) = extract_event_data ( event) ;
233
+ let ( message, mut visitor) = extract_event_data_with_context ( event, ctx . into ( ) ) ;
182
234
183
235
Event {
184
236
logger : Some ( event. metadata ( ) . target ( ) . to_owned ( ) ) ,
@@ -191,15 +243,18 @@ where
191
243
}
192
244
193
245
/// Creates an exception [`Event`] from a given [`tracing_core::Event`]
194
- pub fn exception_from_event < S > ( event : & tracing_core:: Event , _ctx : Context < S > ) -> Event < ' static >
246
+ pub fn exception_from_event < ' context , S > (
247
+ event : & tracing_core:: Event ,
248
+ ctx : impl Into < Option < Context < ' context , S > > > ,
249
+ ) -> Event < ' static >
195
250
where
196
251
S : Subscriber + for < ' a > LookupSpan < ' a > ,
197
252
{
198
253
// Exception records in Sentry need a valid type, value and full stack trace to support
199
254
// proper grouping and issue metadata generation. tracing_core::Record does not contain sufficient
200
255
// information for this. However, it may contain a serialized error which we can parse to emit
201
256
// an exception record.
202
- let ( mut message, visitor) = extract_event_data ( event) ;
257
+ let ( mut message, visitor) = extract_event_data_with_context ( event, ctx . into ( ) ) ;
203
258
let FieldVisitor {
204
259
mut exceptions,
205
260
mut json_values,
0 commit comments