Add support for log rotation, sending SIGUSR1 will cause the log file to be re-opened (#9713)
This commit is contained in:
parent
76b1c2baf0
commit
50f1ec0374
|
@ -31,7 +31,8 @@ solana-vote-program = { path = "../programs/vote", version = "1.2.0" }
|
||||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.0" }
|
solana-vote-signer = { path = "../vote-signer", version = "1.2.0" }
|
||||||
|
|
||||||
[target."cfg(unix)".dependencies]
|
[target."cfg(unix)".dependencies]
|
||||||
gag = "0.1.10"
|
libc = "0.2.66"
|
||||||
|
signal-hook = "0.1.13"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
|
@ -45,7 +45,7 @@ use std::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
thread::sleep,
|
thread::{sleep, JoinHandle},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -400,6 +400,64 @@ fn is_snapshot_config_invalid(
|
||||||
|| snapshot_interval_slots % accounts_hash_interval_slots != 0)
|
|| snapshot_interval_slots % accounts_hash_interval_slots != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn redirect_stderr(filename: &str) {
|
||||||
|
use std::{fs::OpenOptions, os::unix::io::AsRawFd};
|
||||||
|
match OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.append(true)
|
||||||
|
.open(filename)
|
||||||
|
{
|
||||||
|
Ok(file) => unsafe {
|
||||||
|
libc::dup2(file.as_raw_fd(), libc::STDERR_FILENO);
|
||||||
|
},
|
||||||
|
Err(err) => eprintln!("Unable to open {}: {}", filename, err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_logger(logfile: Option<String>) -> Option<JoinHandle<()>> {
|
||||||
|
let logger_thread = match logfile {
|
||||||
|
None => None,
|
||||||
|
Some(logfile) => {
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
let signals = signal_hook::iterator::Signals::new(&[signal_hook::SIGUSR1])
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
eprintln!("Unable to register SIGUSR1 handler: {:?}", err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
redirect_stderr(&logfile);
|
||||||
|
Some(std::thread::spawn(move || {
|
||||||
|
for signal in signals.forever() {
|
||||||
|
info!(
|
||||||
|
"received SIGUSR1 ({}), reopening log file: {:?}",
|
||||||
|
signal, logfile
|
||||||
|
);
|
||||||
|
redirect_stderr(&logfile);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
{
|
||||||
|
println!("logging to a file is not supported on this platform");
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
solana_logger::setup_with_default(
|
||||||
|
&[
|
||||||
|
"solana=info", /* info logging for all solana modules */
|
||||||
|
"rpc=trace", /* json_rpc request/response logging */
|
||||||
|
]
|
||||||
|
.join(","),
|
||||||
|
);
|
||||||
|
|
||||||
|
logger_thread
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let default_dynamic_port_range =
|
let default_dynamic_port_range =
|
||||||
|
@ -661,7 +719,9 @@ pub fn main() {
|
||||||
.long("log")
|
.long("log")
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Redirect logging to the specified file, '-' for standard error"),
|
.help("Redirect logging to the specified file, '-' for standard error. \
|
||||||
|
Sending the SIGUSR1 signal to the validator process will cause it \
|
||||||
|
to re-open the log file"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("wait_for_supermajority")
|
Arg::with_name("wait_for_supermajority")
|
||||||
|
@ -927,42 +987,20 @@ pub fn main() {
|
||||||
warn!("--vote-signer-address ignored");
|
warn!("--vote-signer-address ignored");
|
||||||
}
|
}
|
||||||
|
|
||||||
let _log_redirect = {
|
let logfile = {
|
||||||
#[cfg(unix)]
|
let logfile = matches
|
||||||
{
|
.value_of("logfile")
|
||||||
let default_logfile = format!(
|
.map(|s| s.into())
|
||||||
"solana-validator-{}-{}.log",
|
.unwrap_or_else(|| format!("solana-validator-{}.log", identity_keypair.pubkey()));
|
||||||
identity_keypair.pubkey(),
|
|
||||||
chrono::Utc::now().format("%Y%m%d-%H%M%S")
|
|
||||||
);
|
|
||||||
let logfile = matches.value_of("logfile").unwrap_or(&default_logfile);
|
|
||||||
|
|
||||||
if logfile == "-" {
|
if logfile == "-" {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
println!("log file: {}", logfile);
|
println!("log file: {}", logfile);
|
||||||
Some(gag::Redirect::stderr(File::create(logfile).unwrap_or_else(
|
Some(logfile)
|
||||||
|err| {
|
|
||||||
eprintln!("Unable to create {}: {:?}", logfile, err);
|
|
||||||
exit(1);
|
|
||||||
},
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
{
|
|
||||||
println!("logging to a file is not supported on this platform");
|
|
||||||
()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let _logger_thread = start_logger(logfile);
|
||||||
solana_logger::setup_with_default(
|
|
||||||
&[
|
|
||||||
"solana=info", /* info logging for all solana modules */
|
|
||||||
"rpc=trace", /* json_rpc request/response logging */
|
|
||||||
]
|
|
||||||
.join(","),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Default to RUST_BACKTRACE=1 for more informative validator logs
|
// Default to RUST_BACKTRACE=1 for more informative validator logs
|
||||||
if env::var_os("RUST_BACKTRACE").is_none() {
|
if env::var_os("RUST_BACKTRACE").is_none() {
|
||||||
|
|
Loading…
Reference in New Issue