Skip to content

Commit afaee78

Browse files
committed
refactor: encapsulate log rotation logic
This moves the `SIGHUP` signal handling from the main server loop to a dedicated background task in `ServerLogger` to make the logger responsible for its own file handle management. Co-Authored-By: Gemini 3.0 Pro
1 parent 2c0e186 commit afaee78

2 files changed

Lines changed: 36 additions & 14 deletions

File tree

ldk-server/src/main.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,8 @@ fn main() {
254254
}
255255

256256
runtime.block_on(async {
257-
// Register SIGHUP handler for log rotation
258-
let mut sighup_stream = match tokio::signal::unix::signal(SignalKind::hangup()) {
259-
Ok(stream) => stream,
260-
Err(e) => {
261-
error!("Failed to register SIGHUP handler: {e}");
262-
std::process::exit(-1);
263-
}
264-
};
257+
// Start the logger's signal listener for log rotation
258+
logger.start_signal_listener();
265259

266260
let mut sigterm_stream = match tokio::signal::unix::signal(SignalKind::terminate()) {
267261
Ok(stream) => stream,
@@ -517,11 +511,6 @@ fn main() {
517511
let _ = shutdown_tx.send(true);
518512
break;
519513
}
520-
_ = sighup_stream.recv() => {
521-
if let Err(e) = logger.reopen() {
522-
error!("Failed to reopen log file on SIGHUP: {e}");
523-
}
524-
}
525514
_ = sigterm_stream.recv() => {
526515
info!("Received SIGTERM, shutting down..");
527516
let _ = shutdown_tx.send(true);

ldk-server/src/util/logger.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use std::io::{self, Write};
1212
use std::path::{Path, PathBuf};
1313
use std::sync::{Arc, Mutex};
1414

15-
use log::{Level, LevelFilter, Log, Metadata, Record};
15+
use log::{error, info, Level, LevelFilter, Log, Metadata, Record};
16+
#[cfg(unix)]
17+
use tokio::signal::unix::{signal, SignalKind};
1618

1719
/// A logger implementation that writes logs to both stderr and a file.
1820
///
@@ -61,9 +63,18 @@ impl ServerLogger {
6163
log::set_boxed_logger(Box::new(LoggerWrapper(Arc::clone(&logger))))
6264
.map_err(io::Error::other)?;
6365
log::set_max_level(level);
66+
6467
Ok(logger)
6568
}
6669

70+
/// Starts a background task to listen for SIGHUP and rotate logs.
71+
pub fn start_signal_listener(self: &Arc<Self>) {
72+
#[cfg(unix)]
73+
{
74+
spawn_sighup_handler(Arc::clone(self));
75+
}
76+
}
77+
6778
/// Reopens the log file. Called on SIGHUP for log rotation.
6879
pub fn reopen(&self) -> Result<(), io::Error> {
6980
let new_file = open_log_file(&self.log_file_path)?;
@@ -158,6 +169,28 @@ fn open_log_file(log_file_path: &Path) -> Result<File, io::Error> {
158169
OpenOptions::new().create(true).append(true).open(log_file_path)
159170
}
160171

172+
#[cfg(unix)]
173+
fn spawn_sighup_handler(logger: Arc<ServerLogger>) {
174+
if let Ok(handle) = tokio::runtime::Handle::try_current() {
175+
handle.spawn(async move {
176+
let mut sighup_stream = match signal(SignalKind::hangup()) {
177+
Ok(stream) => stream,
178+
Err(e) => {
179+
error!("Failed to register SIGHUP handler: {e}");
180+
return;
181+
},
182+
};
183+
184+
while sighup_stream.recv().await.is_some() {
185+
info!("SIGHUP received; reopening log file for rotation...");
186+
if let Err(e) = logger.reopen() {
187+
error!("Failed to reopen log file on SIGHUP: {e}");
188+
}
189+
}
190+
});
191+
}
192+
}
193+
161194
/// Wrapper to allow Arc<ServerLogger> to implement Log trait
162195
struct LoggerWrapper(Arc<ServerLogger>);
163196

0 commit comments

Comments
 (0)