Skip to content

feat(trace-sampler): apply APM_SAMPLING remote configurations - #2720

Open
webern wants to merge 3 commits into
m/otlp-semdecfrom
m/otlp-smpdec
Open

webern wants to merge 3 commits into
m/otlp-semdecfrom
m/otlp-smpdec

Conversation

@webern

@webern webern commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Human Summary

Adds a TraceSamplingSubscription and decoder for its remote configuration protocol.

AI Summary

The RC client in #2713 can deliver typed product snapshots, and #2719 handles semantic mappings for trace translation and stats. This PR adds the separate APM_SAMPLING consumer: its decoder interprets remote sampler settings, and the trace sampler can apply accepted settings while processing traces. The sampler configuration takes a TraceSamplingSubscription; without one, it holds an inert subscription and continues using its configured settings. #2724 is responsible for constructing the production subscription and passing it into the sampler.

APM_SAMPLING can override the priority and errors sampler target traces per second and enable or disable rare sampling. For each field, the sampler takes the last matching by_env entry, then all_envs, then its static setting. Missing or null fields leave that field unset; an explicit zero or false is an override. The no-priority sampler target is not remotely changed.

  • SamplingDecoder accepts one configuration. It rejects malformed input or multiple assigned configurations. With none assigned, it publishes an Unassigned snapshot: unlike the semantic registry, the sampler keeps its last applied remote settings instead of returning to static settings.
  • The sampler reads its latest accepted snapshot before each input event buffer, applies a new one once, then processes that buffer with those settings. Rejected updates leave its last applied settings in place.
  • Tests cover decoding, environment precedence, and updates through a built sampler. Without feat(adp): apply trace products from remote configuration #2724's startup wiring, production still uses static sampler settings.

Change Type

  • New feature

How did you test this PR?

  • make fmt, cargo check --workspace, cargo check --workspace --tests, make check-docs, make check-clippy at the stack tip.
  • Filtered saluki-components tests: 549 passed at the stack tip.

References

@webern
webern added this pull request to stack #2721 September 30, 2026 11:18
@dd-octo-sts dd-octo-sts Bot added area/components Sources, transforms, and destinations. transform/trace-sampler Trace Sampler synchronous transform. labels Sep 30, 2026
@webern webern added the changelog/no-changelog No changelog entry needed label Sep 30, 2026
@pr-commenter

