Skip to content

Commit ef1ed88

Browse files
committed
add redirect_stderr_to_file to logger
1 parent 4b1ade7 commit ef1ed88

File tree

4 files changed

+95
-3
lines changed

4 files changed

+95
-3
lines changed

Cargo.lock

Lines changed: 23 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ indicatif = "0.17.9"
161161
itertools = "0.12.1"
162162
js-sys = "0.3.77"
163163
lazy_static = "1.5.0"
164+
libc = "0.2.170"
164165
libsecp256k1 = { version = "0.6.0", default-features = false, features = [
165166
"std",
166167
"static-context",
@@ -192,6 +193,7 @@ serde_with = { version = "3.12.0", default-features = false }
192193
serial_test = "2.0.0"
193194
sha2 = "0.10.8"
194195
sha3 = "0.10.8"
196+
signal-hook = "0.3.17"
195197
siphasher = "0.3.11"
196198
solana-account = { path = "account", version = "2.2.1" }
197199
solana-account-info = { path = "account-info", version = "2.2.1" }

logger/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ edition = { workspace = true }
1212
[dependencies]
1313
env_logger = { workspace = true }
1414
lazy_static = { workspace = true }
15+
libc = { workspace = true }
1516
log = { workspace = true }
17+
signal-hook = { workspace = true }
1618

1719
[lib]
1820
name = "solana_logger"

logger/src/lib.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
33
use {
44
lazy_static::lazy_static,
5-
std::sync::{Arc, RwLock},
5+
std::{
6+
env,
7+
sync::{Arc, RwLock},
8+
thread::JoinHandle,
9+
},
610
};
711

812
lazy_static! {
@@ -75,3 +79,66 @@ pub fn setup_file_with_default(logfile: &str, filter: &str) {
7579
.build();
7680
replace_logger(logger);
7781
}
82+
83+
#[cfg(unix)]
84+
fn redirect_stderr(filename: &str) {
85+
use std::{fs::OpenOptions, os::unix::io::AsRawFd};
86+
match OpenOptions::new().create(true).append(true).open(filename) {
87+
Ok(file) => unsafe {
88+
libc::dup2(file.as_raw_fd(), libc::STDERR_FILENO);
89+
},
90+
Err(err) => eprintln!("Unable to open {filename}: {err}"),
91+
}
92+
}
93+
94+
// Redirect stderr to a file with support for logrotate by sending a SIGUSR1 to the process.
95+
//
96+
// Upon success, future `log` macros and `eprintln!()` can be found in the specified log file.
97+
pub fn redirect_stderr_to_file(logfile: Option<String>) -> Option<JoinHandle<()>> {
98+
// Default to RUST_BACKTRACE=1 for more informative validator logs
99+
if env::var_os("RUST_BACKTRACE").is_none() {
100+
env::set_var("RUST_BACKTRACE", "1")
101+
}
102+
103+
match logfile {
104+
None => {
105+
setup_with_default_filter();
106+
None
107+
}
108+
Some(logfile) => {
109+
#[cfg(unix)]
110+
{
111+
use log::info;
112+
let mut signals =
113+
signal_hook::iterator::Signals::new([signal_hook::consts::SIGUSR1])
114+
.unwrap_or_else(|err| {
115+
eprintln!("Unable to register SIGUSR1 handler: {err:?}");
116+
std::process::exit(1);
117+
});
118+
119+
setup_with_default_filter();
120+
redirect_stderr(&logfile);
121+
Some(
122+
std::thread::Builder::new()
123+
.name("solSigUsr1".into())
124+
.spawn(move || {
125+
for signal in signals.forever() {
126+
info!(
127+
"received SIGUSR1 ({}), reopening log file: {:?}",
128+
signal, logfile
129+
);
130+
redirect_stderr(&logfile);
131+
}
132+
})
133+
.unwrap(),
134+
)
135+
}
136+
#[cfg(not(unix))]
137+
{
138+
println!("logrotate is not supported on this platform");
139+
setup_file_with_default(&logfile, solana_logger::DEFAULT_FILTER);
140+
None
141+
}
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)