From d4b6766a609336477d0a6a6fa3d75998dbeee9ac Mon Sep 17 00:00:00 2001 From: Tianning Li Date: Thu, 13 Nov 2025 14:47:20 -0500 Subject: [PATCH] feat: Add support for DD_LOGS_ENABLED as alias for DD_SERVERLESS_LOGS_ENABLED SVLS-7818 --- bottlecap/src/config/env.rs | 172 ++++++++++++++++++++++++++++++++++- bottlecap/src/config/yaml.rs | 10 +- 2 files changed, 180 insertions(+), 2 deletions(-) diff --git a/bottlecap/src/config/env.rs b/bottlecap/src/config/env.rs index f0b6c075a..8b41e6e1f 100644 --- a/bottlecap/src/config/env.rs +++ b/bottlecap/src/config/env.rs @@ -362,6 +362,11 @@ pub struct EnvConfig { /// Enable logs for AWS Lambda. Default is `true`. #[serde(deserialize_with = "deserialize_optional_bool_from_anything")] pub serverless_logs_enabled: Option, + /// @env `DD_LOGS_ENABLED` + /// + /// Enable logs for AWS Lambda. Alias for `DD_SERVERLESS_LOGS_ENABLED`. Default is `true`. + #[serde(deserialize_with = "deserialize_optional_bool_from_anything")] + pub logs_enabled: Option, /// @env `DD_SERVERLESS_FLUSH_STRATEGY` /// /// The flush strategy to use for AWS Lambda. @@ -609,7 +614,13 @@ fn merge_config(config: &mut Config, env_config: &EnvConfig) { // AWS Lambda merge_string!(config, env_config, api_key_secret_arn); merge_string!(config, env_config, kms_api_key); - merge_option_to_value!(config, env_config, serverless_logs_enabled); + + // Handle serverless_logs_enabled with OR logic: if either DD_LOGS_ENABLED or DD_SERVERLESS_LOGS_ENABLED is true, enable logs + if env_config.serverless_logs_enabled.is_some() || env_config.logs_enabled.is_some() { + config.serverless_logs_enabled = env_config.serverless_logs_enabled.unwrap_or(false) + || env_config.logs_enabled.unwrap_or(false); + } + merge_option_to_value!(config, env_config, serverless_flush_strategy); merge_option_to_value!(config, env_config, enhanced_metrics); merge_option_to_value!(config, env_config, lambda_proc_enhanced_metrics); @@ -974,4 +985,163 @@ mod tests { Ok(()) }); } + + #[test] + fn test_dd_logs_enabled_true() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "true"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_dd_logs_enabled_false() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "false"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(!config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_dd_serverless_logs_enabled_true() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "true"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_dd_serverless_logs_enabled_false() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "false"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(!config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_both_logs_enabled_true() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "true"); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "true"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_both_logs_enabled_false() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "false"); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "false"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + assert!(!config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_logs_enabled_true_serverless_logs_enabled_false() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "true"); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "false"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + // OR logic: if either is true, logs are enabled + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_logs_enabled_false_serverless_logs_enabled_true() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + jail.set_env("DD_LOGS_ENABLED", "false"); + jail.set_env("DD_SERVERLESS_LOGS_ENABLED", "true"); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + // OR logic: if either is true, logs are enabled + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } + + #[test] + fn test_neither_logs_enabled_set_uses_default() { + figment::Jail::expect_with(|jail| { + jail.clear_env(); + + let mut config = Config::default(); + let env_config_source = EnvConfigSource; + env_config_source + .load(&mut config) + .expect("Failed to load config"); + + // Default value is true + assert!(config.serverless_logs_enabled); + Ok(()) + }); + } } diff --git a/bottlecap/src/config/yaml.rs b/bottlecap/src/config/yaml.rs index c800455f7..1624f8eb8 100644 --- a/bottlecap/src/config/yaml.rs +++ b/bottlecap/src/config/yaml.rs @@ -101,6 +101,8 @@ pub struct YamlConfig { pub kms_api_key: Option, #[serde(deserialize_with = "deserialize_optional_bool_from_anything")] pub serverless_logs_enabled: Option, + #[serde(deserialize_with = "deserialize_optional_bool_from_anything")] + pub logs_enabled: Option, pub serverless_flush_strategy: Option, #[serde(deserialize_with = "deserialize_optional_bool_from_anything")] pub enhanced_metrics: Option, @@ -671,7 +673,13 @@ fn merge_config(config: &mut Config, yaml_config: &YamlConfig) { // AWS Lambda merge_string!(config, yaml_config, api_key_secret_arn); merge_string!(config, yaml_config, kms_api_key); - merge_option_to_value!(config, yaml_config, serverless_logs_enabled); + + // Handle serverless_logs_enabled with OR logic: if either logs_enabled or serverless_logs_enabled is true, enable logs + if yaml_config.serverless_logs_enabled.is_some() || yaml_config.logs_enabled.is_some() { + config.serverless_logs_enabled = yaml_config.serverless_logs_enabled.unwrap_or(false) + || yaml_config.logs_enabled.unwrap_or(false); + } + merge_option_to_value!(config, yaml_config, serverless_flush_strategy); merge_option_to_value!(config, yaml_config, enhanced_metrics); merge_option_to_value!(config, yaml_config, lambda_proc_enhanced_metrics);