pr-commenter Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: 216e499 · Comparison: effc81a · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 38.27 MiB (baseline) vs 38.29 MiB (comparison)
Size Change: +26.43 KiB (+0.07%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
core +60.47 KiB 8993
&mut serde_json -35.73 KiB 91
agent_data_plane::state::metrics -35.28 KiB 6
agent_data_plane::internal::remote_agent +24.68 KiB 118
otlp_protos::otlp_include::opentelemetry -18.26 KiB 181
anon.fae0c96d29a9fe1386d81498a79beb50.30.llvm.3370098010730192185 +16.19 KiB 1
anon.87e7c38bfd928d17fa28187081c51bf0.2.llvm.240572210426274404 -16.09 KiB 1
saluki_components::sources::otlp +14.89 KiB 259
anon.fae0c96d29a9fe1386d81498a79beb50.458.llvm.3370098010730192185 +14.63 KiB 1
anon.87e7c38bfd928d17fa28187081c51bf0.768.llvm.240572210426274404 -14.62 KiB 1
serde_json +14.26 KiB 453
anon.fae0c96d29a9fe1386d81498a79beb50.6.llvm.3370098010730192185 +12.84 KiB 1
anon.87e7c38bfd928d17fa28187081c51bf0.766.llvm.240572210426274404 -12.84 KiB 1
[sections] -12.76 KiB 9
piecemeal -11.67 KiB 36
anon.9d1057ec6821611763596b0232be6ef0.693.llvm.6678353967787269721 -11.13 KiB 1
saluki_core::cache::CacheBuilder<K,V,W,H> +11.03 KiB 6
agent_data_plane::internal::telemetry +10.92 KiB 8
anon.3716a808dbcf00fa1ff5dbde2056a4bd.671.llvm.9155267978429562090 +10.87 KiB 1
saluki_components::sources::dogstatsd +10.05 KiB 397
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW] +59.8Ki  [NEW] +59.7Ki    saluki_components::common::datadog::io::run_endpoint_io_loop::_{{closure}}::ha38a49b72e023545
  [NEW] +43.5Ki  [NEW] +43.3Ki    _<saluki_components::forwarders::otlp::OtlpForwarder as saluki_core::components::forwarders::Forwarder>::run::_{{closure}}::hb872765f165820b0
  [NEW] +40.6Ki  [NEW] +40.5Ki    agent_data_plane::cli::run::create_topology::_{{closure}}::h75562c7ea09bcbff
  [NEW] +37.1Ki  [NEW] +36.9Ki    _<saluki_components::transforms::apm_stats::ApmStats as saluki_core::components::transforms::Transform>::run::_{{closure}}::h79ca62828ea1b270
  [NEW] +34.4Ki  [NEW] +34.2Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::h0f7a307e9cc0a16a
  [NEW] +30.8Ki  [NEW] +30.7Ki    agent_data_plane::cli::dogstatsd::run_dogstatsd_command::_{{closure}}::hdfcd4810bc0a3053
  [NEW] +28.7Ki  [NEW] +28.6Ki    agent_data_plane::dogstatsd_contexts::artifact::for_each_record::h1b4e32864ddc5f08
  [NEW] +27.7Ki  [NEW] +27.5Ki    datadog_agent_commons::ipc::client::RemoteAgentClient::connect::_{{closure}}::_{{closure}}::_{{closure}}::h0a198a9356f00b58
  +0.2% +27.6Ki  +0.1% +9.17Ki    [28931 Others]
  [NEW] +25.5Ki  [NEW] +25.4Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::h044bf8d66771780c
  [NEW] +25.1Ki  [NEW] +25.0Ki    agent_data_plane::internal::remote_agent::RemoteAgentBootstrap::build_impl::h9676872f68a8b683
  [DEL] -25.6Ki  [DEL] -25.4Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::h1f55b7becb8f9961
  [DEL] -25.7Ki  [DEL] -25.6Ki    core::ops::function::FnOnce::call_once::h4d6ad556f476b8c9
  [DEL] -28.4Ki  [DEL] -28.2Ki    datadog_agent_commons::ipc::client::RemoteAgentClient::connect::_{{closure}}::_{{closure}}::_{{closure}}::h1bd6a026eeafe819
  [DEL] -28.7Ki  [DEL] -28.6Ki    agent_data_plane::dogstatsd_contexts::artifact::for_each_record::hb60d5262ffff75a0
  [DEL] -31.4Ki  [DEL] -31.2Ki    agent_data_plane::cli::dogstatsd::run_dogstatsd_command::_{{closure}}::h2f5246c806e7f392
  [DEL] -34.9Ki  [DEL] -34.7Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::haa79196f741be08a
  [DEL] -35.8Ki  [DEL] -35.6Ki    _<saluki_components::transforms::apm_stats::ApmStats as saluki_core::components::transforms::Transform>::run::_{{closure}}::h8bffda5d06bacbfd
  [DEL] -40.5Ki  [DEL] -40.4Ki    agent_data_plane::cli::run::create_topology::_{{closure}}::h02ed82f16b54dbc0
  [DEL] -44.7Ki  [DEL] -44.5Ki    _<saluki_components::forwarders::otlp::OtlpForwarder as saluki_core::components::forwarders::Forwarder>::run::_{{closure}}::h252ca254b106e4c3
  [DEL] -58.6Ki  [DEL] -58.5Ki    saluki_components::common::datadog::io::run_endpoint_io_loop::_{{closure}}::h15a965fc1b5a6f1e
  +0.1% +26.4Ki  +0.0% +7.96Ki    TOTAL

@pr-commenter

pr-commenter Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: f8722aa1-4b9b-48f4-b1d3-4659383bd4b2
Baseline: 216e499a · Comparison: effc81af · 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_heavy memory ⚪ -0.22 metrics profiles logs
quality_gates_rss_dsd_medium memory ⚪ -0.55 metrics profiles logs
quality_gates_rss_idle memory ⚪ -0.67 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ -0.84 metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory ⚪ -1.23 metrics profiles logs
Bounds Checks: ✅ Passed (5)
experiment check replicates observed links
quality_gates_rss_dsd_heavy memory_usage 10/10 ✅ 229 MiB ≤ 250 MiB metrics profiles logs
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 51.4 MiB ≤ 60 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 90.6 MiB ≤ 100 MiB metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory_usage 10/10 ✅ 385 MiB ≤ 420 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 33 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. Experiments tagged (no analysis) show ⚠️ n/a: SMP ran them but produced no analysis, usually because a replicate failed and exhausted its retries. Check the SMP report for that experiment's replicate failures.

@dd-octo-sts dd-octo-sts Bot added area/core Core functionality, event model, etc. area/io General I/O and networking. transform/apm-stats APM Stats transform. labels Sep 30, 2026
@dd-octo-sts dd-octo-sts Bot removed area/core Core functionality, event model, etc. area/io General I/O and networking. transform/apm-stats APM Stats transform. labels Sep 30, 2026
@webern
webern force-pushed the m/otlp-smpdec branch 2 times, most recently from 182e522 to 518a5e5 Compare October 1, 2026 17:31
@webern
webern force-pushed the m/otlp-smpdec branch 2 times, most recently from 0a682ab to b8916be Compare October 2, 2026 13:00
webern added 2 commits October 2, 2026 16:14
Add the APM_SAMPLING decoder and a TraceSamplingSubscription owned by
the trace sampler. Decode the Agent payload shape, including absent and
null values and lowercase aliases for the target TPS fields.

Accept a single valid assignment. Reject invalid or multiple assignments
without replacing the accepted snapshot. An empty assignment leaves the
last applied sampler settings in place. Decode errors do not quote the
payload.

Resolve each field from the last by_env entry matching the normalized
default environment, then all_envs, then the static setting. Before each
event buffer, apply new priority and errors sampler targets and the rare
sampling switch. An errors sampler initially disabled by a zero target
stays disabled; the no-priority target stays static.

Expose the subscription through the sampler configuration builder, with
an inert default until startup supplies a client. Test payload decoding,
environment selection and updates through the built sampler.
@webern
webern marked this pull request as ready for review October 2, 2026 14:28
@webern
webern requested a review from a team as a code owner October 2, 2026 14:28

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

ℹ️ 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 thread lib/saluki-components/src/transforms/trace_sampler/mod.rs

@datadog-datadog-prod-us1-2 datadog-datadog-prod-us1-2 Bot left a comment

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.

Bits Code Review: FAIL

A remote target restored from zero within one sampling bucket leaves learned rates at zero until the next recalculation, temporarily suppressing error traces despite a positive effective target.

Open Bits AI session

🤖 Bits Code Review · Commit bbcb426 · @DataDog review to ask questions

Comment thread lib/saluki-components/src/transforms/trace_sampler/mod.rs
A zero target scales every learned signature rate to zero. When a
later update raised the target again, the update returned early
because there is no ratio to scale by, so those signatures kept
dropping every trace until the next bucket began.

Recompute the rates from the current window when the target rises
from zero. The Datadog Agent has the same gap; this departs from it
on purpose.

This branch has not been deployed

No deployments
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. changelog/no-changelog No changelog entry needed transform/trace-sampler Trace Sampler synchronous transform.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant