Skip to content

fix(rc)!: fix missing/null deserialization and rename tracing_sample_rate#2102

Open
iunanua wants to merge 4 commits into
mainfrom
igor/rc/fix-dynamic-config-des
Open

fix(rc)!: fix missing/null deserialization and rename tracing_sample_rate#2102
iunanua wants to merge 4 commits into
mainfrom
igor/rc/fix-dynamic-config-des

Conversation

@iunanua

@iunanua iunanua commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

  • Rename tracing_sample_rate as tracing_sampling_rate
  • make public DynamicConfig properties

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 10, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 73.06% (-0.01%)

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

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 529 documentation warning(s) found

📦 libdd-remote-config - 529 warning(s)


Updated: 2026-06-15 13:42:09 UTC | Commit: f154779 | missing-docs job results

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Clippy Allow Annotation Report

Comparing clippy allow annotations between branches:

  • Base Branch: origin/main
  • PR Branch: origin/igor/rc/fix-dynamic-config-des

Summary by Rule

Rule Base Branch PR Branch Change

Annotation Counts by File

File Base Branch PR Branch Change

Annotation Stats by Crate

Crate Base Branch PR Branch Change
clippy-annotation-reporter 5 5 No change (0%)
datadog-ffe-ffi 1 1 No change (0%)
datadog-ipc 21 21 No change (0%)
datadog-live-debugger 4 4 No change (0%)
datadog-live-debugger-ffi 10 10 No change (0%)
datadog-profiling-replayer 4 4 No change (0%)
datadog-sidecar 46 46 No change (0%)
libdd-common 13 13 No change (0%)
libdd-common-ffi 12 12 No change (0%)
libdd-data-pipeline 5 5 No change (0%)
libdd-ddsketch 2 2 No change (0%)
libdd-dogstatsd-client 1 1 No change (0%)
libdd-profiling 13 13 No change (0%)
libdd-remote-config 3 3 No change (0%)
libdd-telemetry 20 20 No change (0%)
libdd-tinybytes 4 4 No change (0%)
libdd-trace-normalization 2 2 No change (0%)
libdd-trace-obfuscation 3 3 No change (0%)
libdd-trace-stats 1 1 No change (0%)
libdd-trace-utils 12 11 ✅ -1 (-8.3%)
Total 182 181 ✅ -1 (-0.5%)

About This Report

This report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 5 issue(s) found, showing only errors (advisories, bans, sources)

📦 libdd-remote-config - 5 error(s)

Show output
error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:86:1
   │
86 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
   │
   ├ ID: RUSTSEC-2026-0097
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
   ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
     
     - The `log` and `thread_rng` features are enabled
     - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
     - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
     - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
     - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
     
     `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
   ├ Announcement: https://github.com/rust-random/rand/pull/1763
   ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
   ├ rand v0.8.5
     └── (dev) libdd-common v4.2.0
         └── libdd-remote-config v0.1.0
             └── (dev) libdd-remote-config v0.1.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:97:1
   │
97 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0098
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
   ├ Name constraints for URI names were ignored and therefore accepted.
     
     Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
     
     Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
     
     This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
   ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
   ├ rustls-webpki v0.103.10
     └── rustls v0.23.37
         ├── hyper-rustls v0.27.7
         │   └── libdd-common v4.2.0
         │       └── libdd-remote-config v0.1.0
         │           └── (dev) libdd-remote-config v0.1.0 (*)
         ├── libdd-common v4.2.0 (*)
         └── tokio-rustls v0.26.0
             ├── hyper-rustls v0.27.7 (*)
             └── libdd-common v4.2.0 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:97:1
   │
97 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0099
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
   ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
     
     This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
     This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
     
     Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
     
     This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
   ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
   ├ rustls-webpki v0.103.10
     └── rustls v0.23.37
         ├── hyper-rustls v0.27.7
         │   └── libdd-common v4.2.0
         │       └── libdd-remote-config v0.1.0
         │           └── (dev) libdd-remote-config v0.1.0 (*)
         ├── libdd-common v4.2.0 (*)
         └── tokio-rustls v0.26.0
             ├── hyper-rustls v0.27.7 (*)
             └── libdd-common v4.2.0 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:97:1
   │
97 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0104
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
   ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
     or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
     `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
     
     This panic is reachable prior to a CRL's signature being verified.
     
     Applications that do not use CRLs are not affected.
     
     Thank you to @tynus3 for the report.
   ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
   ├ rustls-webpki v0.103.10
     └── rustls v0.23.37
         ├── hyper-rustls v0.27.7
         │   └── libdd-common v4.2.0
         │       └── libdd-remote-config v0.1.0
         │           └── (dev) libdd-remote-config v0.1.0 (*)
         ├── libdd-common v4.2.0 (*)
         └── tokio-rustls v0.26.0
             ├── hyper-rustls v0.27.7 (*)
             └── libdd-common v4.2.0 (*)

error[vulnerability]: Denial of Service via Stack Exhaustion
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:124:1
    │
124 │ time 0.3.41 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0009
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0009
    ├ ## Impact
      
      When user-provided input is provided to any type that parses with the RFC 2822 format, a denial of
      service attack via stack exhaustion is possible. The attack relies on formally deprecated and
      rarely-used features that are part of the RFC 2822 format used in a malicious manner. Ordinary,
      non-malicious input will never encounter this scenario.
      
      ## Patches
      
      A limit to the depth of recursion was added in v0.3.47. From this version, an error will be returned
      rather than exhausting the stack.
      
      ## Workarounds
      
      Limiting the length of user input is the simplest way to avoid stack exhaustion, as the amount of
      the stack consumed would be at most a factor of the length of the input.
    ├ Announcement: https://github.com/time-rs/time/blob/main/CHANGELOG.md#0347-2026-02-05
    ├ Solution: Upgrade to >=0.3.47 (try `cargo update -p time`)
    ├ time v0.3.41
      └── libdd-remote-config v0.1.0
          └── (dev) libdd-remote-config v0.1.0 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-06-15 13:42:08 UTC | Commit: f154779 | dependency-check job results

@iunanua iunanua changed the title fix(remote_config): rename DynamicConfig::tracing_sample_rate fix(remote_config): rename DynamicConfig::tracing_sample_rate Jun 10, 2026
@iunanua iunanua changed the title fix(remote_config): rename DynamicConfig::tracing_sample_rate fix(remote_config)!: rename DynamicConfig::tracing_sample_rate Jun 10, 2026
@dd-octo-sts

dd-octo-sts Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 7.70 MB 7.70 MB 0% (0 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 83.68 MB 83.68 MB 0% (0 B) 👌
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.35 MB 10.35 MB 0% (0 B) 👌
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 94.79 MB 94.79 MB 0% (0 B) 👌
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 24.82 MB 24.82 MB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 86.89 KB 86.89 KB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 180.82 MB 180.83 MB +0% (+8.00 KB) 👌
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 925.68 MB 925.68 MB +0% (+1.01 KB) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 8.09 MB 8.09 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 86.89 KB 86.89 KB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 23.93 MB 23.93 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 47.78 MB 47.78 MB 0% (0 B) 👌
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 21.53 MB 21.53 MB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 88.26 KB 88.26 KB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 184.91 MB 184.91 MB +0% (+8.00 KB) 👌
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 918.55 MB 918.55 MB +0% (+906 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 6.24 MB 6.24 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 88.26 KB 88.26 KB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 25.66 MB 25.66 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 45.41 MB 45.41 MB 0% (0 B) 👌
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 74.61 MB 74.61 MB 0% (0 B) 👌
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 8.58 MB 8.58 MB 0% (0 B) 👌
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 90.02 MB 90.02 MB 0% (0 B) 👌
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.44 MB 10.44 MB 0% (0 B) 👌

@iunanua iunanua force-pushed the igor/rc/fix-dynamic-config-des branch from 82ba0f6 to c0bb7a8 Compare June 10, 2026 14:53
Wraps every DynamicConfig field in a new `Patch<T>` newtype that encodes
JSON Merge Patch (RFC 7396) semantics:
  - Patch(None)          — field absent on the wire (no change intended)
  - Patch(Some(None))    — field present as JSON null (clear prior override)
  - Patch(Some(Some(v))) — field present with value (set to v)

`Configs` variants now carry `Option<T>` (Some = set, None = clear), and
`From<DynamicConfig> for Vec<Configs>` only emits a variant for fields
that were actually delivered. This fixes the prior collapse where any
APM_TRACING payload missing tracing_sampling_rate looked the same to
consumers as `tracing_sampling_rate: null`, so a payload that updated
unrelated fields (e.g. tracing_tags) would wipe an active remote
sample-rate override.

The struct-level `#[serde(default)]` keeps the new shape free of
per-field `deserialize_with` boilerplate. Test-feature `Serialize` is a
small hand-written impl that skips absent fields to keep the
`dummy_dynamic_config` round-trip intact for the sidecar tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@iunanua iunanua force-pushed the igor/rc/fix-dynamic-config-des branch from c0bb7a8 to 1e238b0 Compare June 10, 2026 14:58
@iunanua iunanua changed the title fix(remote_config)!: rename DynamicConfig::tracing_sample_rate fix(rc)!: fix missing/null deserialization and rename tracing_sample_rate Jun 10, 2026
@iunanua iunanua marked this pull request as ready for review June 11, 2026 10:06
@iunanua iunanua requested review from a team as code owners June 11, 2026 10:06

@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: 1f97593726

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread datadog-sidecar/src/shm_remote_config.rs Outdated

@bantonsson bantonsson 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.

Nice

Comment on lines +159 to +166
pub(crate) tracing_sampling_rate: Patch<f64>,
pub(crate) log_injection_enabled: Patch<bool>,
pub(crate) tracing_tags: Patch<Vec<String>>,
pub(crate) tracing_enabled: Patch<bool>,
pub(crate) tracing_sampling_rules: Patch<Vec<TracingSamplingRule>>,
pub(crate) dynamic_instrumentation_enabled: Patch<bool>,
pub(crate) exception_replay_enabled: Patch<bool>,
pub(crate) code_origin_enabled: Patch<bool>,

@iunanua iunanua Jun 11, 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.

I'm tempted of making them public in order to make it easier to access (and that it isn't necessary to create and iterate over a Vec<Configs> array).

Suggested change
pub(crate) tracing_sampling_rate: Patch<f64>,
pub(crate) log_injection_enabled: Patch<bool>,
pub(crate) tracing_tags: Patch<Vec<String>>,
pub(crate) tracing_enabled: Patch<bool>,
pub(crate) tracing_sampling_rules: Patch<Vec<TracingSamplingRule>>,
pub(crate) dynamic_instrumentation_enabled: Patch<bool>,
pub(crate) exception_replay_enabled: Patch<bool>,
pub(crate) code_origin_enabled: Patch<bool>,
pub tracing_sampling_rate: Patch<f64>,
pub log_injection_enabled: Patch<bool>,
pub tracing_tags: Patch<Vec<String>>,
pub tracing_enabled: Patch<bool>,
pub tracing_sampling_rules: Patch<Vec<TracingSamplingRule>>,
pub dynamic_instrumentation_enabled: Patch<bool>,
pub exception_replay_enabled: Patch<bool>,
pub code_origin_enabled: Patch<bool>,

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.

It might be clearer to re-export them at the module level if that's possible?

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.

done

Comment on lines +159 to +166
pub(crate) tracing_sampling_rate: Patch<f64>,
pub(crate) log_injection_enabled: Patch<bool>,
pub(crate) tracing_tags: Patch<Vec<String>>,
pub(crate) tracing_enabled: Patch<bool>,
pub(crate) tracing_sampling_rules: Patch<Vec<TracingSamplingRule>>,
pub(crate) dynamic_instrumentation_enabled: Patch<bool>,
pub(crate) exception_replay_enabled: Patch<bool>,
pub(crate) code_origin_enabled: Patch<bool>,

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.

It might be clearer to re-export them at the module level if that's possible?

Comment on lines +185 to +193
field!(s, tracing_header_tags);
field!(s, tracing_sampling_rate);
field!(s, log_injection_enabled);
field!(s, tracing_tags);
field!(s, tracing_enabled);
field!(s, tracing_sampling_rules);
field!(s, dynamic_instrumentation_enabled);
field!(s, exception_replay_enabled);
field!(s, code_origin_enabled);

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.

Would it be useful to emit these in a canonical order, e.g. alphabetically sorted by tag?


impl From<DynamicConfig> for Vec<Configs> {
fn from(value: DynamicConfig) -> Self {
let mut vec = vec![];

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.

would it make sense to with_capacity here to reserve space and avoid resizes?

iunanua added a commit that referenced this pull request Jun 15, 2026
…order

Reviewer feedback on PR #2102:
- Make DynamicConfig fields pub so callers can read them directly
  instead of going through Vec<Configs>.
- Re-export the dynamic-config types at the config module level so the
  import path doesn't have to spell out the `dynamic` submodule.
- Emit DynamicConfig's manual Serialize impl in alphabetical order so
  JSON output is deterministic.
- Use Vec::with_capacity in From<DynamicConfig> for Vec<Configs> to
  avoid resizes when all fields are delivered.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@iunanua iunanua force-pushed the igor/rc/fix-dynamic-config-des branch 2 times, most recently from 8af95e4 to 63f6363 Compare June 15, 2026 13:37
The earlier `Patch<T>` design assumed JSON Merge Patch semantics for
APM_TRACING — three states (absent / null / value), where null carried
an explicit "clear this field" signal. The dd-trace-go reference
implementation (ddtrace/tracer/remote_config.go) settles otherwise: it
uses `*float64` / `*[]rcSamplingRule`, which collapse absent and null
into the same `nil`, and the `mergeConfigsByPriority` function only
writes when a value is present. Clearing a remote override happens at
the file level: when the agent stops delivering a file, the merge
re-runs without it and `HandleRC(nil)` reverts to local config. There
is no in-file clear signal.

Match that contract:

- `DynamicConfig` fields are plain `Option<T>` again. `None` covers both
  "field absent" and "field present as null"; the distinction is not
  meaningful at this layer.
- `Configs` variants carry `T` (not `Option<T>`). A variant is only
  emitted when the agent delivered a concrete value, so consumers
  leave any prior remote state untouched if a field is missing.
- The `From<DynamicConfig> for Vec<Configs>` impl unwraps with
  `if let Some(v) = ...`, matching the dd-trace-go merge style.

Kept from the prior iteration:

- `pub` visibility on the struct fields and the tracing-rule types, so
  consumers can also access them directly without going through the
  `Configs` projection.
- `#[serde(alias = "tracing_sample_rate")]` on `tracing_sampling_rate`
  for compatibility with payloads that use the legacy key.
- The sidecar's "preserve dynamic_instrumentation across non-DI
  patches" fix (no upfront `take()`), which is correct regardless of
  the two- vs three-state question — and is now the *only* mechanism
  preserving values across incremental updates.

Tests in `dynamic.rs` cover the four meaningful cases: absent →
no-variant, explicit null → no-variant (indistinguishable from
absent), concrete value → set variant, unrelated-field-present →
no spurious sampling variants. Plus a guard for the legacy
`tracing_sample_rate` alias.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@iunanua iunanua force-pushed the igor/rc/fix-dynamic-config-des branch from 63f6363 to 51a7d2a Compare June 15, 2026 13:40
@github-actions github-actions Bot removed the sidecar label Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants