common_telemetry/
panic_hook.rs1use std::panic;
16#[cfg(feature = "deadlock_detection")]
17use std::time::Duration;
18
19use backtrace::Backtrace;
20use lazy_static::lazy_static;
21use prometheus::*;
22
23lazy_static! {
24 pub static ref PANIC_COUNTER: IntCounter =
25 register_int_counter!("greptime_panic_counter", "panic_counter").unwrap();
26}
27
28pub fn set_panic_hook() {
29 let default_hook = panic::take_hook();
36 panic::set_hook(Box::new(move |panic| {
37 let backtrace = Backtrace::new();
38 let backtrace = format!("{backtrace:?}");
39 if let Some(location) = panic.location() {
40 tracing::error!(
41 message = %panic,
42 backtrace = %backtrace,
43 panic.file = location.file(),
44 panic.line = location.line(),
45 panic.column = location.column(),
46 );
47 } else {
48 tracing::error!(message = %panic, backtrace = %backtrace);
49 }
50 PANIC_COUNTER.inc();
51 default_hook(panic);
52 }));
53
54 #[cfg(feature = "deadlock_detection")]
55 let _ = std::thread::spawn(move || {
56 loop {
57 std::thread::sleep(Duration::from_secs(5));
58 let deadlocks = parking_lot::deadlock::check_deadlock();
59 if deadlocks.is_empty() {
60 continue;
61 }
62
63 tracing::info!("{} deadlocks detected", deadlocks.len());
64 for (i, threads) in deadlocks.iter().enumerate() {
65 tracing::info!("Deadlock #{}", i);
66 for t in threads {
67 tracing::info!("Thread Id {:#?}", t.thread_id());
68 tracing::info!("{:#?}", t.backtrace());
69 }
70 }
71 }
72 });
73}