Skip to content

feat: add _dd.p.ksr propagated tag for Knuth sampling rate#180

Merged
bm1549 merged 6 commits intomainfrom
brian.marks/add-ksr-tag
Mar 19, 2026
Merged

feat: add _dd.p.ksr propagated tag for Knuth sampling rate#180
bm1549 merged 6 commits intomainfrom
brian.marks/add-ksr-tag

Conversation

@bm1549
Copy link
Copy Markdown
Contributor

@bm1549 bm1549 commented Mar 11, 2026

What does this PR do?

Adds _dd.p.ksr (Knuth Sampling Rate) as a propagated tag set when agent-based or rule-based sampling decisions are made. The tag is stored in span meta (string type) with up to 6 significant digits and no trailing zeros.

format_sampling_rate now returns Option<String> and guards against invalid inputs (negative, >1.0, NaN, infinity), returning None instead of producing garbage output.

Motivation

To enable consistent sampling across tracers and backend retention filters, the backend needs to know the sampling rate applied by the tracer. Without transmitting the tracer's rate via _dd.p.ksr, backend resampling cannot correctly compute effective rates in multi-stage sampling scenarios.

See RFC: "Transmit Knuth sampling rate to backend"

Additional Notes

Key files changed:

  • datadog-opentelemetry/src/core/constants.rs — Added SAMPLING_KNUTH_RATE_TAG_KEY constant
  • datadog-opentelemetry/src/sampling/datadog_sampler.rs — Added format_sampling_rate() helper (returns Option<String>, defensive against invalid rates) and set ksr in agent/rule sampling paths
  • Updated 2 snapshot JSON files

Related PRs across tracers:

🤖 Generated with Claude Code

bm1549 and others added 2 commits March 10, 2026 21:44
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Expand assert! macro call to multi-line format required by rustfmt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bm1549 bm1549 marked this pull request as ready for review March 17, 2026 01:29
@bm1549 bm1549 requested a review from a team as a code owner March 17, 2026 01:29
Copy link
Copy Markdown
Collaborator

@bantonsson bantonsson left a comment

Choose a reason for hiding this comment

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

Looks good over all. Maybe the formatting should be a bit more defensive.

bm1549 and others added 3 commits March 18, 2026 13:54
… type

Return None for invalid rates (negative, >1.0, NaN, infinity) instead of
producing garbage output. Update call sites to skip the tag when None.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix clippy::manual_range_contains lint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bm1549 bm1549 requested a review from bantonsson March 18, 2026 19:51
@bm1549 bm1549 merged commit dbd805b into main Mar 19, 2026
26 checks passed
@bm1549 bm1549 deleted the brian.marks/add-ksr-tag branch March 19, 2026 14:33
bm1549 added a commit to DataDog/dd-trace-go that referenced this pull request Mar 19, 2026
### What does this PR do?

Fixes `_dd.p.ksr` (Knuth Sampling Rate) to only be set on spans when the
agent has provided sampling rates via `readRatesJSON()`. Previously, ksr
was unconditionally set in `prioritySampler.apply()`, including when the
rate was the initial client-side default (1.0) before any agent response
arrived.

Also refactors `prioritySampler` to consolidate lock acquisitions:
extracts `getRateLocked()` so `apply()` acquires `ps.mu.RLock` only once
to read both the rate and `agentRatesLoaded`.

### Motivation

Cross-language consistency: Python, Java, PHP, and other tracers only
set ksr when actual agent rates or sampling rules are applied, not for
the default fallback. This aligns Go with that behavior.

See RFC: "Transmit Knuth sampling rate to backend"

### Additional Notes

- Added `agentRatesLoaded` bool field to `prioritySampler`, set to
`true` in `readRatesJSON()`
- `apply()` now gates ksr behind `agentRatesLoaded` check
- Extracted `getRateLocked()` to avoid double lock acquisition in
`apply()`
- Rule-based sampling path (`applyTraceRuleSampling` in span.go)
unchanged — correctly always sets ksr
- Tests added: `ksr-not-set-without-agent-rates` and
`ksr-set-after-agent-rates-received`

