Skip to content

chore(config): migrate trace sampler to typed configuration - #2191

Merged
webern merged 1 commit into
mainfrom
m/confra-apmcf
Aug 6, 2026
Merged

chore(config): migrate trace sampler to typed configuration#2191
webern merged 1 commit into
mainfrom
m/confra-apmcf

Conversation

@webern

@webern webern commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Human Summary

This is a relatively straightforward conversion of TraceSamplerConfiguration to typed config. No issues were encountered. The Codex flag is because we are changing our default to match the Agent (which is what we want).

AI Summary

Migrate the trace sampler transform to the typed traces configuration domain.

  • Construct TraceSamplerConfiguration from domains.traces instead of GenericConfiguration and ApmConfig.
  • Preserve the Saluki-only defaults for the trace sampler in the typed model.
  • Remove sampler-only fields, accessors, and legacy deserialization tests from ApmConfig.
  • Update the traces pipeline construction to use the typed configuration.

Change Type

  • Non-functional (chore, refactoring, docs)

How did you test this PR?

  • make fmt
  • make build-schema-overlay (no generated drift)
  • cargo check --workspace --tests
  • cargo clippy -p saluki-components -p agent-data-plane-config-system -p agent-data-plane -p agent-data-plane-config --all-targets
  • cargo nextest run -p saluki-components -p agent-data-plane-config-system -p agent-data-plane-config (843 passed, 1 skipped)

References

@webern
webern requested a review from a team as a code owner July 23, 2026 06:00
@dd-octo-sts dd-octo-sts Bot added area/components Sources, transforms, and destinations. transform/trace-sampler Trace Sampler synchronous transform. labels Jul 23, 2026

@datadog-prod-us1-3 datadog-prod-us1-3 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.

Datadog Autotest: PASS

More details

The migration preserves trace sampler behavior through the resolved configuration path: generated schema defaults still provide the historical 10 TPS values, while Saluki-only defaults and explicit nested settings are seeded into the traces domain. No diff-only behavioral regression was identified. No additional tests recommended: the existing configuration transport coverage already exercises the migrated Saluki-only fields, and execution was blocked by unavailable Rust dependencies.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit fa6af8d · What is Autotest? · Any feedback? Reach out in #autotest

@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: fa6af8d373

ℹ️ 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".

let otlp_sampling_rate = normalize_sampling_rate(traces.otlp.probabilistic_sampler_sampling_percentage / 100.0);
Self {
probabilistic_sampler_enabled: traces.probabilistic_sampler.enabled,
sampling_percentage: traces.probabilistic_sampler.sampling_percentage,

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 Restore the omitted probabilistic sampler percentage fallback

When apm_config.probabilistic_sampler.enabled is set but sampling_percentage is omitted, this now copies the typed Datadog default of 0_f64 from lib/datadog-agent/config/src/generated/datadog_configuration.rs:1769; the removed raw ApmConfig default was 100%, so line 111 builds a sampling rate of 0.0 and the probabilistic path drops all non-error/non-rare traces. Preserve the previous 100% fallback for the omitted-percentage case so this typed-config cutover remains behaviorally transparent.

Useful? React with 👍 / 👎.

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 is correct and a bugfix that goes toward #1802. ADP should honor the core Agent defaults. Fortunately this feature isn't released to customers yet so only our tests are affected.

@pr-commenter

pr-commenter Bot commented Jul 23, 2026

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: 853c1fe · Comparison: b510d9b · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 41.50 MiB (baseline) vs 41.50 MiB (comparison)
Size Change: -2.30 KiB (-0.01%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
figment +50.61 KiB 170
core -47.17 KiB 2084
tokio +29.80 KiB 864
tonic +24.66 KiB 75
serde_core -21.62 KiB 196
piecemeal +20.99 KiB 29
serde -20.89 KiB 29
serde_with +19.41 KiB 13
anon.846b21e6dda52c9a744127ddd23a5106.1184.llvm.3672468582573643209 -17.80 KiB 1
anon.4a29db1e19c408ff1e16e39b748f19e4.1182.llvm.16037465561292757490 +17.80 KiB 1
http_body_util -16.85 KiB 59
saluki_components::transforms::dogstatsd_mapper -15.25 KiB 9
saluki_components::common::datadog +14.68 KiB 122
saluki_components::sources::dogstatsd +13.57 KiB 39
tracing -13.23 KiB 16
quick_cache +13.05 KiB 52
anon.953dae56435bf69d4ba63de4c547ae60.498.llvm.2156985661193919661 +12.46 KiB 1
anon.953dae56435bf69d4ba63de4c547ae60.498.llvm.9073899492071955771 -12.37 KiB 1
saluki_common::task::instrument +10.09 KiB 21
anon.4a29db1e19c408ff1e16e39b748f19e4.525.llvm.16037465561292757490 +9.71 KiB 1
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW] +32.5Ki  [NEW] +32.4Ki    agent_data_plane::internal::env::workload::RemoteAgentWorkloadProvider::from_configuration::_{{closure}}::h273918a7d610bdfa
  +0.2% +25.2Ki  +0.1% +7.09Ki    [12420 Others]
 +37e2% +18.1Ki +43e2% +18.1Ki    prost::message::Message::encode::h5b57720a71420a9c
  [NEW] +17.8Ki  [NEW]     +76    anon.4a29db1e19c408ff1e16e39b748f19e4.1182.llvm.16037465561292757490
  [NEW] +15.2Ki  [NEW] +15.1Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_struct::hcd5d2f1d3886cf32
  [NEW] +14.1Ki  [NEW] +14.0Ki    _<figment::value::magic::RelativePathBuf as figment::value::magic::Magic>::deserialize_from::h57935c312d7d4142
  [NEW] +13.8Ki  [NEW] +13.6Ki    _<figment::value::magic::Tagged<T> as figment::value::magic::Magic>::deserialize_from::hbc114368f39b0da4
  [NEW] +12.9Ki  [NEW] +12.8Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_any::h9c01161bf3a4a364
 +20e2% +12.8Ki +23e2% +12.8Ki    prost::message::Message::encode_to_vec::h93b2b33121d3c9be
  [NEW] +12.5Ki  [NEW]     +81    anon.953dae56435bf69d4ba63de4c547ae60.498.llvm.2156985661193919661
 -39.4% -12.3Ki -39.7% -12.3Ki    _<saluki_components::transforms::apm_stats::ApmStats as saluki_core::components::transforms::Transform>::run::_{{closure}}::h17e28c515cd1a8f5
  [DEL] -12.4Ki  [DEL]     -81    anon.953dae56435bf69d4ba63de4c547ae60.498.llvm.9073899492071955771
  [DEL] -12.9Ki  [DEL] -12.8Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_struct::hdc5c7a358bf201fd
  [DEL] -15.2Ki  [DEL] -15.1Ki    _<figment::value::magic::Tagged<T> as figment::value::magic::Magic>::deserialize_from::hf697faa584ef7446
  [DEL] -15.2Ki  [DEL] -15.0Ki    saluki_components::common::datadog::obfuscation::_::_<impl serde_core::de::Deserialize for saluki_components::common::datadog::obfuscation::ObfuscationConfig>::deserialize::hfdb45102b1c29886
  [DEL] -15.4Ki  [DEL] -15.2Ki    _<figment::value::magic::RelativePathBuf as figment::value::magic::Magic>::deserialize_from::h18cc13ebe25523a9
  [DEL] -16.8Ki  [DEL] -16.7Ki    figment::figment::Figment::extract::h35d5a146172e5fec
  [DEL] -17.8Ki  [DEL]     -76    anon.846b21e6dda52c9a744127ddd23a5106.1184.llvm.3672468582573643209
  [DEL] -19.5Ki  [DEL] -19.4Ki    saluki_components::transforms::apm_stats::ApmStats::process_trace::hce992ca7b6928d1d
  [DEL] -19.8Ki  [DEL] -19.7Ki    agent_data_plane::internal::env::workload::build_collector::_{{closure}}::hfecfe48366f575fc
  [DEL] -19.9Ki  [DEL] -19.7Ki    agent_data_plane::internal::env::ADPEnvironmentProvider::from_configuration::_{{closure}}::h0631d7db0dec70b3
  -0.0% -2.30Ki  -0.1% -20.1Ki    TOTAL

@pr-commenter

pr-commenter Bot commented Jul 23, 2026

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: afad9d84-c8ce-4a09-a438-11a830e517c4
Baseline: c3563758 · Comparison: 6a00f686 · diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment (5)

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_dsd_ultraheavy memory ⚪ -0.15 metrics profiles logs
quality_gates_rss_dsd_heavy memory ⚪ -0.23 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ -0.33 metrics profiles logs
quality_gates_rss_dsd_medium memory ⚪ -0.43 metrics profiles logs
quality_gates_rss_idle memory ⚪ -0.63 metrics profiles logs
Bounds Checks: ✅ Passed (5)
experiment check replicates observed links
quality_gates_rss_dsd_heavy memory_usage 10/10 ✅ 140 MiB ≤ 145 MiB metrics profiles logs
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 49.2 MiB ≤ 50 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 77.9 MiB ≤ 80 MiB metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory_usage 10/10 ✅ 203 MiB ≤ 205 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 31.9 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 marked this pull request as draft July 24, 2026 16:25
@webern
webern force-pushed the m/confra-apmcf branch 2 times, most recently from b5f20b6 to 8efc4d4 Compare August 5, 2026 10:53
@webern
webern force-pushed the m/confra-dtcfg branch 2 times, most recently from 760cc24 to be8b6a3 Compare August 5, 2026 11:02
@webern
webern force-pushed the m/confra-apmcf branch 2 times, most recently from da6bd8a to 45fade5 Compare August 5, 2026 11:11
@dd-octo-sts dd-octo-sts Bot added encoder/datadog-stats Datadog APM Stats encoder. encoder/datadog-traces Datadog Traces encoder. labels Aug 5, 2026
@webern
webern marked this pull request as ready for review August 5, 2026 11:37

@datadog-prod-us1-3 datadog-prod-us1-3 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.

Datadog Autotest: PASS

More details

The typed migration preserves the trace sampler's Datadog defaults, Saluki-only overrides, and OTLP sampling normalization across the inspected startup and override paths. Local Rust execution could not run because the sandbox cannot fetch the repository's pinned git dependency, so confidence is based on the three-dot diff and complete source-level path comparison.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 3ca5877 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

@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: 3ca5877e4b

ℹ️ 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".

error_sampling_enabled: self.apm_config.error_sampling_enabled(),
error_tracking_standalone: self.apm_config.error_tracking_standalone_enabled(),
probabilistic_sampler_enabled: self.apm_config.probabilistic_sampler_enabled(),
sampling_rate: self.sampling_percentage / 100.0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep disabled probabilistic sampling from emitting zero rate

With the typed config, the Core Agent default for apm_config.probabilistic_sampler.sampling_percentage is 0 while probabilistic_sampler_enabled defaults to false. In that default legacy path, kept non-OTLP traces still pass through apply_sampling_metadata, which copies this sampling_rate into trace.otlp_sampling_rate, and the trace encoder writes it as _dd.otlp_sr; default-sampled traces are therefore emitted with 0.00 instead of the prior/default 1.00 unless users explicitly set a sampling percentage. Fresh evidence is the disabled-sampler metadata path, not the intentional 0% behavior when the probabilistic sampler is enabled; avoid using the disabled sampler's percentage for the emitted rate.

Useful? React with 👍 / 👎.

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.

I don't really understand this. Does it seem problematic for an unreleased feature under development?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sounds like a separate bugfix but also something that should have a correctness test on it that'd break if you changed it. Maybe worth kicking off a clanker session on it to put a correctness test in place so we don't inadvertently regress it here.

Build the trace sampler from the resolved traces domain slice instead of
reading GenericConfiguration through the shared ApmConfig helper.

- Take the sampler's probabilistic, error, priority, and rare-sampler
  inputs from domains.traces, and drop its raw deserialization.
- Establish the Saluki-only sampler defaults in the traces model, matching
  ADP's historical values: default_env "none", error_sampling_enabled on,
  and rare_sampler tps 5, cooldown 300s, cardinality 200.
- Trim ApmConfig to the span-kind, peer-tags, environment, hostname, and
  obfuscation surface still read by the APM stats and trace obfuscation
  transforms, removing the now-unused sampler fields and their legacy
  deserialization tests.

The witnessed apm_config.probabilistic_sampling.sampling_percentage takes
the Datadog schema default of 0 rather than ADP's former 100. This only
affects the effective rate when the APM probabilistic sampler is enabled
without an explicit percentage; the sampler is off by default.

@datadog-prod-us1-3 datadog-prod-us1-3 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.

Datadog Autotest: PASS

More details

The typed configuration boundary preserves every trace sampler and encoder input from the generated Datadog witness or Saluki-only seed through to the trace pipeline, including the intentional schema-aligned APM sampling default. No behavioral regression was identified from the PR diff.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 6a00f68 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

@webern
webern merged commit ae0fae9 into main Aug 6, 2026
83 of 91 checks passed
@webern
webern deleted the m/confra-apmcf branch August 6, 2026 12:30
dd-octo-sts Bot pushed a commit that referenced this pull request Aug 6, 2026
## Human Summary

This is a relatively straightforward conversion of
`TraceSamplerConfiguration` to typed config. No issues were encountered.
The Codex flag is because we are changing our default to match the Agent
(which is what we want).

## AI Summary

Migrate the trace sampler transform to the typed traces configuration
domain.

- Construct `TraceSamplerConfiguration` from `domains.traces` instead of
`GenericConfiguration` and `ApmConfig`.
- Preserve the Saluki-only defaults for the trace sampler in the typed
model.
- Remove sampler-only fields, accessors, and legacy deserialization
tests from `ApmConfig`.
- Update the traces pipeline construction to use the typed
configuration.

## Change Type

- [x] Non-functional (chore, refactoring, docs)

## How did you test this PR?

- `make fmt`
- `make build-schema-overlay` (no generated drift)
- `cargo check --workspace --tests`
- `cargo clippy -p saluki-components -p agent-data-plane-config-system
-p agent-data-plane -p agent-data-plane-config --all-targets`
- `cargo nextest run -p saluki-components -p
agent-data-plane-config-system -p agent-data-plane-config` (843 passed,
1 skipped)

## References

- Progresses: #2169
- Progresses: #2193
- Progresses: #1802 ae0fae9
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. decoders/otlp encoder/datadog-stats Datadog APM Stats encoder. encoder/datadog-traces Datadog Traces encoder. source/otlp OTLP source. transform/trace-sampler Trace Sampler synchronous transform.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants