Skip to content

chore(config): fix env-overlay behavior and saluki only shape#1986

Open
webern wants to merge 6 commits into
mainfrom
m/pr3b-env-keys
Open

chore(config): fix env-overlay behavior and saluki only shape#1986
webern wants to merge 6 commits into
mainfrom
m/pr3b-env-keys

Conversation

@webern

@webern webern commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Human Summary

Part of the typed config initiative, this PR retains ADP's ability to read DD_* environment
variables for dotted config paths. The alias paths are created from the schema and added to the
deserialization logic of DatadogConfiguration.

It is debatable whether this should be done when we are receiving our authoritative config from the
Agent, but it is definitely needed in standalone mode, so the behavior is retained during the
typed-config migration.

AI Summary

Preserves environment-variable reachability when ADP deserializes its complete typed source models
instead of querying individual keys from GenericConfiguration.

For DatadogConfiguration, environment variables enter the merged map as flat keys while the
generated model expects nested paths. A generated table maps each supported Datadog key's actual
Agent environment-variable names to its nested path. It records alias priority, handles declared
environment names that differ from a mechanical .-to-_ conversion, and preserves the Agent's
handling of string-list values.

For SalukiOnly, there is deliberately no key table or alias list. A recording serde deserializer
discovers the canonical leaf paths directly from the hand-written source model, and the overlay
derives each flat environment spelling algorithmically by replacing path separators with
underscores. Discovery descends through optional nested structs, treats scalar-like source types as
leaves, and is cached after its first run. Single-segment keys are already flat and are left alone.

Both overlays honor the selected precedence mode:

  • Fallback fills only a missing nested value, leaving Agent-supplied configuration authoritative.
  • Override allows a flat environment value to replace an existing nested value.
  • Disabled leaves the merged map unchanged.

This PR also prepares the configuration system for typed component construction without cutting a
component over:

  • Loads ConfigurationSystem before topology assembly and threads it to the DogStatsD builder.
  • Reshapes SalukiOnly to mirror canonical source key paths, so plain serde transports top-level and
    nested keys correctly.
  • Models memory_limit as a byte size at the source boundary, accepting integer byte counts and
    byte-size strings.
  • Moves defaults for seeded Saluki-only values into the typed model and adds round-trip transport
    coverage.

Change Type

  • Bug fix

How did you test this PR?

  • cargo test -p agent-data-plane-config-system saluki_env_overlay
  • cargo check -p agent-data-plane-config-system
  • cargo check -p agent-data-plane
  • Unit coverage exercises Datadog and Saluki-only environment-key relocation, precedence, declared
    Datadog env-name overrides, alias priority, string-list conversion, optional-struct discovery,
    scalar-like leaves, and Saluki-only source transport.

References

@datadog-prod-us1-4

datadog-prod-us1-4 Bot commented Jul 4, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 1 Pipeline job failed

DataDog/saluki | test-integration   View in Datadog   GitLab

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f4bc7fe | Docs | Datadog PR Page | Give us feedback!

@pr-commenter

pr-commenter Bot commented Jul 4, 2026

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: 2715682 · Comparison: f4bc7fe · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 41.54 MiB (baseline) vs 42.64 MiB (comparison)
Size Change: +1.10 MiB (+2.65%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
serde_json +240.33 KiB 353
core +169.32 KiB 4704
datadog_agent_config::generated::datadog_configuration +114.62 KiB 54
serde_core +88.22 KiB 416
figment +66.72 KiB 159
agent_data_plane_config_system::saluki_env_overlay::PathRecorder +66.19 KiB 25
[sections] +49.54 KiB 8
alloc +47.93 KiB 673
tonic -29.63 KiB 207
tokio +27.88 KiB 1183
agent_data_plane_config_system::translators::datadog_translator +24.70 KiB 22
http_body_util +18.94 KiB 79
anon.b1d34d51c938cd913199284b8f39126e.69.llvm.9179742737739013148 +17.78 KiB 1
anon.5f040b9cf0e85edcd98481965dce5e0f.55.llvm.9953283433741861364 -17.07 KiB 1
hashbrown +14.04 KiB 325
agent_data_plane::internal::env -13.48 KiB 201
axum +13.45 KiB 144
tracing -13.05 KiB 15
datadog_agent_config::generated::witness +12.72 KiB 1
agent_data_plane_config::shared::_ +11.27 KiB 15
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
   +14% +1019Ki   +15%  +763Ki    [16164 Others]
  [NEW] +54.1Ki  [NEW] +53.7Ki    _<datadog_agent_config::generated::datadog_configuration::_::<impl serde_core::de::Deserialize for datadog_agent_config::generated::datadog_configuration::DatadogConfiguration>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map::hb8fedc8e9123324e
  [NEW] +51.9Ki  [NEW] +51.8Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::h5c25aa83fccb92d0
  [NEW] +32.4Ki  [NEW] +32.3Ki    agent_data_plane::internal::env::workload::RemoteAgentWorkloadProvider::from_configuration::_{{closure}}::hd1e638851f0cd91b
  [NEW] +29.9Ki  [NEW] +29.8Ki    agent_data_plane::cli::dogstatsd::handle_dogstatsd_command::_{{closure}}::hfaa29303c464138d
  +2.6% +28.9Ki  +2.6% +28.9Ki    [section .gcc_except_table]
  [NEW] +27.7Ki  [NEW] +27.6Ki    agent_data_plane::cli::run::create_topology::_{{closure}}::h2bcde695847eff3b
  [NEW] +23.9Ki  [NEW] +23.7Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::he4acfc15ba314845
  [NEW] +23.6Ki  [NEW] +23.5Ki    agent_data_plane::state::metrics::rules::get_datadog_agent_remappings::h9cad7ca691a0ce7d
  [NEW] +22.4Ki  [NEW] +22.2Ki    _<agent_data_plane::components::host_tags::HostTagsConfiguration as saluki_core::components::transforms::builder::SynchronousTransformBuilder>::build::_{{closure}}::hb9288fb6fe06d4ca
  [NEW] +21.5Ki  [NEW] +21.3Ki    datadog_agent_commons::ipc::client::RemoteAgentClient::from_client_configuration::_{{closure}}::_{{closure}}::_{{closure}}::h60ac4b5f36651d67
  [NEW] +20.6Ki  [NEW] +20.5Ki    agent_data_plane::cli::debug::handle_debug_command::_{{closure}}::hdcc07573009c9d02
  [DEL] -19.5Ki  [DEL] -19.4Ki    agent_data_plane::internal::env::workload::build_collector::_{{closure}}::h68269a7c75296660
  [DEL] -19.6Ki  [DEL] -19.4Ki    datadog_agent_commons::ipc::client::RemoteAgentClient::from_client_configuration::_{{closure}}::_{{closure}}::_{{closure}}::hfe5418ff83bea119
  [DEL] -21.1Ki  [DEL] -20.9Ki    agent_data_plane::internal::env::ADPEnvironmentProvider::from_configuration::_{{closure}}::h2a4d118040535a27
  [DEL] -21.1Ki  [DEL] -21.0Ki    agent_data_plane::cli::debug::handle_debug_command::_{{closure}}::h52186509e2e9628d
  [DEL] -23.0Ki  [DEL] -22.8Ki    _<agent_data_plane::components::host_tags::HostTagsConfiguration as saluki_core::components::transforms::builder::SynchronousTransformBuilder>::build::_{{closure}}::h7d89934f63b89648
  [DEL] -24.8Ki  [DEL] -24.6Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::hf458fedae78eed58
  [DEL] -28.0Ki  [DEL] -27.9Ki    agent_data_plane::cli::run::create_topology::_{{closure}}::hb59d6631923a902b
  [DEL] -30.0Ki  [DEL] -29.9Ki    agent_data_plane::cli::dogstatsd::handle_dogstatsd_command::_{{closure}}::hf69bf5e5176a850d
  [DEL] -41.4Ki  [DEL] -41.2Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::h244a74d1ea5c869f
  +2.7% +1.10Mi  +2.6%  +871Ki    TOTAL

@pr-commenter

pr-commenter Bot commented Jul 4, 2026

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: 607a8f73-6925-4b0d-a0b2-28c487d8e3d4
Baseline: 2715682b · Comparison: f4bc7fee · diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment (3)

Experiments configured erratic: true are tagged (ignored) and skipped when determining which experiments regressed or improved. Experiments which are detected as erratic at runtime are tagged (erratic) to flag that the run's sample dispersion was high, but their regression / improvement signal still counts.

experiment goal Δ mean % links
quality_gates_rss_idle memory ⚪ +2.85 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ +2.25 metrics profiles logs
quality_gates_rss_dsd_medium memory ⚪ +1.35 metrics profiles logs
Bounds Checks: ✅ Passed (3)
experiment check replicates observed links
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 43.8 MiB ≤ 50 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 65.4 MiB ≤ 75 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 29.7 MiB ≤ 40 MiB metrics profiles logs
Explanation

A change is flagged as a regression when |Δ mean %| > 5.00% in the regressing direction for its optimization goal AND SMP marks the experiment as a regression (is_regression: true). Improvements use the matching criteria for the improving direction. Experiments configured erratic: true (tagged (ignored)) are skipped outright; experiments detected as erratic at runtime (tagged (erratic)) still count, since that flag describes sample dispersion rather than directional certainty. The Δ mean % cell is colored accordingly: 🟢 = improvement, 🔴 = regression, ⚪ = neutral. Reduction in CPU or memory is an improvement; reduction in ingress throughput is a regression.

@webern webern force-pushed the m/pr3b-env-keys branch from e6bfdc9 to 74ecadf Compare July 5, 2026 11:55
@dd-octo-sts dd-octo-sts Bot added the area/components Sources, transforms, and destinations. label Jul 5, 2026
@webern webern changed the title chore(config): overlay flat env-var keys onto the nested Datadog config chore(config): fix env-overlay behavior and saluki only shape Jul 5, 2026
@webern webern force-pushed the m/pr3b-env-keys branch from 67baf4b to 3a5cfe3 Compare July 8, 2026 15:21
@webern webern marked this pull request as ready for review July 8, 2026 16:21
@webern webern requested a review from a team as a code owner July 8, 2026 16:21
Copilot AI review requested due to automatic review settings July 8, 2026 16:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a5cfe3652

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +99 to +102
let flats: Vec<String> = candidate_flats
.into_iter()
.filter(|flat| !(segments.len() == 1 && segments[0] == flat))
.collect();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep top-level list env vars in the overlay table

For top-level StringList settings such as dogstatsd_tags, this filter removes the only flat form because it is already at the destination path, so no EnvOverlayKey is emitted and apply_env_overlay never calls to_string_list. With an env var like DD_DOGSTATSD_TAGS="env:prod team:core", the merged value remains a JSON string while DatadogConfiguration::dogstatsd_tags expects Vec<String>, causing the configuration-system load to fail instead of splitting the list. Keep these entries, or split in place, whenever value_type is StringList.

Useful? React with 👍 / 👎.

@webern webern Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a good finding. I am pushing a fix that I still need to take a closer look at before merging.

Fix: https://github.com/DataDog/saluki/compare/3a5cfe3652589ec386ed15881eaa3b40618503c7..c5032e8d67ea54f2c7ba50e2b42c5495122de744

Comment thread lib/agent-data-plane-config-system/src/saluki_only.rs Outdated
Copilot AI review requested due to automatic review settings July 8, 2026 18:01
@webern webern force-pushed the m/pr3b-env-keys branch from 3a5cfe3 to c5032e8 Compare July 8, 2026 18:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 9, 2026 09:44
@webern webern force-pushed the m/pr3b-env-keys branch from c5032e8 to 24621f3 Compare July 9, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 9, 2026 12:02
@webern webern force-pushed the m/pr3b-env-keys branch from 24621f3 to cd6d290 Compare July 9, 2026 12:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@webern webern force-pushed the m/pr3b-env-keys branch from cd6d290 to ed8a6cb Compare July 9, 2026 13:31
@webern webern force-pushed the m/pr3-dynamic branch 2 times, most recently from 4e175c2 to fea786d Compare July 9, 2026 14:27
Copilot AI review requested due to automatic review settings July 9, 2026 14:27
@webern webern force-pushed the m/pr3b-env-keys branch from ed8a6cb to 8ca4292 Compare July 9, 2026 14:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@webern webern force-pushed the m/pr3b-env-keys branch from 8ca4292 to 90da4b6 Compare July 9, 2026 15:41
Copilot AI review requested due to automatic review settings July 9, 2026 15:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

webern added 6 commits July 10, 2026 12:02
Environment variables reach the config map as flat, underscore-joined
top-level keys (`DD_AUTOSCALING_FAILOVER_ENABLED` -> `autoscaling_failover_enabled`),
while `DatadogConfiguration` deserializes the nested shape. The whole-struct
deserialize never reads those flat keys, so an env var set for a multi-segment
key is silently dropped. The legacy per-key lookup bridged this at query time by
retrying the dotted key with `.` replaced by `_`; the typed path issues no
per-key queries, so that bridge no longer fires.

Reinstate it as a one-time pass over the merged value, driven by a generated
table of the supported multi-segment keys. For each known dotted path, relocate
any matching flat key into the nested slot the deserializer reads. This runs the
safe direction (known path -> its single flat form), so it never has to guess
where an arbitrary flat key's nesting boundaries are. String lists are split on
whitespace to match the Agent's env convention; scalars relocate verbatim.

The mode is chosen at deserialization: Fallback fills only slots the Agent left
empty (matching the legacy precedence, restoring prior behavior), Override lets
an env var replace an Agent-supplied value, and Disabled relocates nothing. The
overlay is applied only to the Datadog input; the Saluki-only source
deserializes from the untouched value and is out of scope here.

(cherry picked from commit 7e6e4095dbfc12224773216c4c6ecf6611103442)
Preparatory fixes the component cutovers depend on; none of these change a
component yet.

- Load ConfigurationSystem before topology assembly and thread the system
  handle down to the DogStatsD pipeline builder (unused for now, hence the
  leading underscore).
- Reshape the Saluki-only source struct to mirror the config key hierarchy
  exactly, so each field maps by plain serde to its real config-key path.
- Model the memory limit as a byte size (u64 in the model, ByteSize in the
  source) so a bare-integer value no longer fails the whole config load.
Environment variables reach the merged map as flat, underscore-joined keys, but SalukiOnly deserializes a nested shape, so a DD_* var for a dotted Saluki-only path (e.g. DD_DATA_PLANE_STANDALONE_MODE) was silently dropped. The Datadog overlay already fixes this for schema keys via a generated table; SalukiOnly has no table by design.

Discover SalukiOnly's canonical leaf paths algorithmically from its derived Deserialize using a hand-rolled recording deserializer (no new dependency), treating scalar-like custom types (DurationString, ByteSize, Duration) as leaves. Cache the paths. Before deserializing SalukiOnly, relocate each multi-segment path's flat form into its nested slot, honoring EnvOverlayMode (Disabled/Fallback/Override). Single-segment keys are already flat and untouched.
Copilot AI review requested due to automatic review settings July 10, 2026 10:26
@webern webern force-pushed the m/pr3b-env-keys branch from 90da4b6 to f4bc7fe Compare July 10, 2026 10:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Base automatically changed from m/pr3-dynamic to main July 10, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/components Sources, transforms, and destinations.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants