Skip to content

Commit a0f249a

Browse files
bm1549claude
andauthored
Add _dd.p.ksr propagated tag for Knuth sampling rate (#7741)
* Add _dd.p.ksr propagated tag for Knuth sampling rate Co-Authored-By: Claude Opus 4.6 <[email protected]> * Do not set _dd.p.ksr when default sampling mechanism is used Only set the SAMPLING_KNUTH_RATE (_dd.p.ksr) tag when actual agent rates have been received (SAMPLING_MECHANISM_AGENT), not when using the built-in default sampler (SAMPLING_MECHANISM_DEFAULT). Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent f3c5706 commit a0f249a

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

packages/dd-trace/src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module.exports = {
2323
SPAN_SAMPLING_MAX_PER_SECOND: '_dd.span_sampling.max_per_second',
2424
DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
2525
DECISION_MAKER_KEY: '_dd.p.dm',
26+
SAMPLING_KNUTH_RATE: '_dd.p.ksr',
2627
PROCESS_ID: 'process_id',
2728
ERROR_TYPE: 'error.type',
2829
ERROR_MESSAGE: 'error.message',

packages/dd-trace/src/priority_sampler.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,21 @@ const {
3131
SAMPLING_LIMIT_DECISION,
3232
SAMPLING_AGENT_DECISION,
3333
DECISION_MAKER_KEY,
34+
SAMPLING_KNUTH_RATE,
3435
} = require('./constants')
3536

3637
const DEFAULT_KEY = 'service:,env:'
3738

39+
/**
40+
* Formats a sampling rate as a string with up to 6 significant digits and no trailing zeros.
41+
*
42+
* @param {number} rate
43+
* @returns {string}
44+
*/
45+
function formatKnuthRate (rate) {
46+
return Number(rate.toPrecision(6)).toString()
47+
}
48+
3849
const defaultSampler = new Sampler(AUTO_KEEP)
3950

4051
/**
@@ -254,6 +265,7 @@ class PrioritySampler {
254265
*/
255266
#getPriorityByRule (context, rule) {
256267
context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
268+
context._trace.tags[SAMPLING_KNUTH_RATE] = formatKnuthRate(rule.sampleRate)
257269
context._sampling.mechanism = SAMPLING_MECHANISM_RULE
258270
if (rule.provenance === 'customer') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_USER
259271
if (rule.provenance === 'dynamic') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_DYNAMIC
@@ -290,9 +302,15 @@ class PrioritySampler {
290302
// TODO: Change underscored properties to private ones.
291303
const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY]
292304

293-
context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
305+
const rate = sampler.rate()
306+
context._trace[SAMPLING_AGENT_DECISION] = rate
294307

295-
context._sampling.mechanism = sampler === defaultSampler ? SAMPLING_MECHANISM_DEFAULT : SAMPLING_MECHANISM_AGENT
308+
if (sampler === defaultSampler) {
309+
context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
310+
} else {
311+
context._trace.tags[SAMPLING_KNUTH_RATE] = formatKnuthRate(rate)
312+
context._sampling.mechanism = SAMPLING_MECHANISM_AGENT
313+
}
296314

297315
return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
298316
}

packages/dd-trace/test/priority_sampler.spec.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const {
1818
SAMPLING_MECHANISM_REMOTE_DYNAMIC,
1919
DECISION_MAKER_KEY,
2020
SAMPLING_MECHANISM_APPSEC,
21+
SAMPLING_KNUTH_RATE,
2122
} = require('../src/constants')
2223
const { ASM } = require('../src/standalone/product')
2324

@@ -369,6 +370,65 @@ describe('PrioritySampler', () => {
369370
assert.strictEqual(context._trace['_dd.limit_psr'], 1)
370371
})
371372

373+
it('should not set _dd.p.ksr tag for default sampling mechanism', () => {
374+
prioritySampler.sample(span)
375+
376+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], undefined)
377+
})
378+
379+
it('should set _dd.p.ksr tag for agent sampling with explicit rates', () => {
380+
prioritySampler.update({
381+
'service:test,env:test': 0.5,
382+
})
383+
prioritySampler.sample(span)
384+
385+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], '0.5')
386+
})
387+
388+
it('should set _dd.p.ksr tag for rule-based sampling', () => {
389+
prioritySampler = new PrioritySampler('test', {
390+
sampleRate: 0.5,
391+
})
392+
prioritySampler.sample(span)
393+
394+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], '0.5')
395+
})
396+
397+
it('should set _dd.p.ksr tag for rule-based sampling with rate 0', () => {
398+
prioritySampler = new PrioritySampler('test', {
399+
sampleRate: 0,
400+
})
401+
prioritySampler.sample(span)
402+
403+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], '0')
404+
})
405+
406+
it('should set _dd.p.ksr tag for rate 1.0 as "1"', () => {
407+
prioritySampler = new PrioritySampler('test', {
408+
sampleRate: 1.0,
409+
})
410+
prioritySampler.sample(span)
411+
412+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], '1')
413+
})
414+
415+
it('should set _dd.p.ksr tag as a string type', () => {
416+
prioritySampler.update({
417+
'service:test,env:test': 0.5,
418+
})
419+
prioritySampler.sample(span)
420+
421+
assert.strictEqual(typeof context._trace.tags[SAMPLING_KNUTH_RATE], 'string')
422+
})
423+
424+
it('should not set _dd.p.ksr tag for manual sampling', () => {
425+
context._tags[MANUAL_KEEP] = undefined
426+
427+
prioritySampler.sample(context)
428+
429+
assert.strictEqual(context._trace.tags[SAMPLING_KNUTH_RATE], undefined)
430+
})
431+
372432
it('should ignore empty span', () => {
373433
prioritySampler.sample()
374434
prioritySampler.sample()

0 commit comments

Comments
 (0)