From 9685e2aecad0b350a1ffd36e22962d96471129ee Mon Sep 17 00:00:00 2001 From: stevenhorsman Date: Fri, 13 Jun 2025 10:51:11 +0100 Subject: [PATCH] trace-forwarder: Replace removed clap functions When moving from clap v2 to v4 a bunch of functions have been removed, so update the code to handle these replacements Signed-off-by: stevenhorsman --- src/tools/trace-forwarder/Cargo.toml | 4 +- src/tools/trace-forwarder/src/main.rs | 70 +++++++++++++++------------ 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/tools/trace-forwarder/Cargo.toml b/src/tools/trace-forwarder/Cargo.toml index 858afacb6e..1bb87f12ac 100644 --- a/src/tools/trace-forwarder/Cargo.toml +++ b/src/tools/trace-forwarder/Cargo.toml @@ -12,7 +12,7 @@ license = "Apache-2.0" [dependencies] futures = "0.3.15" -clap = "4.5.40" +clap = { version = "4.5.40", features = ["cargo"] } vsock = "0.2.3" nix = "0.23.0" libc = "0.2.94" @@ -21,7 +21,7 @@ bincode = "1.3.3" byteorder = "1.4.3" serde_json = "1.0.44" anyhow = "1.0.31" -opentelemetry = { version = "0.14.0", features=["serialize"] } +opentelemetry = { version = "0.14.0", features = ["serialize"] } opentelemetry-jaeger = "0.13.0" tracing-opentelemetry = "0.16.0" tracing = "0.1.41" diff --git a/src/tools/trace-forwarder/src/main.rs b/src/tools/trace-forwarder/src/main.rs index 482bbdda80..a8828e1842 100644 --- a/src/tools/trace-forwarder/src/main.rs +++ b/src/tools/trace-forwarder/src/main.rs @@ -1,11 +1,12 @@ // Copyright (c) 2020-2021 Intel Corporation +// Copyright (c) 2025 IBM Corporation // // SPDX-License-Identifier: Apache-2.0 // #![warn(unused_extern_crates)] use anyhow::{anyhow, Result}; -use clap::{crate_name, crate_version, App, Arg}; +use clap::{crate_name, crate_version, Arg, Command}; use slog::{error, info, Logger}; use std::env; use std::io; @@ -136,78 +137,73 @@ fn real_main() -> Result<()> { let version = crate_version!(); let name = crate_name!(); - let args = App::new(name) + let args = Command::new(name) .version(version) - .version_short("v") .about(ABOUT_TEXT) - .long_about(&*make_description_text()) - .after_help(&*make_examples_text(name)) + .long_about(make_description_text()) + .after_help(make_examples_text(name)) .arg( - Arg::with_name("dump-only") + Arg::new("dump-only") .long("dump-only") .help("Disable forwarding of spans and write to stdout (for testing)"), ) .arg( - Arg::with_name("trace-name") + Arg::new("trace-name") .long("trace-name") .help("Specify name for traces") .required(false) - .takes_value(true) .default_value(DEFAULT_TRACE_NAME), ) .arg( - Arg::with_name("jaeger-host") + Arg::new("jaeger-host") .long("jaeger-host") .help("Jaeger host address") - .takes_value(true) .default_value(DEFAULT_JAEGER_HOST), ) .arg( - Arg::with_name("jaeger-port") + Arg::new("jaeger-port") .long("jaeger-port") .help("Jaeger port number") - .takes_value(true) .default_value(DEFAULT_JAEGER_PORT), ) .arg( - Arg::with_name("log-level") + Arg::new("log-level") .long("log-level") - .short("l") + .short('l') .help("specific log level") .default_value(logging::slog_level_to_level_name(DEFAULT_LOG_LEVEL).unwrap()) - .possible_values(&logging::get_log_levels()) - .takes_value(true) + .value_parser(logging::get_log_levels()) .required(false), ) .arg( - Arg::with_name("socket-path") + Arg::new("socket-path") .long("socket-path") .help("Full path to hypervisor socket (needs root! cloud-hypervisor and firecracker hypervisors only)") - .takes_value(true) .required(false), ) .arg( - Arg::with_name("vsock-cid") + Arg::new("vsock-cid") .long("vsock-cid") - .help(&format!( + .help(format!( "VSOCK CID number (or {:?}) (QEMU hypervisor only)", VSOCK_CID_ANY_STR )) - .takes_value(true) .required(false) .default_value(VSOCK_CID_ANY_STR), ) .arg( - Arg::with_name("vsock-port") + Arg::new("vsock-port") .long("vsock-port") .help("VSOCK port number (QEMU hypervisor only)") - .takes_value(true) .default_value(DEFAULT_KATA_VSOCK_TRACING_PORT), ) .get_matches(); // Cannot fail as a default has been specified - let log_level_name = args.value_of("log-level").unwrap(); + let log_level_name = args + .get_one::("log-level") + .map(|s| s.as_str()) + .unwrap(); let log_level = logging::level_name_to_slog_level(log_level_name).map_err(|e| anyhow!(e))?; @@ -215,12 +211,13 @@ fn real_main() -> Result<()> { let writer = io::stdout(); let (logger, _logger_guard) = logging::create_logger(name, name, log_level, writer); - let dump_only = args.is_present("dump-only"); + let dump_only = args.contains_id("dump-only"); announce(&logger, version, dump_only); let trace_name: &str = args - .value_of("trace-name") + .get_one::("trace-name") + .map(|s| s.as_str()) .ok_or(anyhow!("BUG: trace name not set")) .map_or_else( |e| Err(anyhow!(e)), @@ -234,15 +231,23 @@ fn real_main() -> Result<()> { )?; // Handle the Hybrid VSOCK option first (since it cannot be defaulted). - let vsock = if let Some(socket_path) = args.value_of("socket-path") { - handle_hybrid_vsock(socket_path, args.value_of("vsock-port")) + let vsock = if let Some(socket_path) = args.get_one::("socket-path").map(|s| s.as_str()) + { + handle_hybrid_vsock( + socket_path, + args.get_one::("vsock-port").map(|s| s.as_str()), + ) } else { // The default is standard VSOCK - handle_standard_vsock(args.value_of("vsock-cid"), args.value_of("vsock-port")) + handle_standard_vsock( + args.get_one::("vsock-cid").map(|s| s.as_str()), + args.get_one::("vsock-port").map(|s| s.as_str()), + ) }?; let jaeger_port: u32 = args - .value_of("jaeger-port") + .get_one::("jaeger-port") + .map(|s| s.as_str()) .ok_or("Need Jaeger port number") .map(|p| p.parse::().unwrap()) .map_err(|e| anyhow!("Jaeger port number must be an integer: {:?}", e))?; @@ -252,9 +257,10 @@ fn real_main() -> Result<()> { } let jaeger_host = args - .value_of("jaeger-host") + .get_one::("jaeger-host") + .map(|s| s.as_str()) .ok_or("Need Jaeger host") - .map_err(|e| anyhow!(e))?; + .map_err(|e: &str| anyhow!(e))?; if jaeger_host.is_empty() { return Err(anyhow!("Jaeger host cannot be blank"));