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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use sentry_core::protocol::Breadcrumb;
use tracing_core::{Event, Level, Metadata, Subscriber};
use tracing_subscriber::layer::{Context, Layer};
use crate::converters::*;
#[derive(Debug, Clone, Copy)]
pub enum EventFilter {
Ignore,
Breadcrumb,
Event,
Exception,
}
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum EventMapping {
Ignore,
Breadcrumb(Breadcrumb),
Event(sentry_core::protocol::Event<'static>),
}
pub fn default_filter(metadata: &Metadata) -> EventFilter {
match metadata.level() {
&Level::ERROR => EventFilter::Exception,
&Level::WARN | &Level::INFO => EventFilter::Breadcrumb,
&Level::DEBUG | &Level::TRACE => EventFilter::Ignore,
}
}
pub struct SentryLayer {
filter: Box<dyn Fn(&Metadata) -> EventFilter + Send + Sync>,
mapper: Option<Box<dyn Fn(&Event) -> EventMapping + Send + Sync>>,
}
impl SentryLayer {
pub fn filter<F>(mut self, filter: F) -> Self
where
F: Fn(&Metadata) -> EventFilter + Send + Sync + 'static,
{
self.filter = Box::new(filter);
self
}
pub fn mapper<F>(mut self, mapper: F) -> Self
where
F: Fn(&Event) -> EventMapping + Send + Sync + 'static,
{
self.mapper = Some(Box::new(mapper));
self
}
}
impl Default for SentryLayer {
fn default() -> Self {
Self {
filter: Box::new(default_filter),
mapper: None,
}
}
}
impl<S: Subscriber> Layer<S> for SentryLayer {
fn on_event(&self, event: &Event, _ctx: Context<'_, S>) {
let item = match &self.mapper {
Some(mapper) => mapper(event),
None => match (self.filter)(event.metadata()) {
EventFilter::Ignore => EventMapping::Ignore,
EventFilter::Breadcrumb => EventMapping::Breadcrumb(breadcrumb_from_event(event)),
EventFilter::Event => EventMapping::Event(event_from_event(event)),
EventFilter::Exception => EventMapping::Event(exception_from_event(event)),
},
};
match item {
EventMapping::Event(event) => {
sentry_core::capture_event(event);
}
EventMapping::Breadcrumb(breadcrumb) => sentry_core::add_breadcrumb(breadcrumb),
_ => (),
}
}
}
pub fn layer() -> SentryLayer {
Default::default()
}