fix(otel): flush data when terminating signal is received (#29515)

This commit adds signal handlers that flush telemetry data
before the process is terminated.
This commit is contained in:
Bartek Iwańczuk 2025-05-30 01:42:33 +02:00 committed by GitHub
parent dacfd23b87
commit 248d038ef6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -770,9 +770,87 @@ pub fn init(
})
.map_err(|_| deno_core::anyhow::anyhow!("failed to set otel globals"))?;
setup_signal_handlers();
Ok(())
}
#[cfg(unix)]
fn setup_signal_handlers() {
use tokio::signal::unix::SignalKind;
let signals_to_handle = [
SignalKind::hangup(),
SignalKind::interrupt(),
SignalKind::terminate(),
];
for signal_kind in signals_to_handle {
tokio::spawn(async move {
let Ok(mut signal_fut) = tokio::signal::unix::signal(signal_kind) else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
}
}
#[cfg(windows)]
fn setup_signal_handlers() {
tokio::spawn(async {
let Ok(mut signal_fut) = tokio::signal::windows::ctrl_break() else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
tokio::spawn(async {
let Ok(mut signal_fut) = tokio::signal::windows::ctrl_c() else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
tokio::spawn(async {
let Ok(mut signal_fut) = tokio::signal::windows::ctrl_close() else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
tokio::spawn(async {
let Ok(mut signal_fut) = tokio::signal::windows::ctrl_logoff() else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
tokio::spawn(async {
let Ok(mut signal_fut) = tokio::signal::windows::ctrl_shutdown() else {
return;
};
loop {
signal_fut.recv().await;
flush();
}
});
}
/// This function is called by the runtime whenever it is about to call
/// `process::exit()`, to ensure that all OpenTelemetry logs are properly
/// flushed before the process terminates.