Related PRs across tracers:
- Java: DataDog/dd-trace-java#10802
- .NET: DataDog/dd-trace-dotnet#8287
- Ruby: DataDog/dd-trace-rb#5436
- Node.js: DataDog/dd-trace-js#7741
- PHP: DataDog/dd-trace-php#3701
- Rust: DataDog/dd-trace-rs#180
- C++: DataDog/dd-trace-cpp#288
- System tests: DataDog/system-tests#6466

### Reviewer's Checklist

- [x] Changed code has unit tests for its functionality at or near 100%
coverage.
- [x] [System-Tests](https://github.com/DataDog/system-tests/) covering
this feature have been added and enabled with the va.b.c-dev version
tag.
- [ ] There is a benchmark for any new code, or changes to existing
code.
- [x] If this interacts with the agent in a new way, a system test has
been added.
- [x] New code is free of linting errors. You can check this by running
`make lint` locally.
- [x] New code doesn't break existing tests. You can check this by
running `make test` locally.
- [ ] Add an appropriate team label so this PR gets put in the right
place for the release notes.
- [ ] All generated files are up to date. You can check this by running
`make generate` locally.
- [ ] Non-trivial go.mod changes, e.g. adding new modules, are reviewed
by @DataDog/dd-trace-go-guild. Make sure all nested modules are up to
date by running `make fix-modules` locally.

Unsure? Have a question? Request a review!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Dario Castañé <dario.castane@datadoghq.com>
Co-authored-by: Mikayla Toffler <46911781+mtoffl01@users.noreply.github.com>
bm1549 added a commit to DataDog/dd-trace-dotnet that referenced this pull request Mar 25, 2026
## Summary of changes

Add `_dd.p.ksr` (Knuth Sampling Rate) propagated tag to spans when
sampling is applied via agent rates or trace sampling rules, per the
[Transmit Knuth Sampling Rate to Backend
RFC](https://docs.google.com/document/d/1Po3qtJb6PGheFeKFSUMv2pVY_y-HFAxTzNLuacCbCXY/edit).

## Reason for change

The backend needs to know the exact sampling rate applied by the tracer
to correctly compute effective rates during resampling (e.g., tracer 0.5
× backend 0.5 = effective 0.25). This tag enables that by propagating
the rate via `x-datadog-tags` and W3C `tracestate`.

## Implementation details

- Set `_dd.p.ksr` in `TraceContext.SetSamplingPriority()` for
`AgentRate`, `LocalTraceSamplingRule`, `RemoteAdaptiveSamplingRule`, and
`RemoteUserSamplingRule` mechanisms
- Use `TryAddTag` to preserve the original rate (consistent with
`AppliedSamplingRate ??= rate` semantics)
- Format with `"0.######"` (up to 6 decimal digits, no trailing zeros,
no scientific notation) per RFC spec
- Added `.IsOptional("_dd.p.ksr")` to `SpanTagAssertion.cs` so
integration test tag validators accept the new tag

## Test coverage

- Unit tests in `TraceContextTests_KnuthSamplingRate.cs`:
  - KSR set for agent rate sampling
- KSR set for trace sampling rules (local, remote adaptive, remote user)
- KSR NOT set for manual, AppSec, rate limiter, or single span
mechanisms
  - KSR preserved on subsequent sampling calls (TryAddTag semantics)
- Formatting with up to 6 decimal digits (boundary values including
small rates like 0.00001)
- System tests in [system-tests
#6466](DataDog/system-tests#6466)

## Other details

Related PRs across tracers:
- Java: DataDog/dd-trace-java#10802
- Ruby: DataDog/dd-trace-rb#5436
- Node.js: DataDog/dd-trace-js#7741
- PHP: DataDog/dd-trace-php#3701
- Rust: DataDog/dd-trace-rs#180
- C++: DataDog/dd-trace-cpp#288

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants