diff --git a/beacon_node/client/Cargo.toml b/beacon_node/client/Cargo.toml index 1a82cd22bee..d806f200703 100644 --- a/beacon_node/client/Cargo.toml +++ b/beacon_node/client/Cargo.toml @@ -27,7 +27,6 @@ error-chain = "0.12.1" serde_yaml = "0.8.11" slog = { version = "2.5.2", features = ["max_level_trace"] } slog-async = "2.3.0" -slog-json = "2.3.0" tokio = "0.1.22" clap = "2.33.0" dirs = "2.0.2" diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index 331c905ccf8..b88b2ba4c64 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -1,10 +1,8 @@ use clap::ArgMatches; use network::NetworkConfig; use serde_derive::{Deserialize, Serialize}; -use slog::{info, o, Drain}; -use std::fs::{self, OpenOptions}; +use std::fs; use std::path::PathBuf; -use std::sync::Mutex; /// The number initial validators when starting the `Minimal`. const TESTNET_SPEC_CONSTANTS: &str = "minimal"; @@ -95,47 +93,11 @@ impl Config { Some(path) } - // Update the logger to output in JSON to specified file - fn update_logger(&mut self, log: &mut slog::Logger) -> Result<(), &'static str> { - let file = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(&self.log_file); - - if file.is_err() { - return Err("Cannot open log file"); - } - let file = file.unwrap(); - - if let Some(file) = self.log_file.to_str() { - info!( - *log, - "Log file specified, output will now be written to {} in json.", file - ); - } else { - info!( - *log, - "Log file specified output will now be written in json" - ); - } - - let drain = Mutex::new(slog_json::Json::default(file)).fuse(); - let drain = slog_async::Async::new(drain).build().fuse(); - *log = slog::Logger::root(drain, o!()); - - Ok(()) - } - /// Apply the following arguments to `self`, replacing values if they are specified in `args`. /// /// Returns an error if arguments are obviously invalid. May succeed even if some values are /// invalid. - pub fn apply_cli_args( - &mut self, - args: &ArgMatches, - log: &mut slog::Logger, - ) -> Result<(), String> { + pub fn apply_cli_args(&mut self, args: &ArgMatches, _log: &slog::Logger) -> Result<(), String> { if let Some(dir) = args.value_of("datadir") { self.data_dir = PathBuf::from(dir); }; @@ -149,11 +111,6 @@ impl Config { self.rest_api.apply_cli_args(args)?; self.websocket_server.apply_cli_args(args)?; - if let Some(log_file) = args.value_of("logfile") { - self.log_file = PathBuf::from(log_file); - self.update_logger(log)?; - }; - Ok(()) } } diff --git a/lighthouse/environment/Cargo.toml b/lighthouse/environment/Cargo.toml index b5e21a4e883..01053ae9acc 100644 --- a/lighthouse/environment/Cargo.toml +++ b/lighthouse/environment/Cargo.toml @@ -17,3 +17,4 @@ slog-async = "^2.3.0" ctrlc = { version = "3.1.1", features = ["termination"] } futures = "0.1.25" parking_lot = "0.7" +slog-json = "2.3.0" diff --git a/lighthouse/environment/src/lib.rs b/lighthouse/environment/src/lib.rs index de9cef7c98f..d6cdbe2fec2 100644 --- a/lighthouse/environment/src/lib.rs +++ b/lighthouse/environment/src/lib.rs @@ -1,8 +1,11 @@ use eth2_config::Eth2Config; use futures::{sync::oneshot, Future}; -use slog::{o, Drain, Level, Logger}; +use slog::{info, o, Drain, Level, Logger}; use sloggers::{null::NullLoggerBuilder, Build}; use std::cell::RefCell; +use std::fs::OpenOptions; +use std::path::PathBuf; +use std::sync::Mutex; use tokio::runtime::{Builder as RuntimeBuilder, Runtime, TaskExecutor}; use types::{EthSpec, InteropEthSpec, MainnetEthSpec, MinimalEthSpec}; @@ -183,6 +186,28 @@ impl Environment { .map_err(|e| format!("Tokio runtime shutdown returned an error: {:?}", e)) } + /// Sets the logger (and all child loggers) to log to a file. + pub fn log_to_json_file(&mut self, path: PathBuf) -> Result<(), String> { + let file = OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&path) + .map_err(|e| format!("Unable to open logfile: {:?}", e))?; + + let drain = Mutex::new(slog_json::Json::default(file)).fuse(); + let drain = slog_async::Async::new(drain).build().fuse(); + self.log = slog::Logger::root(drain, o!()); + + info!( + self.log, + "Logging to JSON file"; + "path" => format!("{:?}", path) + ); + + Ok(()) + } + pub fn eth_spec_instance(&self) -> &E { &self.eth_spec_instance } diff --git a/lighthouse/src/main.rs b/lighthouse/src/main.rs index dff23d60131..cb11339b408 100644 --- a/lighthouse/src/main.rs +++ b/lighthouse/src/main.rs @@ -6,6 +6,7 @@ use clap::{App, Arg, ArgMatches}; use env_logger::{Builder, Env}; use environment::EnvironmentBuilder; use slog::{crit, info, warn}; +use std::path::PathBuf; use std::process::exit; use types::EthSpec; use validator_client::ProductionValidatorClient; @@ -95,6 +96,13 @@ fn run( let log = environment.core_log(); + if let Some(log_path) = matches.value_of("logfile") { + let path = log_path + .parse::() + .map_err(|e| format!("Failed to parse log path: {:?}", e))?; + environment.log_to_json_file(path)?; + } + if std::mem::size_of::() != 8 { crit!( log, diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index 038bbd3c358..c3e9cb8561b 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -25,7 +25,6 @@ serde_derive = "1.0.102" serde_json = "1.0.41" slog = { version = "2.5.2", features = ["max_level_trace", "release_max_level_trace"] } slog-async = "2.3.0" -slog-json = "2.3.0" slog-term = "2.4.2" tokio = "0.1.22" tokio-timer = "0.2.11" diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index d56487616ad..749a5813cdc 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -2,12 +2,11 @@ use bincode; use bls::Keypair; use clap::ArgMatches; use serde_derive::{Deserialize, Serialize}; -use slog::{error, info, o, warn, Drain}; -use std::fs::{self, File, OpenOptions}; +use slog::{error, warn}; +use std::fs::{self, File}; use std::io::{Error, ErrorKind}; use std::ops::Range; use std::path::PathBuf; -use std::sync::Mutex; use types::{ test_utils::{generate_deterministic_keypair, load_keypairs_from_yaml}, EthSpec, MainnetEthSpec, @@ -94,17 +93,12 @@ impl Config { pub fn apply_cli_args( &mut self, args: &ArgMatches, - log: &mut slog::Logger, + _log: &slog::Logger, ) -> Result<(), &'static str> { if let Some(datadir) = args.value_of("datadir") { self.data_dir = PathBuf::from(datadir); }; - if let Some(log_file) = args.value_of("logfile") { - self.log_file = PathBuf::from(log_file); - self.update_logger(log)?; - }; - if let Some(srv) = args.value_of("server") { self.server = srv.to_string(); }; @@ -112,38 +106,6 @@ impl Config { Ok(()) } - // Update the logger to output in JSON to specified file - fn update_logger(&mut self, log: &mut slog::Logger) -> Result<(), &'static str> { - let file = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(&self.log_file); - - if file.is_err() { - return Err("Cannot open log file"); - } - let file = file.unwrap(); - - if let Some(file) = self.log_file.to_str() { - info!( - *log, - "Log file specified, output will now be written to {} in json.", file - ); - } else { - info!( - *log, - "Log file specified output will now be written in json" - ); - } - - let drain = Mutex::new(slog_json::Json::default(file)).fuse(); - let drain = slog_async::Async::new(drain).build().fuse(); - *log = slog::Logger::root(drain, o!()); - - Ok(()) - } - /// Reads a single keypair from the given `path`. /// /// `path` should be the path to a directory containing a private key. The file name of `path`