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
use std::backtrace::Backtrace;
use std::panic::PanicInfo;
use cfg_if::cfg_if;
use tracing::error;
use tracing_error::SpanTrace;
#[allow(clippy::needless_pass_by_value)]
pub fn setup(tag: impl ToString) {
cfg_if! {
if #[cfg(target_os = "android")] {
paranoid_android::init(tag);
} else {
let env = format!("LOG_{}", tag.to_string().to_ascii_uppercase());
let filter = tracing_subscriber::filter::EnvFilter::from_env(env);
tracing_subscriber::fmt().with_env_filter(filter).init();
}
}
std::panic::set_hook(panic_hook(true, true));
}
pub fn panic_hook(
backtrace: bool,
spantrace: bool,
) -> Box<dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static> {
Box::new(move |info| {
let location = info.location().unwrap();
let msg = match info.payload().downcast_ref::<&'static str>() {
Some(s) => *s,
None => match info.payload().downcast_ref::<String>() {
Some(s) => &s[..],
None => "Box<dyn Any>",
},
};
error!(target: "panic", "panicked at '{}', {}", msg, location);
if backtrace {
error!(target: "panic", "{:?}", Backtrace::force_capture());
}
if spantrace {
error!(target: "panic", "{:?}", SpanTrace::capture());
}
})
}