node: Log Panics
Register a panic handler that logs a backtrace via the `backtrace` crate, instead of setting `RUST_BACKTRACE`. Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xy>
This commit is contained in:
parent
0441b048f9
commit
ed8b086045
|
|
@ -2908,6 +2908,7 @@ name = "radicle-node"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"amplify",
|
"amplify",
|
||||||
|
"backtrace",
|
||||||
"bloomy",
|
"bloomy",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,13 @@ build = "build.rs"
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["systemd", "structured-logger"]
|
default = ["backtrace", "systemd", "structured-logger"]
|
||||||
systemd = ["dep:radicle-systemd"]
|
systemd = ["dep:radicle-systemd"]
|
||||||
test = ["radicle/test", "radicle-crypto/test", "radicle-crypto/cyphernet", "radicle-protocol/test", "qcheck", "snapbox"]
|
test = ["radicle/test", "radicle-crypto/test", "radicle-crypto/cyphernet", "radicle-protocol/test", "qcheck", "snapbox"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
amplify = { workspace = true }
|
amplify = { workspace = true }
|
||||||
|
backtrace = { version = "0.3.75", optional = true }
|
||||||
bloomy = "1.2"
|
bloomy = "1.2"
|
||||||
bytes = { workspace = true }
|
bytes = { workspace = true }
|
||||||
chrono = { workspace = true, features = ["clock"] }
|
chrono = { workspace = true, features = ["clock"] }
|
||||||
|
|
|
||||||
|
|
@ -300,15 +300,40 @@ fn initialize_logging(options: &LogOptions) -> Result<(), Box<dyn std::error::Er
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn panic_hook(info: &std::panic::PanicHookInfo) {
|
||||||
// If `RUST_BACKTRACE` does not have a value, then we set it to capture
|
#[cfg(feature = "backtrace")]
|
||||||
// backtraces for better debugging, otherwise we keep the environments
|
let backtrace = format!("{:?}", backtrace::Backtrace::new());
|
||||||
// value.
|
|
||||||
const RUST_BACKTRACE: &str = "RUST_BACKTRACE";
|
#[cfg(not(feature = "backtrace"))]
|
||||||
if std::env::var_os(RUST_BACKTRACE).is_none() {
|
let backtrace = " (no backtrace available)";
|
||||||
std::env::set_var(RUST_BACKTRACE, "1");
|
|
||||||
|
let thread = std::thread::current();
|
||||||
|
let thread = thread.name().unwrap_or("<unnamed>");
|
||||||
|
|
||||||
|
let msg = info
|
||||||
|
.payload()
|
||||||
|
.downcast_ref::<&'static str>()
|
||||||
|
.copied()
|
||||||
|
.or(info.payload().downcast_ref::<String>().map(|s| s.as_str()))
|
||||||
|
.unwrap_or("Box<Any>");
|
||||||
|
|
||||||
|
match info.location() {
|
||||||
|
Some(location) => {
|
||||||
|
log::error!(
|
||||||
|
target: "panic", "thread '{thread}' panicked at '{msg}': {}:{}{backtrace}",
|
||||||
|
location.file(),
|
||||||
|
location.line(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => log::error!(
|
||||||
|
target: "panic", "thread '{thread}' panicked at '{msg}'{backtrace}",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::logger().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
let options = parse_options().unwrap_or_else(|err| {
|
let options = parse_options().unwrap_or_else(|err| {
|
||||||
// The lexopt errors read nicely with a comma.
|
// The lexopt errors read nicely with a comma.
|
||||||
eprintln!("Failed to parse options, {err:#}");
|
eprintln!("Failed to parse options, {err:#}");
|
||||||
|
|
@ -320,6 +345,8 @@ fn main() {
|
||||||
exit(3);
|
exit(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::panic::set_hook(Box::new(panic_hook));
|
||||||
|
|
||||||
if let Err(err) = execute(options) {
|
if let Err(err) = execute(options) {
|
||||||
log::error!(target: "node", "{err:#}");
|
log::error!(target: "node", "{err:#}");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue