diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index b8b44406a..8afc218eb 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -6,8 +6,10 @@ All notable changes to this project will be documented in this file. ### Added -- Adds the `--file-log-max-files` CLI argument and `FILE_LOG_MAX_FILES` environment variable - see detailed [stackable-telemetry changelog](../stackable-telemetry/CHANGELOG.md) ([#1010]). +- Adds new CLI arguments and environment variables ([#1010], [#1012]). + - Use `--file-log-max-files` (or `FILE_LOG_MAX_FILES`) to limit the number of log files kept. + - Use `--console-log-format` (or `CONSOLE_LOG_FORMAT`) to set the format to `plain` (default) or `json`. + - See detailed [stackable-telemetry changelog](../stackable-telemetry/CHANGELOG.md). ### Changed @@ -16,6 +18,7 @@ All notable changes to this project will be documented in this file. [#1009]: https://github.com/stackabletech/operator-rs/pull/1009 [#1010]: https://github.com/stackabletech/operator-rs/pull/1010 +[#1012]: https://github.com/stackabletech/operator-rs/pull/1012 ## [0.91.1] - 2025-04-09 diff --git a/crates/stackable-telemetry/CHANGELOG.md b/crates/stackable-telemetry/CHANGELOG.md index d83b60b34..8ea4be116 100644 --- a/crates/stackable-telemetry/CHANGELOG.md +++ b/crates/stackable-telemetry/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Add support for JSON console log output ([#1012]). + - A new CLI argument was added: `--console-log-format`. It can be set to `plain` (default), + or `json`. + ### Changed - BREAKING: Update and align telemetry related CLI arguments in `TelemetryOptions` ([#1009]). @@ -25,6 +31,7 @@ All notable changes to this project will be documented in this file. [#1009]: https://github.com/stackabletech/operator-rs/pull/1009 [#1010]: https://github.com/stackabletech/operator-rs/pull/1010 +[#1012]: https://github.com/stackabletech/operator-rs/pull/1012 ## [0.5.0] - 2025-04-08 diff --git a/crates/stackable-telemetry/src/tracing/mod.rs b/crates/stackable-telemetry/src/tracing/mod.rs index 7b1026e38..0d4562be0 100644 --- a/crates/stackable-telemetry/src/tracing/mod.rs +++ b/crates/stackable-telemetry/src/tracing/mod.rs @@ -6,7 +6,7 @@ //! //! To get started, see [`Tracing`]. -use std::path::PathBuf; +use std::{ops::Not, path::PathBuf}; #[cfg_attr(feature = "clap", cfg(doc))] use clap; @@ -105,6 +105,7 @@ pub enum Error { /// async fn main() -> Result<(), Error> { /// let options = TelemetryOptions { /// console_log_disabled: false, +/// console_log_format: Default::default(), /// file_log_directory: None, /// file_log_rotation_period: None, /// file_log_max_files: Some(6), @@ -347,6 +348,7 @@ impl Tracing { pub fn pre_configured(service_name: &'static str, options: TelemetryOptions) -> Self { let TelemetryOptions { console_log_disabled, + console_log_format, file_log_directory, file_log_rotation_period, file_log_max_files, @@ -358,11 +360,14 @@ impl Tracing { Self::builder() .service_name(service_name) - .with_console_output(( - Self::CONSOLE_LOG_LEVEL_ENV, - LevelFilter::INFO, - !console_log_disabled, - )) + .with_console_output(console_log_disabled.not().then(|| { + Settings::builder() + .with_environment_variable(Self::CONSOLE_LOG_LEVEL_ENV) + .with_default_level(LevelFilter::INFO) + .console_log_settings_builder() + .with_log_format(console_log_format) + .build() + })) .with_file_output(file_log_directory.map(|log_directory| { Settings::builder() .with_environment_variable(Self::FILE_LOG_LEVEL_ENV) @@ -397,16 +402,29 @@ impl Tracing { if let ConsoleLogSettings::Enabled { common_settings, - log_format: _, + log_format, } = &self.console_log_settings { let env_filter_layer = env_filter_builder( common_settings.environment_variable, common_settings.default_level, ); - let console_output_layer = - tracing_subscriber::fmt::layer().with_filter(env_filter_layer); - layers.push(console_output_layer.boxed()); + + // NOTE (@NickLarsenNZ): There is no elegant way to build the layer depending on formats because the types + // returned from each subscriber "modifier" function is different (sometimes with different generics). + match log_format { + Format::Plain => { + let console_output_layer = + tracing_subscriber::fmt::layer().with_filter(env_filter_layer); + layers.push(console_output_layer.boxed()); + } + Format::Json => { + let console_output_layer = tracing_subscriber::fmt::layer() + .json() + .with_filter(env_filter_layer); + layers.push(console_output_layer.boxed()); + } + }; } if let FileLogSettings::Enabled { @@ -761,9 +779,16 @@ struct Cli { #[derive(Debug, Default)] pub struct TelemetryOptions { /// Disable console logs. - #[cfg_attr(feature = "clap", arg(long, env))] + #[cfg_attr(feature = "clap", arg(long, env, group = "console_log"))] pub console_log_disabled: bool, + /// Console log format. + #[cfg_attr( + feature = "clap", + arg(long, env, group = "console_log", default_value_t) + )] + pub console_log_format: Format, + /// Enable logging to files located in the specified DIRECTORY. #[cfg_attr( feature = "clap", @@ -1023,6 +1048,7 @@ mod test { fn pre_configured() { let tracing = Tracing::pre_configured("test", TelemetryOptions { console_log_disabled: false, + console_log_format: Default::default(), file_log_directory: None, file_log_rotation_period: None, file_log_max_files: None, diff --git a/crates/stackable-telemetry/src/tracing/settings/console_log.rs b/crates/stackable-telemetry/src/tracing/settings/console_log.rs index 469eaea7c..cdcd43637 100644 --- a/crates/stackable-telemetry/src/tracing/settings/console_log.rs +++ b/crates/stackable-telemetry/src/tracing/settings/console_log.rs @@ -24,7 +24,10 @@ pub enum ConsoleLogSettings { /// Console subscriber log event output formats. /// /// Currently, only [Plain][Format::Plain] is supported. -#[derive(Debug, Default, PartialEq)] +#[derive( + Clone, Debug, Default, Eq, PartialEq, strum::EnumString, strum::Display, clap::ValueEnum, +)] +#[strum(serialize_all = "snake_case")] pub enum Format { /// Use the plain unstructured log output. /// @@ -34,7 +37,9 @@ pub enum Format { /// See: [`Layer::with_ansi`][tracing_subscriber::fmt::Layer::with_ansi]. #[default] Plain, - // Json { pretty: bool }, + + /// Use structured JSON log output. + Json, // LogFmt, }