From 68998f1bc7a1ad4c885c30e5b72ab7504ea50499 Mon Sep 17 00:00:00 2001 From: "Sarver, Edwin" Date: Wed, 24 Jul 2024 14:51:56 -0400 Subject: [PATCH 1/3] add option for log-socket --- kic-discover/src/main.rs | 120 ++++++++++++++++++++++++++++++++++----- kic/src/main.rs | 107 +++++++++++++++++++++++++++++++--- 2 files changed, 205 insertions(+), 22 deletions(-) diff --git a/kic-discover/src/main.rs b/kic-discover/src/main.rs index c75fb8c..3313167 100644 --- a/kic-discover/src/main.rs +++ b/kic-discover/src/main.rs @@ -9,10 +9,14 @@ use tracing::{error, info, instrument, level_filters::LevelFilter, trace, warn}; use tracing_subscriber::{layer::SubscriberExt, Layer, Registry}; use tsp_toolkit_kic_lib::instrument::info::InstrumentInfo; -use std::collections::HashSet; use std::fs::OpenOptions; use std::str; use std::time::Duration; +use std::{ + collections::HashSet, + net::{SocketAddr, TcpStream}, + sync::Mutex, +}; use clap::{command, Args, Command, FromArgMatches, Parser, Subcommand}; @@ -21,14 +25,18 @@ use kic_discover::DISC_INSTRUMENTS; #[derive(Debug, Parser)] #[command(author, version, about, long_about = None)] struct Cli { - /// Enable logging to stderr. When used with `--log-file`, logs will be written to both stderr and the given log file. + /// Enable logging to stderr. Can be used in conjunction with `--log-file` and `--verbose`. #[arg(global = true, short = 'v', long = "verbose")] verbose: bool, - /// Log to the given log file path. If not set, logging will not occur unless `--verbose` is set. + /// Log to the given log file path. Can be used in conjunction with `--log-socket` and `--verbose`. #[arg(name = "log-file", global = true, short = 'l', long = "log-file")] log_file: Option, + /// Log to the given socket (in IPv4 or IPv6 format with port number). Can be used in conjunction with `--log-file` and `--verbose`. + #[arg(name = "log-socket", global = true, short = 's', long = "log-socket")] + log_socket: Option, + #[command(subcommand)] conn: SubCli, } @@ -45,14 +53,18 @@ enum SubCli { #[derive(Debug, Args, Clone, PartialEq)] pub(crate) struct DiscoverCmd { - /// Enable logging to stderr. When used with `--log-file`, logs will be written to both stderr and the given log file. + /// Enable logging to stderr. Can be used in conjunction with `--log-file` and `--verbose`. #[arg(from_global)] verbose: bool, - /// Log to the given log file path. If not set, logging will not occur unless `--verbose` is set. + /// Log to the given log file path. Can be used in conjunction with `--log-socket` and `--verbose`. #[clap(name = "log-file", from_global)] log_file: Option, + /// Log to the given socket (in IPv4 or IPv6 format with port number). Can be used in conjunction with `--log-file` and `--verbose`. + #[clap(name = "log-socket", from_global)] + log_socket: Option, + /// Print JSON-encoded instrument information. #[clap(long)] json: bool, @@ -68,9 +80,40 @@ pub(crate) struct DiscoverCmd { exit: bool, } -fn start_logger(verbose: &bool, log_file: &Option) -> anyhow::Result<()> { - match (verbose, log_file) { - (true, Some(l)) => { +fn start_logger( + verbose: &bool, + log_file: &Option, + log_socket: &Option, +) -> anyhow::Result<()> { + match (verbose, log_file, log_socket) { + (true, Some(l), Some(s)) => { + let err = tracing_subscriber::fmt::layer() + .with_ansi(true) + .with_writer(std::io::stderr) + .with_filter(LevelFilter::INFO); + + let log = OpenOptions::new().append(true).create(true).open(l)?; + + let log = tracing_subscriber::fmt::layer() + .with_writer(log) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(err) + .with(log) + .with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (true, Some(l), None) => { let err = tracing_subscriber::fmt::layer() .with_ansi(true) .with_writer(std::io::stderr) @@ -90,7 +133,27 @@ fn start_logger(verbose: &bool, log_file: &Option) -> anyhow::Result<() tracing::subscriber::set_global_default(logger)?; } - (false, Some(l)) => { + (false, Some(l), Some(s)) => { + let log = OpenOptions::new().append(true).create(true).open(l)?; + + let log = tracing_subscriber::fmt::layer() + .with_writer(log) + .with_ansi(false); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(log) + .with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (false, Some(l), None) => { let log = OpenOptions::new().append(true).create(true).open(l)?; let log = tracing_subscriber::fmt::layer() @@ -101,7 +164,25 @@ fn start_logger(verbose: &bool, log_file: &Option) -> anyhow::Result<() tracing::subscriber::set_global_default(logger)?; } - (true, None) => { + (true, None, Some(s)) => { + let err = tracing_subscriber::fmt::layer() + .with_ansi(true) + .with_writer(std::io::stderr); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(err) + .with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (true, None, None) => { let err = tracing_subscriber::fmt::layer() .with_ansi(true) .with_writer(std::io::stderr); @@ -110,7 +191,18 @@ fn start_logger(verbose: &bool, log_file: &Option) -> anyhow::Result<() tracing::subscriber::set_global_default(logger)?; } - (false, None) => {} + (false, None, Some(s)) => { + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default().with(LevelFilter::TRACE).with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (false, None, None) => {} } info!("Application started"); @@ -152,7 +244,7 @@ async fn main() -> anyhow::Result<()> { match sub { SubCli::Lan(args) => { - start_logger(&args.verbose, &args.log_file)?; + start_logger(&args.verbose, &args.log_file, &args.log_socket)?; info!("Discovering LAN instruments"); #[allow(clippy::mutable_key_type)] let lan_instruments = match discover_lan(args).await { @@ -171,7 +263,7 @@ async fn main() -> anyhow::Result<()> { } } SubCli::Usb(args) => { - start_logger(&args.verbose, &args.log_file)?; + start_logger(&args.verbose, &args.log_file, &args.log_socket)?; info!("Discovering USB instruments"); #[allow(clippy::mutable_key_type)] let usb_instruments = match discover_usb().await { @@ -189,7 +281,7 @@ async fn main() -> anyhow::Result<()> { } } SubCli::All(args) => { - start_logger(&args.verbose, &args.log_file)?; + start_logger(&args.verbose, &args.log_file, &args.log_socket)?; info!("Discovering USB instruments"); #[allow(clippy::mutable_key_type)] let usb_instruments = match discover_usb().await { diff --git a/kic/src/main.rs b/kic/src/main.rs index 15d2ecc..5094548 100644 --- a/kic/src/main.rs +++ b/kic/src/main.rs @@ -26,7 +26,7 @@ use std::{ net::{IpAddr, SocketAddr, TcpStream}, path::PathBuf, process::exit, - sync::Arc, + sync::{Arc, Mutex}, thread, time::Duration, }; @@ -115,16 +115,25 @@ fn cmds() -> Command { .short('l') .long("log-file") .required(false) - .help("Log to the given log file path. If not set, logging will not occur unless `--verbose` is set.") + .help("Log to the given log file path. Can be used in conjunction with `--log-socket` and `--verbose`.") .global(true) .value_parser(PathBufValueParser::new()), ) + .arg( + Arg::new("log-socket") + .short('s') + .long("log-socket") + .required(false) + .help("Log to the given socket (in IPv4 or IPv6 format with port number). Can be used in conjunction with `--log-file` and `--verbose`.") + .global(true) + .value_parser(clap::value_parser!(SocketAddr)), + ) .arg( Arg::new("verbose") .short('v') .long("verbose") .required(false) - .help("Enable logging to stderr. When used with `--log-file`, logs will be written to both stderr and the given log file.") + .help("Enable logging to stderr. Can be used in conjunction with `--log-file` and `--verbose`.") .global(true) .action(ArgAction::SetTrue), ) @@ -228,9 +237,37 @@ fn main() -> anyhow::Result<()> { let verbose: bool = matches.get_flag("verbose"); let log_file: Option<&PathBuf> = matches.get_one("log-file"); + let log_socket: Option<&SocketAddr> = matches.get_one("log-socket"); + + match (verbose, log_file, log_socket) { + (true, Some(l), Some(s)) => { + let err = tracing_subscriber::fmt::layer() + .with_ansi(true) + .with_writer(std::io::stderr) + .with_filter(LevelFilter::INFO); + + let log = OpenOptions::new().append(true).create(true).open(l)?; + + let log = tracing_subscriber::fmt::layer() + .with_writer(log) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(err) + .with(log) + .with(sock); - match (verbose, log_file) { - (true, Some(l)) => { + tracing::subscriber::set_global_default(logger)?; + } + (true, Some(l), None) => { let err = tracing_subscriber::fmt::layer() .with_ansi(true) .with_writer(std::io::stderr) @@ -250,7 +287,27 @@ fn main() -> anyhow::Result<()> { tracing::subscriber::set_global_default(logger)?; } - (false, Some(l)) => { + (false, Some(l), Some(s)) => { + let log = OpenOptions::new().append(true).create(true).open(l)?; + + let log = tracing_subscriber::fmt::layer() + .with_writer(log) + .with_ansi(false); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(log) + .with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (false, Some(l), None) => { let log = OpenOptions::new().append(true).create(true).open(l)?; let log = tracing_subscriber::fmt::layer() @@ -261,7 +318,25 @@ fn main() -> anyhow::Result<()> { tracing::subscriber::set_global_default(logger)?; } - (true, None) => { + (true, None, Some(s)) => { + let err = tracing_subscriber::fmt::layer() + .with_ansi(true) + .with_writer(std::io::stderr); + + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default() + .with(LevelFilter::TRACE) + .with(err) + .with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (true, None, None) => { let err = tracing_subscriber::fmt::layer() .with_ansi(true) .with_writer(std::io::stderr); @@ -270,7 +345,18 @@ fn main() -> anyhow::Result<()> { tracing::subscriber::set_global_default(logger)?; } - (false, None) => {} + (false, None, Some(s)) => { + let sock = TcpStream::connect(s)?; + let sock = tracing_subscriber::fmt::layer() + .with_writer(Mutex::new(sock)) + .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) + .with_ansi(false); + + let logger = Registry::default().with(LevelFilter::TRACE).with(sock); + + tracing::subscriber::set_global_default(logger)?; + } + (false, None, None) => {} } info!("Application started"); @@ -320,6 +406,11 @@ fn main() -> anyhow::Result<()> { args.push(log_file.to_str().unwrap().to_string()) } + if let Some(log_socket) = log_socket { + args.push("--log-socket".to_string()); + args.push(log_socket.to_string()); + } + debug!("Replacing this executable with '{path:?}' args: {args:?}"); if let Err(e) = Process::new(path.clone(), args) From b5293107ae955d9241530bed5f4e3553aadd4c61 Mon Sep 17 00:00:00 2001 From: "Sarver, Edwin" Date: Thu, 25 Jul 2024 13:13:34 -0400 Subject: [PATCH 2/3] Add logging to a port in JSON format --- Cargo.lock | 19 ++++++++++++++++--- Cargo.toml | 2 +- kic-discover/src/main.rs | 8 ++++---- kic/src/main.rs | 8 ++++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d1332a..a53fba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1128,7 +1128,7 @@ dependencies = [ [[package]] name = "instrument-repl" -version = "0.16.3" +version = "0.17.0" dependencies = [ "chrono", "clap", @@ -1254,7 +1254,7 @@ dependencies = [ [[package]] name = "kic" -version = "0.16.3" +version = "0.17.0" dependencies = [ "anyhow", "clap", @@ -1273,7 +1273,7 @@ dependencies = [ [[package]] name = "kic-discover" -version = "0.16.3" +version = "0.17.0" dependencies = [ "anyhow", "async-std", @@ -2555,6 +2555,16 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" @@ -2562,11 +2572,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bff60c4..79c2167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ serde_json = "1.0.114" thiserror = "1.0.58" tmc = { git = "https://github.com/esarver/rusb-usbtmc" } tracing = { version = "0.1.40", features = ["async-await"] } -tracing-subscriber = "0.3.18" +tracing-subscriber = { version = "0.3.18", features = ["json"] } tsp-toolkit-kic-lib = { git = "https://github.com/tektronix/tsp-toolkit-kic-lib.git", tag = "v0.16.1" } [workspace.lints.rust] diff --git a/kic-discover/src/main.rs b/kic-discover/src/main.rs index 3313167..6c65851 100644 --- a/kic-discover/src/main.rs +++ b/kic-discover/src/main.rs @@ -103,7 +103,7 @@ fn start_logger( let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -144,7 +144,7 @@ fn start_logger( let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -173,7 +173,7 @@ fn start_logger( let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -196,7 +196,7 @@ fn start_logger( let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default().with(LevelFilter::TRACE).with(sock); diff --git a/kic/src/main.rs b/kic/src/main.rs index 5094548..f60a1e1 100644 --- a/kic/src/main.rs +++ b/kic/src/main.rs @@ -257,7 +257,7 @@ fn main() -> anyhow::Result<()> { let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -298,7 +298,7 @@ fn main() -> anyhow::Result<()> { let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -327,7 +327,7 @@ fn main() -> anyhow::Result<()> { let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default() .with(LevelFilter::TRACE) @@ -350,7 +350,7 @@ fn main() -> anyhow::Result<()> { let sock = tracing_subscriber::fmt::layer() .with_writer(Mutex::new(sock)) .fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new()) - .with_ansi(false); + .json(); let logger = Registry::default().with(LevelFilter::TRACE).with(sock); From aaae09764e2d25db526020cc0d2d88c79976a6db Mon Sep 17 00:00:00 2001 From: "Sarver, Edwin" Date: Thu, 25 Jul 2024 13:41:09 -0400 Subject: [PATCH 3/3] Update Changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c7d7b..64673dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,11 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [0.17.0] +### Added +- Added logging infrastructure over socket, in files, and to stderr in `kic` and `kic-discover`. + ### Fixed -- Fixed an indexing issue for uploading modules (TSP-761) *Open Source Contribution: c3charvat, amcooper181* +- Fixed an indexing issue for upgrading module firmware (TSP-761) *Open Source Contribution: c3charvat, amcooper181* ## [0.16.2]