1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::collections::BTreeMap;
use sentry_core::protocol::{Event, Value};
use sentry_core::{Breadcrumb, Level};
use tracing_core::field::{Field, Visit};
pub fn convert_tracing_level(level: &tracing_core::Level) -> Level {
match level {
&tracing_core::Level::TRACE | &tracing_core::Level::DEBUG => Level::Debug,
&tracing_core::Level::INFO => Level::Info,
&tracing_core::Level::WARN => Level::Warning,
&tracing_core::Level::ERROR => Level::Error,
}
}
pub fn extract_data(event: &tracing_core::Event) -> (Option<String>, BTreeMap<String, Value>) {
let mut data = BTreeMapRecorder::default();
event.record(&mut data);
let message = data
.0
.remove("message")
.map(|v| v.as_str().map(|s| s.to_owned()))
.flatten();
(message, data.0)
}
#[derive(Default)]
struct BTreeMapRecorder(pub BTreeMap<String, Value>);
impl BTreeMapRecorder {
fn record<T: Into<Value>>(&mut self, field: &Field, value: T) {
self.0.insert(field.name().to_owned(), value.into());
}
}
impl Visit for BTreeMapRecorder {
fn record_debug(&mut self, field: &Field, value: &dyn std::fmt::Debug) {
self.record(field, format!("{:?}", value));
}
fn record_i64(&mut self, field: &Field, value: i64) {
self.record(field, value);
}
fn record_u64(&mut self, field: &Field, value: u64) {
self.record(field, value);
}
fn record_bool(&mut self, field: &Field, value: bool) {
self.record(field, value);
}
fn record_str(&mut self, field: &Field, value: &str) {
self.record(field, value);
}
}
pub fn breadcrumb_from_event(event: &tracing_core::Event) -> Breadcrumb {
let (message, data) = extract_data(event);
Breadcrumb {
category: Some(event.metadata().target().to_owned()),
ty: "log".into(),
level: convert_tracing_level(event.metadata().level()),
message,
data,
..Default::default()
}
}
pub fn event_from_event(event: &tracing_core::Event) -> Event<'static> {
let (message, extra) = extract_data(event);
Event {
logger: Some(event.metadata().target().to_owned()),
level: convert_tracing_level(event.metadata().level()),
message,
extra,
..Default::default()
}
}
pub fn exception_from_event(event: &tracing_core::Event) -> Event<'static> {
event_from_event(event)
}