forked from graphprotocol/graph-node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.rs
More file actions
105 lines (97 loc) · 3.5 KB
/
Copy pathlog.rs
File metadata and controls
105 lines (97 loc) · 3.5 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use backtrace::Backtrace;
use futures::sync::oneshot;
use slog::{crit, debug, o, Drain, FilterLevel, Logger};
use slog_async;
use slog_envlogger;
use slog_term;
use std::sync::Mutex;
use std::time::Duration;
use std::{env, panic, process, thread};
pub const MAPPING_THREAD_PREFIX: &str = "mapping-thread";
pub fn logger(show_debug: bool) -> Logger {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
let drain = slog_envlogger::LogBuilder::new(drain)
.filter(
None,
if show_debug {
FilterLevel::Debug
} else {
FilterLevel::Info
},
)
.parse(
env::var_os("GRAPH_LOG")
.unwrap_or_else(|| "".into())
.to_str()
.unwrap(),
)
.build();
let drain = slog_async::Async::new(drain).build().fuse();
Logger::root(drain, o!())
}
pub fn guarded_logger() -> (Logger, slog_async::AsyncGuard) {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
let (drain, guard) = slog_async::Async::new(drain).build_with_guard();
(Logger::root(drain.fuse(), o!()), guard)
}
pub fn register_panic_hook(panic_logger: Logger, shutdown_sender: oneshot::Sender<()>) {
let shutdown_mutex = Mutex::new(Some(shutdown_sender));
panic::set_hook(Box::new(move |panic_info| {
let panic_payload = panic_info
.payload()
.downcast_ref::<String>()
.cloned()
.or_else(|| {
panic_info
.payload()
.downcast_ref::<&str>()
.map(|s| s.to_string())
});
let panic_location = if let Some(location) = panic_info.location() {
format!("{}:{}", location.file(), location.line().to_string())
} else {
"NA".to_string()
};
match env::var_os("RUST_BACKTRACE") {
Some(ref val) if val != "0" => {
crit!(
panic_logger, "{}", panic_payload.unwrap();
"location" => &panic_location,
"backtrace" => format!("{:?}", Backtrace::new()),
);
}
_ => {
crit!(
panic_logger, "{}", panic_payload.unwrap();
"location" => &panic_location,
);
}
};
// Don't kill the process when a mapping thread panics.
if thread::current()
.name()
.filter(|name| name.starts_with(MAPPING_THREAD_PREFIX))
.is_some()
{
return;
}
// Send a shutdown signal to main which will attempt to cleanly shutdown the runtime
// After sending shutdown, the thread sleeps for 3 seconds then forces the process to
// exit because the shutdown is not always able to cleanly exit all workers
match shutdown_mutex.lock().unwrap().take() {
Some(sender) => sender
.send(())
.map(|_| ())
.map_err(|_| {
crit!(panic_logger, "Failed to send shutdown signal");
()
})
.unwrap_or(()),
None => debug!(panic_logger, "Shutdown signal already sent"),
}
thread::sleep(Duration::from_millis(3000));
process::exit(1);
}));
}