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
#![doc(html_root_url = "https://docs.rs/log-panics/2.0.0")]
#![warn(missing_docs)]
#[macro_use]
extern crate log;
#[cfg(feature = "with-backtrace")]
extern crate backtrace;
use std::fmt;
use std::panic;
use std::thread;
use backtrace::Backtrace;
#[cfg(not(feature = "with-backtrace"))]
mod backtrace {
pub struct Backtrace;
impl Backtrace {
pub fn new() -> Backtrace {
Backtrace
}
}
}
struct Shim(Backtrace);
impl fmt::Debug for Shim {
#[cfg(feature = "with-backtrace")]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "\n{:?}", self.0)
}
#[cfg(not(feature = "with-backtrace"))]
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
Ok(())
}
}
pub fn init() {
panic::set_hook(Box::new(|info| {
let backtrace = Backtrace::new();
let thread = thread::current();
let thread = thread.name().unwrap_or("unnamed");
let msg = match info.payload().downcast_ref::<&'static str>() {
Some(s) => *s,
None => match info.payload().downcast_ref::<String>() {
Some(s) => &**s,
None => "Box<Any>",
},
};
match info.location() {
Some(location) => {
error!(
target: "panic", "thread '{}' panicked at '{}': {}:{}{:?}",
thread,
msg,
location.file(),
location.line(),
Shim(backtrace)
);
}
None => {
error!(
target: "panic",
"thread '{}' panicked at '{}'{:?}",
thread,
msg,
Shim(backtrace)
)
}
}
}));
}