From 54f4d13350c3e86f534c2a106fb2e828cee88af5 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Sat, 10 Aug 2019 22:54:46 -0700 Subject: [PATCH] Validator log filter may now be reconfigured at runtime (#5473) * Log filter may now be reconfigured at runtime * Add RPC API and bash script to reconfigure the log filter --- Cargo.lock | 2 ++ core/src/rpc.rs | 8 +++++++ logger/Cargo.toml | 2 ++ logger/src/lib.rs | 46 +++++++++++++++++++++++++++++---------- scripts/set-log-filter.sh | 27 +++++++++++++++++++++++ 5 files changed, 73 insertions(+), 12 deletions(-) create mode 100755 scripts/set-log-filter.sh diff --git a/Cargo.lock b/Cargo.lock index a115e2e74e..38179f8529 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3505,6 +3505,8 @@ name = "solana-logger" version = "0.18.0-pre1" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 914429d1df..49e490bbb6 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -328,6 +328,9 @@ pub trait RpcSol { #[rpc(meta, name = "getVersion")] fn get_version(&self, _: Self::Metadata) -> Result; + + #[rpc(meta, name = "setLogFilter")] + fn set_log_filter(&self, _: Self::Metadata, _: String) -> Result<()>; } pub struct RpcSolImpl; @@ -619,6 +622,11 @@ impl RpcSol for RpcSolImpl { solana_core: VERSION.to_string(), }) } + + fn set_log_filter(&self, _: Self::Metadata, filter: String) -> Result<()> { + solana_logger::setup_with_filter(&filter); + Ok(()) + } } #[cfg(test)] diff --git a/logger/Cargo.toml b/logger/Cargo.toml index 482b4d091c..4a3a6297c2 100644 --- a/logger/Cargo.toml +++ b/logger/Cargo.toml @@ -10,6 +10,8 @@ edition = "2018" [dependencies] env_logger = "0.6.2" +lazy_static = "1.3.0" +log = "0.4.8" [lib] name = "solana_logger" diff --git a/logger/src/lib.rs b/logger/src/lib.rs index bebd8f0e16..879c9a4206 100644 --- a/logger/src/lib.rs +++ b/logger/src/lib.rs @@ -1,19 +1,41 @@ -//! The `logger` module provides a setup function for `env_logger`. Its only function, -//! `setup()` may be called multiple times. +//! The `logger` module configures `env_logger` -use env_logger; -use std::sync::Once; +use lazy_static::lazy_static; +use std::sync::{Arc, RwLock}; -static INIT: Once = Once::new(); - -pub fn setup_with_filter(filter: &str) { - INIT.call_once(|| { - env_logger::Builder::from_env(env_logger::Env::new().default_filter_or(filter)) - .default_format_timestamp_nanos(true) - .init(); - }); +lazy_static! { + static ref LOGGER: Arc> = + { Arc::new(RwLock::new(env_logger::Logger::from_default_env())) }; } +struct LoggerShim {} + +impl log::Log for LoggerShim { + fn enabled(&self, metadata: &log::Metadata) -> bool { + LOGGER.read().unwrap().enabled(metadata) + } + + fn log(&self, record: &log::Record) { + LOGGER.read().unwrap().log(record); + } + + fn flush(&self) {} +} + +// Configures logging with a specific filter. +// May be called at any time to re-configure the log filter +pub fn setup_with_filter(filter: &str) { + let logger = env_logger::Builder::from_env(env_logger::Env::new().default_filter_or(filter)) + .default_format_timestamp_nanos(true) + .build(); + let max_level = logger.filter(); + log::set_max_level(max_level); + let mut rw = LOGGER.write().unwrap(); + std::mem::replace(&mut *rw, logger); + let _ = log::set_boxed_logger(Box::new(LoggerShim {})); +} + +// Configures logging with the default filter ("error") pub fn setup() { setup_with_filter("error"); } diff --git a/scripts/set-log-filter.sh b/scripts/set-log-filter.sh new file mode 100755 index 0000000000..bee721e019 --- /dev/null +++ b/scripts/set-log-filter.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# +# Reconfigures the log filter on a validator using the current RUST_LOG value +# + +if [[ -n $1 ]]; then + url=$1 +else + # Default to the local node + url=http://127.0.0.1:8899 +fi + +if [[ -z $RUST_LOG ]]; then + echo "RUST_LOG not defined" + exit 1 +fi + +set -x +exec curl $url -X POST -H "Content-Type: application/json" \ + -d " + { + \"jsonrpc\": \"2.0\", + \"id\": 1, + \"method\": \"setLogFilter\", + \"params\": [\"$RUST_LOG\"] + } + "