From 3d8dc565f9de9466f0e049d28101e6a1d64bba17 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 5 Mar 2021 16:17:25 +0100 Subject: Add "endpoint stats" subcommand Signed-off-by: Matthias Beyer --- src/cli.rs | 11 +++++++ src/commands/endpoint.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/src/cli.rs b/src/cli.rs index 2aacc98..d079a70 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -865,6 +865,17 @@ pub fn cli<'a>() -> App<'a> { .about("How long to sleep between pings") ) ) + .subcommand(App::new("stats") + .version(crate_version!()) + .about("Get stats for the endpoint(s)") + .arg(Arg::new("csv") + .required(false) + .multiple(false) + .long("csv") + .takes_value(false) + .about("Format output as CSV") + ) + ) ) } diff --git a/src/commands/endpoint.rs b/src/commands/endpoint.rs index fb98c6a..128613a 100644 --- a/src/commands/endpoint.rs +++ b/src/commands/endpoint.rs @@ -37,6 +37,7 @@ pub async fn endpoint(matches: &ArgMatches, config: &Configuration, progress_gen match matches.subcommand() { Some(("ping", matches)) => ping(endpoint_names, matches, config, progress_generator).await, + Some(("stats", matches)) => stats(endpoint_names, matches, config, progress_generator).await, Some((other, _)) => Err(anyhow!("Unknown subcommand: {}", other)), None => Err(anyhow!("No subcommand")), } @@ -111,3 +112,86 @@ async fn ping(endpoint_names: Vec, let multibar_block = tokio::task::spawn_blocking(move || multibar.join()); tokio::join!(ping_process, multibar_block).0 } + +async fn stats(endpoint_names: Vec, + matches: &ArgMatches, + config: &Configuration, + progress_generator: ProgressBars +) -> Result<()> { + let csv = matches.is_present("csv"); + + let endpoint_configurations = config + .docker() + .endpoints() + .iter() + .filter(|ep| endpoint_names.contains(ep.name())) + .cloned() + .map(|ep_cfg| { + crate::endpoint::EndpointConfiguration::builder() + .endpoint(ep_cfg) + .required_images(config.docker().images().clone()) + .required_docker_versions(config.docker().docker_versions().clone()) + .required_docker_api_versions(config.docker().docker_api_versions().clone()) + .build() + }) + .collect::>(); + + info!("Endpoint config build"); + info!("Connecting to {n} endpoints: {eps}", + n = endpoint_configurations.len(), + eps = endpoint_configurations.iter().map(|epc| epc.endpoint().name()).join(", ")); + + let bar = progress_generator.bar(); + bar.set_length(endpoint_configurations.len() as u64); + bar.set_message("Fetching stats"); + + let endpoints = crate::endpoint::util::setup_endpoints(endpoint_configurations).await?; + + let hdr = crate::commands::util::mk_header([ + "Name", + "Containers", + "Images", + "Kernel", + "Memory", + "Memory limit", + "Cores", + "OS", + "System Time", + ].to_vec()); + + let data = endpoints + .into_iter() + .map(|endpoint| { + let bar = bar.clone(); + async move { + let r = endpoint.stats().await; + bar.inc(1); + r + } + }) + .collect::>() + .collect::>>() + .await + .map_err(|e| { + bar.finish_with_message("Fetching stats errored"); + e + })? + .into_iter() + .map(|stat| { + vec![ + stat.name, + stat.containers.to_string(), + stat.images.to_string(), + stat.kernel_version, + stat.mem_total.to_string(), + stat.memory_limit.to_string(), + stat.n_cpu.to_string(), + stat.operating_system.to_string(), + stat.system_time.map(|t| t.to_string()).unwrap_or_else(|| String::from("unknown")), + ] + }) + .collect(); + + bar.finish_with_message("Fetching stats successful"); + crate::commands::util::display_data(hdr, data, csv) +} -- cgit v1.2.3