sentry_backtrace/
integration.rs
1use std::thread;
2
3use sentry_core::protocol::{Event, Thread};
4use sentry_core::{ClientOptions, Integration};
5
6use crate::current_stacktrace;
7use crate::process::process_event_stacktrace;
8
9#[derive(Debug, Default)]
16pub struct ProcessStacktraceIntegration;
17
18impl ProcessStacktraceIntegration {
19 pub fn new() -> Self {
21 Self
22 }
23}
24
25impl Integration for ProcessStacktraceIntegration {
26 fn name(&self) -> &'static str {
27 "process-stacktrace"
28 }
29
30 fn process_event(
31 &self,
32 mut event: Event<'static>,
33 options: &ClientOptions,
34 ) -> Option<Event<'static>> {
35 for exc in &mut event.exception {
36 if let Some(ref mut stacktrace) = exc.stacktrace {
37 process_event_stacktrace(stacktrace, options);
38 }
39 }
40 for th in &mut event.threads {
41 if let Some(ref mut stacktrace) = th.stacktrace {
42 process_event_stacktrace(stacktrace, options);
43 }
44 }
45 if let Some(ref mut stacktrace) = event.stacktrace {
46 process_event_stacktrace(stacktrace, options);
47 }
48 Some(event)
49 }
50}
51
52#[derive(Debug, Default)]
57pub struct AttachStacktraceIntegration;
58
59impl AttachStacktraceIntegration {
60 pub fn new() -> Self {
62 Self
63 }
64}
65
66impl Integration for AttachStacktraceIntegration {
67 fn name(&self) -> &'static str {
68 "attach-stacktrace"
69 }
70
71 fn process_event(
72 &self,
73 mut event: Event<'static>,
74 options: &ClientOptions,
75 ) -> Option<Event<'static>> {
76 if options.attach_stacktrace && !has_stacktrace(&event) {
77 let thread = current_thread(true);
78 if thread.stacktrace.is_some() {
79 event.threads.values.push(thread);
80 }
81 }
82 Some(event)
83 }
84}
85
86fn has_stacktrace(event: &Event) -> bool {
87 event.stacktrace.is_some()
88 || event.exception.iter().any(|exc| exc.stacktrace.is_some())
89 || event.threads.iter().any(|thrd| thrd.stacktrace.is_some())
90}
91
92pub fn current_thread(with_stack: bool) -> Thread {
97 let thread_id: u64 = unsafe { std::mem::transmute(thread::current().id()) };
100 Thread {
101 id: Some(thread_id.to_string().into()),
102 name: thread::current().name().map(str::to_owned),
103 current: true,
104 stacktrace: if with_stack {
105 current_stacktrace()
106 } else {
107 None
108 },
109 ..Default::default()
110 }
111}