diff --git a/Cargo.toml b/Cargo.toml index 26db776ee0..fefdb2d3aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,6 +101,9 @@ kube.workspace = true trust-dns-resolver = { version = "0.23.0", features = ["tokio", "tokio-rustls", "dns-over-https-rustls"] } async-trait = "0.1.73" nom = "7.1.3" +atty = "0.2.14" +strum = "0.25.0" +strum_macros = "0.25" [target.'cfg(target_os = "linux")'.dependencies] sys-info = "0.9.1" diff --git a/src/cli.rs b/src/cli.rs index 1ac73b0fe7..556f06f103 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -19,10 +19,12 @@ use std::{ sync::Arc, }; +use clap::builder::TypedValueParser; use clap::crate_version; use tokio::{signal, sync::watch}; use crate::{admin::Mode, Config}; +use strum_macros::{Display, EnumString}; pub use self::{ agent::Agent, generate_config_schema::GenerateConfigSchema, manage::Manage, proxy::Proxy, @@ -68,6 +70,27 @@ pub struct Cli { pub quiet: bool, #[clap(subcommand)] pub command: Commands, + #[clap( + long, + default_value_t = LogFormats::Auto, + value_parser = clap::builder::PossibleValuesParser::new(["auto", "json", "plain", "pretty"]) + .map(|s| s.parse::().unwrap()), + )] + pub log_format: LogFormats, +} + +/// The various log format options +#[derive(Copy, Clone, PartialEq, Eq, Debug, EnumString, Display, Default)] +pub enum LogFormats { + #[strum(serialize = "auto")] + #[default] + Auto, + #[strum(serialize = "json")] + Json, + #[strum(serialize = "plain")] + Plain, + #[strum(serialize = "pretty")] + Pretty, } /// The various Quilkin commands. @@ -101,11 +124,22 @@ impl Cli { let env_filter = tracing_subscriber::EnvFilter::builder() .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) .from_env_lossy(); - tracing_subscriber::fmt() - .json() + let subscriber = tracing_subscriber::fmt() .with_file(true) - .with_env_filter(env_filter) - .init(); + .with_env_filter(env_filter); + + match self.log_format { + LogFormats::Auto => { + if atty::isnt(atty::Stream::Stdout) { + subscriber.json().init(); + } else { + subscriber.init(); + } + } + LogFormats::Json => subscriber.json().init(), + LogFormats::Plain => subscriber.init(), + LogFormats::Pretty => subscriber.pretty().init(), + } } tracing::info!( @@ -307,6 +341,7 @@ mod tests { }), ..<_>::default() }), + log_format: LogFormats::default(), }; let control_plane_admin_port = crate::test_utils::available_addr().await.port(); @@ -325,6 +360,7 @@ mod tests { path: endpoints_file.path().to_path_buf(), }, }), + log_format: LogFormats::default(), }; let proxy_admin_port = crate::test_utils::available_addr().await.port(); @@ -337,6 +373,7 @@ mod tests { management_server: vec!["http://localhost:7800".parse().unwrap()], ..<_>::default() }), + log_format: LogFormats::default(), }; tokio::spawn(relay.drive());