fix: use Box<dyn Write + Send> for cross-platform tracing writer
Replace platform-specific std::os::unix::io::FromRawFd with Box<dyn std::io::Write + Send> return type. This compiles on Windows, macOS, and Linux without unsafe code. The closure now returns a boxed writer that is either: - The cloned file handle (success case) - A reopened file handle (clone failed) - stderr (last resort, prevents panic)
This commit is contained in:
@@ -157,21 +157,23 @@ pub fn init() -> Result<TuiLogGuard> {
|
||||
let log_path_clone = log_path.clone();
|
||||
let subscriber = tracing_subscriber::registry().with(env_filter).with(
|
||||
fmt::layer()
|
||||
.with_writer(move || {
|
||||
.with_writer(move || -> Box<dyn std::io::Write + Send> {
|
||||
// Clone the file handle for each write. If clone fails (fd exhaustion),
|
||||
// fall back to reopening the same path, or ultimately stderr.
|
||||
subscriber_file.try_clone().unwrap_or_else(|e| {
|
||||
tracing::warn!("Failed to clone log file handle: {e}, reopening");
|
||||
std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(&log_path_clone)
|
||||
.unwrap_or_else(|_| {
|
||||
// Last resort: wrap stderr as a File to prevent panic.
|
||||
use std::os::unix::io::FromRawFd;
|
||||
unsafe { std::fs::File::from_raw_fd(2) }
|
||||
})
|
||||
})
|
||||
match subscriber_file.try_clone() {
|
||||
Ok(f) => Box::new(f),
|
||||
Err(e) => {
|
||||
tracing::warn!("Failed to clone log file handle: {e}, reopening");
|
||||
match std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(&log_path_clone)
|
||||
{
|
||||
Ok(f) => Box::new(f),
|
||||
Err(_) => Box::new(std::io::stderr()),
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.with_ansi(false)
|
||||
.with_target(true)
|
||||
|
||||
Reference in New Issue
Block a user