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