From 532abc61fbed1c690a5c455b47a8c07e1f3bee3f Mon Sep 17 00:00:00 2001 From: Jordan Gonzalez <30836115+duncanista@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:17:40 -0400 Subject: [PATCH 1/4] chore(deps): bump datadog-agent-config to f76e911, drop local dd_org_uuid PR DataDog/serverless-components#137 landed dd_org_uuid as a top-level field on the upstream Config struct, sourced from DD_ORG_UUID (env) and org_uuid (datadog.yaml). Bumps the pin and removes the now-redundant local copy from LambdaConfig and LambdaConfigSource. - LambdaConfig: drop `dd_org_uuid: String` - LambdaConfigSource: drop `org_uuid: Option` and the merge_string! source-to-config renaming call in merge_from - Consumers (secrets/decrypt.rs, secrets/delegated_auth/client.rs) switch from `config.ext.dd_org_uuid` to `config.dd_org_uuid` - Tests update to assert on the upstream field; pinning works through the same env/yaml surface, only the field location moved - Drop the unused `deserialize_string_or_int` import --- bottlecap/Cargo.lock | 34 +++++-------------- bottlecap/Cargo.toml | 6 ++-- bottlecap/src/config/mod.rs | 23 ++----------- bottlecap/src/secrets/decrypt.rs | 4 +-- .../src/secrets/delegated_auth/client.rs | 2 +- 5 files changed, 18 insertions(+), 51 deletions(-) diff --git a/bottlecap/Cargo.lock b/bottlecap/Cargo.lock index 3eacd5c28..9bbaf8a4b 100644 --- a/bottlecap/Cargo.lock +++ b/bottlecap/Cargo.lock @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "datadog-agent-config" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=bb4dedeee20b949db3143c05e5a779b843a8a484#bb4dedeee20b949db3143c05e5a779b843a8a484" +source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" dependencies = [ "datadog-opentelemetry", "dogstatsd", @@ -800,7 +800,7 @@ dependencies = [ [[package]] name = "datadog-fips" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=bb4dedeee20b949db3143c05e5a779b843a8a484#bb4dedeee20b949db3143c05e5a779b843a8a484" +source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" dependencies = [ "reqwest", "rustls", @@ -942,7 +942,7 @@ dependencies = [ [[package]] name = "dogstatsd" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=bb4dedeee20b949db3143c05e5a779b843a8a484#bb4dedeee20b949db3143c05e5a779b843a8a484" +source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" dependencies = [ "datadog-protos", "ddsketch-agent", @@ -1072,12 +1072,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - [[package]] name = "flate2" version = "1.1.9" @@ -1629,7 +1623,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.3", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1841,7 +1835,7 @@ dependencies = [ "ena", "itertools 0.11.0", "lalrpop-util", - "petgraph 0.6.5", + "petgraph", "pico-args", "regex", "regex-syntax", @@ -2654,17 +2648,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ - "fixedbitset 0.4.2", - "indexmap", -] - -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset 0.5.7", + "fixedbitset", "indexmap", ] @@ -2864,7 +2848,7 @@ dependencies = [ "log", "multimap", "once_cell", - "petgraph 0.7.1", + "petgraph", "prettyplease", "prost 0.13.5", "prost-types 0.13.5", @@ -2988,7 +2972,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.3", + "socket2 0.5.10", "thiserror 2.0.18", "tokio", "tracing", @@ -3025,7 +3009,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.3", + "socket2 0.5.10", "tracing", "windows-sys 0.60.2", ] diff --git a/bottlecap/Cargo.toml b/bottlecap/Cargo.toml index b3ef5c58d..ca4fdf743 100644 --- a/bottlecap/Cargo.toml +++ b/bottlecap/Cargo.toml @@ -82,9 +82,9 @@ libdd-trace-normalization = { git = "https://github.com/DataDog/libdatadog", rev libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "48da0d82cb32b43d4cdece35b794c9bcbc275a03", default-features = false } libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog", rev = "48da0d82cb32b43d4cdece35b794c9bcbc275a03", default-features = false } datadog-opentelemetry = { git = "https://github.com/DataDog/dd-trace-rs", rev = "f51cefc4ad24bec81b38fb2f36b1ed93f21ae913", default-features = false } -dogstatsd = { git = "https://github.com/DataDog/serverless-components", rev = "bb4dedeee20b949db3143c05e5a779b843a8a484", default-features = false } -datadog-fips = { git = "https://github.com/DataDog/serverless-components", rev = "bb4dedeee20b949db3143c05e5a779b843a8a484", default-features = false } -datadog-agent-config = { git = "https://github.com/DataDog/serverless-components", rev = "bb4dedeee20b949db3143c05e5a779b843a8a484", default-features = false } +dogstatsd = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } +datadog-fips = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } +datadog-agent-config = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } libddwaf = { version = "1.28.1", git = "https://github.com/DataDog/libddwaf-rust", rev = "d1534a158d976bd4f747bf9fcc58e0712d2d17fc", default-features = false, features = ["serde"] } [dev-dependencies] diff --git a/bottlecap/src/config/mod.rs b/bottlecap/src/config/mod.rs index e9ce7f331..54a9fc168 100644 --- a/bottlecap/src/config/mod.rs +++ b/bottlecap/src/config/mod.rs @@ -45,7 +45,7 @@ use datadog_agent_config::{ deserialize_optional_duration_from_microseconds as deser_dur_micros, deserialize_optional_duration_from_seconds as deser_dur_secs, deserialize_optional_duration_from_seconds_ignore_zero as deser_dur_secs_ignore_zero, - deserialize_optional_string as deser_opt_str, deserialize_string_or_int as deser_str_or_int, + deserialize_optional_string as deser_opt_str, flush_strategy::FlushStrategy as UpstreamFlushStrategy, }; @@ -68,7 +68,6 @@ pub struct LambdaConfig { pub lambda_extension_compute_stats: bool, pub span_dedup_timeout: Option, pub api_key_secret_reload_interval: Option, - pub dd_org_uuid: String, pub serverless_appsec_enabled: bool, pub appsec_rules: Option, pub appsec_waf_timeout: Duration, @@ -98,7 +97,6 @@ impl Default for LambdaConfig { lambda_extension_compute_stats: false, span_dedup_timeout: None, api_key_secret_reload_interval: None, - dd_org_uuid: String::new(), serverless_appsec_enabled: false, appsec_rules: None, appsec_waf_timeout: Duration::from_millis(5), @@ -154,12 +152,6 @@ pub struct LambdaConfigSource { #[serde(deserialize_with = "deser_dur_secs_ignore_zero")] pub api_key_secret_reload_interval: Option, - /// `DD_ORG_UUID` — when set, delegated auth is auto-enabled. The source - /// field is `org_uuid` (matching the env var) and merges into the - /// `dd_org_uuid` config field. - #[serde(deserialize_with = "deser_str_or_int")] - pub org_uuid: Option, - #[serde(deserialize_with = "deser_opt_bool")] pub serverless_appsec_enabled: Option, #[serde(deserialize_with = "deser_opt_str")] @@ -218,9 +210,6 @@ impl DatadogConfigExtension for LambdaConfig { || source.logs_enabled.unwrap_or(false); } - // org_uuid (source) → dd_org_uuid (config) - datadog_agent_config::merge_string!(self, dd_org_uuid, source, org_uuid); - // lambda_customer_metrics_exclude_tags (source) → custom_metrics_exclude_tags (config) if !source.lambda_customer_metrics_exclude_tags.is_empty() { self.custom_metrics_exclude_tags @@ -598,10 +587,7 @@ mod lambda_config_tests { jail.set_env("DD_ORG_UUID", "00000000-1111-2222-3333-444444444444"); Ok(()) }); - assert_eq!( - config.ext.dd_org_uuid, - "00000000-1111-2222-3333-444444444444" - ); + assert_eq!(config.dd_org_uuid, "00000000-1111-2222-3333-444444444444"); } #[test] @@ -615,10 +601,7 @@ mod lambda_config_tests { )?; Ok(()) }); - assert_eq!( - config.ext.dd_org_uuid, - "00000000-1111-2222-3333-444444444444" - ); + assert_eq!(config.dd_org_uuid, "00000000-1111-2222-3333-444444444444"); } #[test] diff --git a/bottlecap/src/secrets/decrypt.rs b/bottlecap/src/secrets/decrypt.rs index cde54a56a..23e4be81c 100644 --- a/bottlecap/src/secrets/decrypt.rs +++ b/bottlecap/src/secrets/decrypt.rs @@ -26,7 +26,7 @@ pub async fn resolve_secrets( let api_key_candidate = if !config.ext.api_key_secret_arn.is_empty() || !config.ext.kms_api_key.is_empty() || !config.ext.api_key_ssm_arn.is_empty() - || !config.ext.dd_org_uuid.is_empty() + || !config.dd_org_uuid.is_empty() { let before_decrypt = Instant::now(); @@ -48,7 +48,7 @@ pub async fn resolve_secrets( let aws_credentials = get_aws_credentials(&client).await?; - let decrypted_key = if !config.ext.dd_org_uuid.is_empty() { + let decrypted_key = if !config.dd_org_uuid.is_empty() { delegated_auth::get_delegated_api_key( &config, &aws_config, diff --git a/bottlecap/src/secrets/delegated_auth/client.rs b/bottlecap/src/secrets/delegated_auth/client.rs index 29ea70a54..ae995d2e2 100644 --- a/bottlecap/src/secrets/delegated_auth/client.rs +++ b/bottlecap/src/secrets/delegated_auth/client.rs @@ -35,7 +35,7 @@ pub async fn get_delegated_api_key( ) -> Result> { debug!("Attempting to get API key via delegated auth"); - let proof = generate_auth_proof(aws_credentials, &aws_config.region, &config.ext.dd_org_uuid)?; + let proof = generate_auth_proof(aws_credentials, &aws_config.region, &config.dd_org_uuid)?; let url = get_api_endpoint(&config.site); debug!("Requesting delegated API key from: {}", url); From a3a23b89d2edbb864f9828925916c0d0d4e926c9 Mon Sep 17 00:00:00 2001 From: Jordan Gonzalez <30836115+duncanista@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:46:54 -0400 Subject: [PATCH 2/4] chore(deps): bump to 8ce37eb (adds upstream logs_enabled), document alias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream DataDog/serverless-components#138 landed `Config::logs_enabled` as a top-level field sourced from `DD_LOGS_ENABLED` / `logs_enabled` (yaml), default `false`. Bumps the pin from f76e911 -> 8ce37eb. The lambda extension's existing OR-merge contract is preserved exactly: DD_SERVERLESS_LOGS_ENABLED and DD_LOGS_ENABLED are still OR-merged into config.ext.serverless_logs_enabled, and the default-true is still kept only when neither env var is explicitly set. To do that without losing "was DD_LOGS_ENABLED explicitly set?" information, the alias source field on LambdaConfigSource is retained — the upstream parsing of the same env var into config.logs_enabled is intentional and runs in parallel for non-lambda consumers. Lambda call sites continue to gate log shipping on config.ext.serverless_logs_enabled. No behavior change for customers. Adds a regression test for the "DD_LOGS_ENABLED=false alone disables logs" edge case so a future refactor that breaks it fails loudly. --- bottlecap/Cargo.lock | 12 ++++---- bottlecap/Cargo.toml | 6 ++-- bottlecap/src/config/mod.rs | 60 ++++++++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/bottlecap/Cargo.lock b/bottlecap/Cargo.lock index 9bbaf8a4b..285e4b0c5 100644 --- a/bottlecap/Cargo.lock +++ b/bottlecap/Cargo.lock @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "datadog-agent-config" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" +source = "git+https://github.com/DataDog/serverless-components?rev=8ce37eb029410b7cf30847376772e3af6baa5f5c#8ce37eb029410b7cf30847376772e3af6baa5f5c" dependencies = [ "datadog-opentelemetry", "dogstatsd", @@ -800,7 +800,7 @@ dependencies = [ [[package]] name = "datadog-fips" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" +source = "git+https://github.com/DataDog/serverless-components?rev=8ce37eb029410b7cf30847376772e3af6baa5f5c#8ce37eb029410b7cf30847376772e3af6baa5f5c" dependencies = [ "reqwest", "rustls", @@ -942,7 +942,7 @@ dependencies = [ [[package]] name = "dogstatsd" version = "0.1.0" -source = "git+https://github.com/DataDog/serverless-components?rev=f76e9118433bb4a36dd0a3572a3566f5047a8b4c#f76e9118433bb4a36dd0a3572a3566f5047a8b4c" +source = "git+https://github.com/DataDog/serverless-components?rev=8ce37eb029410b7cf30847376772e3af6baa5f5c#8ce37eb029410b7cf30847376772e3af6baa5f5c" dependencies = [ "datadog-protos", "ddsketch-agent", @@ -1623,7 +1623,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.3", "tokio", "tower-service", "tracing", @@ -2972,7 +2972,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.5.10", + "socket2 0.6.3", "thiserror 2.0.18", "tokio", "tracing", @@ -3009,7 +3009,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.3", "tracing", "windows-sys 0.60.2", ] diff --git a/bottlecap/Cargo.toml b/bottlecap/Cargo.toml index ca4fdf743..714afa77f 100644 --- a/bottlecap/Cargo.toml +++ b/bottlecap/Cargo.toml @@ -82,9 +82,9 @@ libdd-trace-normalization = { git = "https://github.com/DataDog/libdatadog", rev libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "48da0d82cb32b43d4cdece35b794c9bcbc275a03", default-features = false } libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog", rev = "48da0d82cb32b43d4cdece35b794c9bcbc275a03", default-features = false } datadog-opentelemetry = { git = "https://github.com/DataDog/dd-trace-rs", rev = "f51cefc4ad24bec81b38fb2f36b1ed93f21ae913", default-features = false } -dogstatsd = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } -datadog-fips = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } -datadog-agent-config = { git = "https://github.com/DataDog/serverless-components", rev = "f76e9118433bb4a36dd0a3572a3566f5047a8b4c", default-features = false } +dogstatsd = { git = "https://github.com/DataDog/serverless-components", rev = "8ce37eb029410b7cf30847376772e3af6baa5f5c", default-features = false } +datadog-fips = { git = "https://github.com/DataDog/serverless-components", rev = "8ce37eb029410b7cf30847376772e3af6baa5f5c", default-features = false } +datadog-agent-config = { git = "https://github.com/DataDog/serverless-components", rev = "8ce37eb029410b7cf30847376772e3af6baa5f5c", default-features = false } libddwaf = { version = "1.28.1", git = "https://github.com/DataDog/libddwaf-rust", rev = "d1534a158d976bd4f747bf9fcc58e0712d2d17fc", default-features = false, features = ["serde"] } [dev-dependencies] diff --git a/bottlecap/src/config/mod.rs b/bottlecap/src/config/mod.rs index 54a9fc168..fca2c7436 100644 --- a/bottlecap/src/config/mod.rs +++ b/bottlecap/src/config/mod.rs @@ -124,11 +124,19 @@ pub struct LambdaConfigSource { #[serde(deserialize_with = "deser_opt_str")] pub api_key_ssm_arn: Option, - /// `DD_SERVERLESS_LOGS_ENABLED` — primary toggle for Lambda log shipping. + /// `DD_SERVERLESS_LOGS_ENABLED` — Lambda-specific log toggle, kept for + /// backwards compatibility. Defaults to `true` (the Lambda extension's + /// historical behavior). #[serde(deserialize_with = "deser_opt_bool")] pub serverless_logs_enabled: Option, - /// `DD_LOGS_ENABLED` — alias for `serverless_logs_enabled`; OR-merged so - /// either being `true` turns logs on. See `merge_from` below. + /// `DD_LOGS_ENABLED` — alias surface kept on the lambda source side + /// purely so we can detect "was it explicitly set?" and preserve the + /// legacy OR-merge semantics with `serverless_logs_enabled` (see + /// `merge_from`). The canonical `Config::logs_enabled` upstream field + /// is also populated by the upstream env/yaml parsing; lambda call + /// sites that gate on log shipping should keep using + /// `config.ext.serverless_logs_enabled`, which the merge logic below + /// reconciles with this alias. #[serde(deserialize_with = "deser_opt_bool")] pub logs_enabled: Option, @@ -202,9 +210,15 @@ impl DatadogConfigExtension for LambdaConfig { option: [span_dedup_timeout, api_key_secret_reload_interval, appsec_rules], ); - // OR-merge serverless_logs_enabled with the logs_enabled alias. Either - // env var set to `true` enables logs; if both are absent the default - // (true) is preserved. + // Preserve legacy OR-merge semantics: when either env var is + // explicitly set, the resolved value is the OR of the two (unset + // counts as false for the OR). When neither is set, the default + // (true) is preserved. This invariant — in particular that setting + // only DD_LOGS_ENABLED=false disables logs — predates upstream + // owning `logs_enabled` and must be kept. The duplicate parse of + // DD_LOGS_ENABLED (once upstream, once here via the alias) is + // intentional: upstream populates `config.logs_enabled` for any + // non-lambda consumer, while this branch keeps the lambda contract. if source.serverless_logs_enabled.is_some() || source.logs_enabled.is_some() { self.serverless_logs_enabled = source.serverless_logs_enabled.unwrap_or(false) || source.logs_enabled.unwrap_or(false); @@ -305,6 +319,14 @@ mod lambda_config_tests { } // ---- serverless_logs_enabled with OR-merge alias ---- + // + // The legacy contract: DD_SERVERLESS_LOGS_ENABLED and DD_LOGS_ENABLED are + // OR-merged into config.ext.serverless_logs_enabled. The default (true) + // is preserved iff neither env var was explicitly set; otherwise the + // resolved value is the OR of the two (unset counts as false). The + // upstream `Config::logs_enabled` field is also populated independently + // (sourced by the upstream env/yaml parsing), but lambda call sites that + // gate on log shipping continue to use serverless_logs_enabled. #[test] fn serverless_logs_enabled_defaults_true() { @@ -332,7 +354,7 @@ mod lambda_config_tests { } #[test] - fn logs_enabled_alias_only() { + fn logs_enabled_alias_only_true() { let config = load(|jail| { jail.set_env("DD_LOGS_ENABLED", "true"); Ok(()) @@ -340,6 +362,18 @@ mod lambda_config_tests { assert!(config.ext.serverless_logs_enabled); } + #[test] + fn logs_enabled_alias_only_false_overrides_default() { + // Setting only DD_LOGS_ENABLED=false must disable logs, overriding + // the default-true. This is the legacy behavior that the alias-only + // entry into the OR-merge guards. + let config = load(|jail| { + jail.set_env("DD_LOGS_ENABLED", "false"); + Ok(()) + }); + assert!(!config.ext.serverless_logs_enabled); + } + #[test] fn serverless_logs_disabled_when_both_false() { let config = load(|jail| { @@ -359,6 +393,18 @@ mod lambda_config_tests { assert!(!config.ext.serverless_logs_enabled); } + #[test] + fn dd_logs_enabled_also_populates_upstream_field() { + // The upstream Config::logs_enabled field is wired through the + // upstream env parsing independently of the lambda alias. Lambda + // doesn't read this field, but other consumers of the same crate do. + let config = load(|jail| { + jail.set_env("DD_LOGS_ENABLED", "true"); + Ok(()) + }); + assert!(config.logs_enabled); + } + // ---- FlushStrategy ---- #[test] From e4f5541d09cd32bf0b8bc3f1a6549e803fe09ca9 Mon Sep 17 00:00:00 2001 From: Jordan Gonzalez <30836115+duncanista@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:50:18 -0400 Subject: [PATCH 3/4] docs(secrets): update delegated_auth client doc for renamed config field Address Copilot review: the doc on get_delegated_api_key still mentioned config.org_uuid, but after the upstream migration the value lives at config.dd_org_uuid (top-level, not under .ext). --- bottlecap/src/secrets/delegated_auth/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlecap/src/secrets/delegated_auth/client.rs b/bottlecap/src/secrets/delegated_auth/client.rs index ae995d2e2..fa56ba1fd 100644 --- a/bottlecap/src/secrets/delegated_auth/client.rs +++ b/bottlecap/src/secrets/delegated_auth/client.rs @@ -16,7 +16,7 @@ const INTAKE_KEY_ENDPOINT: &str = "/api/v2/intake-key"; /// 3. Returns the managed API key /// /// # Arguments -/// * `config` - The extension configuration containing site and `org_uuid` +/// * `config` - The agent configuration containing `site` and `dd_org_uuid` /// * `aws_config` - The AWS configuration containing region /// * `client` - A pre-built `reqwest::Client` to use for the request. The client is built /// with `create_reqwest_client_builder()` which respects proxy configuration via From 39f7acefc129f778b332f3287674805dbebb0533 Mon Sep 17 00:00:00 2001 From: Jordan Gonzalez <30836115+duncanista@users.noreply.github.com> Date: Thu, 18 Jun 2026 17:05:04 -0400 Subject: [PATCH 4/4] docs(config): clarify why DD_LOGS_ENABLED is deserialized twice Tighten the doc comment on the LambdaConfigSource alias to lead with the real reason: lambda defaults logs to true, upstream defaults to false, so the alias is needed to preserve the legacy default-true + OR-merge behavior. --- bottlecap/src/config/mod.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/bottlecap/src/config/mod.rs b/bottlecap/src/config/mod.rs index fca2c7436..db0a1f192 100644 --- a/bottlecap/src/config/mod.rs +++ b/bottlecap/src/config/mod.rs @@ -129,14 +129,12 @@ pub struct LambdaConfigSource { /// historical behavior). #[serde(deserialize_with = "deser_opt_bool")] pub serverless_logs_enabled: Option, - /// `DD_LOGS_ENABLED` — alias surface kept on the lambda source side - /// purely so we can detect "was it explicitly set?" and preserve the - /// legacy OR-merge semantics with `serverless_logs_enabled` (see - /// `merge_from`). The canonical `Config::logs_enabled` upstream field - /// is also populated by the upstream env/yaml parsing; lambda call - /// sites that gate on log shipping should keep using - /// `config.ext.serverless_logs_enabled`, which the merge logic below - /// reconciles with this alias. + /// `DD_LOGS_ENABLED` — deserialized here a second time (the canonical + /// `Config::logs_enabled` upstream field is also populated by the upstream + /// env/yaml parsing) because lambda's default for logs is `true` while + /// upstream's is `false`. Keeping the alias as `Option` lets + /// `merge_from` detect "was it explicitly set?" and OR-merge it into + /// `serverless_logs_enabled` — that is the field lambda call sites read. #[serde(deserialize_with = "deser_opt_bool")] pub logs_enabled: Option,