diff --git a/crates/integration_test/src/logger.rs b/crates/integration_test/src/logger.rs index 34412ffb..e6591448 100644 --- a/crates/integration_test/src/logger.rs +++ b/crates/integration_test/src/logger.rs @@ -1,6 +1,4 @@ -//! Default Youki Logger - -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; use log::{LevelFilter, Log, Metadata, Record}; use once_cell::sync::OnceCell; use std::borrow::Cow; @@ -11,27 +9,13 @@ use std::str::FromStr; pub static LOG_FILE: OnceCell> = OnceCell::new(); const LOG_LEVEL_ENV_NAME: &str = "YOUKI_INTEGRATION_LOG_LEVEL"; -const LOG_FORMAT_TEXT: &str = "text"; -const LOG_FORMAT_JSON: &str = "json"; -enum LogFormat { - Text, - Json, -} -/// If in debug mode, default level is debug to get maximum logging -#[cfg(debug_assertions)] -const DEFAULT_LOG_LEVEL: &str = "debug"; - -/// If not in debug mode, default level is warn to get important logs -#[cfg(not(debug_assertions))] -const DEFAULT_LOG_LEVEL: &str = "warn"; /// Initialize the logger, must be called before accessing the logger /// Multiple parts might call this at once, but the actual initialization /// is done only once due to use of OnceCell -pub fn init(log_file: Option, log_format: Option) -> Result<()> { - let level = detect_log_level(true).context("failed to parse log level")?; - let format = detect_log_format(log_format).context("failed to detect log format")?; +pub fn init(log_file: Option, debug: bool) -> Result<()> { + let level = detect_log_level(debug).context("failed to parse log level")?; let _ = LOG_FILE.get_or_init(|| -> Option { log_file.map(|path| { OpenOptions::new() @@ -43,7 +27,7 @@ pub fn init(log_file: Option, log_format: Option) -> Result<()> }) }); - let logger = IntegrationLogger::new(level.to_level(), format); + let logger = IntegrationLogger::new(level.to_level()); log::set_boxed_logger(Box::new(logger)) .map(|()| log::set_max_level(level)) .expect("set logger failed"); @@ -51,35 +35,27 @@ pub fn init(log_file: Option, log_format: Option) -> Result<()> Ok(()) } -fn detect_log_format(log_format: Option) -> Result { - match log_format.as_deref() { - None | Some(LOG_FORMAT_TEXT) => Ok(LogFormat::Text), - Some(LOG_FORMAT_JSON) => Ok(LogFormat::Json), - Some(unknown) => bail!("unknown log format: {}", unknown), - } -} - fn detect_log_level(is_debug: bool) -> Result { let filter: Cow = if is_debug { "debug".into() } else if let Ok(level) = std::env::var(LOG_LEVEL_ENV_NAME) { level.into() } else { - DEFAULT_LOG_LEVEL.into() + "off".into() }; + Ok(LevelFilter::from_str(filter.as_ref())?) } struct IntegrationLogger { /// Indicates level up to which logs are to be printed level: Option, - format: LogFormat, } impl IntegrationLogger { /// Create new logger - pub fn new(level: Option, format: LogFormat) -> Self { - Self { level, format } + pub fn new(level: Option) -> Self { + Self { level } } } @@ -97,10 +73,7 @@ impl Log for IntegrationLogger { /// Function to carry out logging fn log(&self, record: &Record) { if self.enabled(record.metadata()) { - let log_msg = match self.format { - LogFormat::Text => text_format(record), - LogFormat::Json => json_format(record), - }; + let log_msg =text_format(record); // if log file is set, write to it, else write to stderr if let Some(mut log_file) = LOG_FILE.get().unwrap().as_ref() { let _ = writeln!(log_file, "{}", log_msg); @@ -120,15 +93,6 @@ impl Log for IntegrationLogger { } } -fn json_format(record: &log::Record) -> String { - serde_json::to_string(&serde_json::json!({ - "level": record.level().to_string(), - "time": chrono::Local::now().to_rfc3339(), - "message": record.args(), - })) - .expect("serde::to_string with string keys will not fail") -} - fn text_format(record: &log::Record) -> String { let log_msg = match (record.file(), record.line()) { (Some(file), Some(line)) => format!( diff --git a/crates/integration_test/src/main.rs b/crates/integration_test/src/main.rs index 162a6157..6edd998a 100644 --- a/crates/integration_test/src/main.rs +++ b/crates/integration_test/src/main.rs @@ -17,14 +17,20 @@ use tests::cgroups; #[derive(Parser, Debug)] #[clap(version = "0.0.1", author = "youki team")] struct Opts { - /// path for the container runtime to be tested + /// Path for the container runtime to be tested #[clap(short, long)] runtime: PathBuf, - /// selected tests to be run, format should be + /// Selected tests to be run, format should be /// space separated groups, eg /// -t group1::test1,test3 group2 group3::test5 #[clap(short, long, multiple_values = true, value_delimiter = ' ')] tests: Option>, + /// Enables debug output + #[clap(short, long)] + debug: bool, + /// Logs to the specified file + #[clap(long)] + log: Option, } // parse test string given in commandline option as pair of testgroup name and tests belonging to that @@ -45,7 +51,7 @@ fn parse_tests(tests: &[String]) -> Vec<(&str, Option>)> { fn main() -> Result<()> { let opts: Opts = Opts::parse(); - if let Err(e) = logger::init(None, None) { + if let Err(e) = logger::init(opts.log, opts.debug) { eprintln!("logger could not be initialized: {:?}", e); }