@@ -2,7 +2,11 @@ use std::collections::BTreeMap;
2
2
use std:: error:: Error ;
3
3
4
4
use sentry_core:: protocol:: { Event , Exception , Mechanism , Value } ;
5
+ #[ cfg( feature = "logs" ) ]
6
+ use sentry_core:: protocol:: { Log , LogAttribute , LogLevel } ;
5
7
use sentry_core:: { event_from_error, Breadcrumb , Level , TransactionOrSpan } ;
8
+ #[ cfg( feature = "logs" ) ]
9
+ use std:: time:: SystemTime ;
6
10
use tracing_core:: field:: { Field , Visit } ;
7
11
use tracing_core:: Subscriber ;
8
12
use tracing_subscriber:: layer:: Context ;
@@ -11,7 +15,7 @@ use tracing_subscriber::registry::LookupSpan;
11
15
use super :: layer:: SentrySpanData ;
12
16
use crate :: TAGS_PREFIX ;
13
17
14
- /// Converts a [`tracing_core::Level`] to a Sentry [`Level`].
18
+ /// Converts a [`tracing_core::Level`] to a Sentry [`Level`], used for events and breadcrumbs .
15
19
fn level_to_sentry_level ( level : & tracing_core:: Level ) -> Level {
16
20
match * level {
17
21
tracing_core:: Level :: TRACE | tracing_core:: Level :: DEBUG => Level :: Debug ,
@@ -21,6 +25,18 @@ fn level_to_sentry_level(level: &tracing_core::Level) -> Level {
21
25
}
22
26
}
23
27
28
+ /// Converts a [`tracing_core::Level`] to a Sentry [`LogLevel`], used for logs.
29
+ #[ cfg( feature = "logs" ) ]
30
+ fn level_to_log_level ( level : & tracing_core:: Level ) -> LogLevel {
31
+ match * level {
32
+ tracing_core:: Level :: TRACE => LogLevel :: Trace ,
33
+ tracing_core:: Level :: DEBUG => LogLevel :: Debug ,
34
+ tracing_core:: Level :: INFO => LogLevel :: Info ,
35
+ tracing_core:: Level :: WARN => LogLevel :: Warn ,
36
+ tracing_core:: Level :: ERROR => LogLevel :: Error ,
37
+ }
38
+ }
39
+
24
40
/// Converts a [`tracing_core::Level`] to the corresponding Sentry [`Exception::ty`] entry.
25
41
#[ allow( unused) ]
26
42
fn level_to_exception_type ( level : & tracing_core:: Level ) -> & ' static str {
@@ -308,3 +324,43 @@ where
308
324
..Default :: default ( )
309
325
}
310
326
}
327
+
328
+ /// Creates a [`Log`] from a given [`tracing_core::Event`]
329
+ #[ cfg( feature = "logs" ) ]
330
+ pub fn log_from_event < ' context , S > (
331
+ event : & tracing_core:: Event ,
332
+ ctx : impl Into < Option < Context < ' context , S > > > ,
333
+ ) -> Log
334
+ where
335
+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
336
+ {
337
+ let ( message, visitor) = extract_event_data_with_context ( event, ctx. into ( ) , true ) ;
338
+
339
+ let mut attributes: BTreeMap < String , LogAttribute > = visitor
340
+ . json_values
341
+ . into_iter ( )
342
+ . map ( |( key, val) | ( key, val. into ( ) ) )
343
+ . collect ( ) ;
344
+
345
+ let event_meta = event. metadata ( ) ;
346
+ if let Some ( module_path) = event_meta. module_path ( ) {
347
+ attributes. insert ( "tracing.module_path" . to_owned ( ) , module_path. into ( ) ) ;
348
+ }
349
+ if let Some ( file) = event_meta. file ( ) {
350
+ attributes. insert ( "tracing.file" . to_owned ( ) , file. into ( ) ) ;
351
+ }
352
+ if let Some ( line) = event_meta. line ( ) {
353
+ attributes. insert ( "tracing.line" . to_owned ( ) , line. into ( ) ) ;
354
+ }
355
+
356
+ attributes. insert ( "sentry.origin" . to_owned ( ) , "auto.tracing" . into ( ) ) ;
357
+
358
+ Log {
359
+ level : level_to_log_level ( event. metadata ( ) . level ( ) ) ,
360
+ body : message. unwrap_or_default ( ) ,
361
+ trace_id : None ,
362
+ timestamp : SystemTime :: now ( ) ,
363
+ severity_number : None ,
364
+ attributes,
365
+ }
366
+ }
0 commit comments