Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED consistent #5223

Merged
merged 8 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions packages/dd-trace/src/opentracing/propagation/text_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const tracestateTagKeyFilter = /[^\x21-\x2b\x2d-\x3c\x3e-\x7e]/g
const tracestateTagValueFilter = /[^\x20-\x2b\x2d-\x3a\x3c-\x7d]/g
const invalidSegment = /^0+$/
const zeroTraceId = '0000000000000000'
const hex16 = /^[0-9A-Fa-f]{16}$/

class TextMapPropagator {
constructor (config) {
Expand Down Expand Up @@ -482,10 +483,20 @@ class TextMapPropagator {
}
break
}
default:
default: {
if (!key.startsWith('t.')) continue
spanContext._trace.tags[`_dd.p.${key.slice(2)}`] = value
.replace(/[\x7e]/gm, '=')
const subKey = key.slice(2) // e.g. t.tid -> tid
const transformedValue = value.replace(/[\x7e]/gm, '=')

// If subkey is tid then do nothing because trace header tid should always be preserved
if (subKey === 'tid') {
if (!hex16.test(value) || spanContext._trace.tags['_dd.p.tid'] !== transformedValue) {
log.error(`Invalid trace id ${value} in tracestate, skipping`)
}
continue
}
spanContext._trace.tags[`_dd.p.${subKey}`] = transformedValue
}
}
}
})
Expand Down Expand Up @@ -645,7 +656,11 @@ class TextMapPropagator {
log.error('Trace tags from carrier are invalid, skipping extraction.')
return
}

// Check if value is a valid 16 character lower-case hexadecimal encoded number as per spec
if (key === '_dd.p.tid' && !(hex16.test(value))) {
log.error(`Invalid _dd.p.tid tag ${value}, skipping`)
continue
}
tags[key] = value
}

Expand Down
59 changes: 59 additions & 0 deletions packages/dd-trace/test/opentracing/propagation/text_map.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,41 @@ describe('TextMapPropagator', () => {
expect(spanContextD._baggageItems).to.deep.equal({})
})

it('should discard malformed tids', () => {
// tid with malformed characters
let carrier = {
'x-datadog-trace-id': '1234567890123456789',
'x-datadog-parent-id': '987654321',
'x-datadog-tags': '_dd.p.tid=1234567890abcdeX'
}
let spanContext = propagator.extract(carrier)
expect(spanContext.toTraceId()).to.equal(carrier['x-datadog-trace-id'])
expect(spanContext.toSpanId()).to.equal(carrier['x-datadog-parent-id'])
expect(spanContext._trace.tags).to.not.have.property('_dd.p.tid')

// tid too long
carrier = {
'x-datadog-trace-id': '234567890123456789',
'x-datadog-parent-id': '987654321',
'x-datadog-tags': '_dd.p.tid=1234567890abcdef1'
}
spanContext = propagator.extract(carrier)
expect(spanContext.toTraceId()).to.equal(carrier['x-datadog-trace-id'])
expect(spanContext.toSpanId()).to.equal(carrier['x-datadog-parent-id'])
expect(spanContext._trace.tags).to.not.have.property('_dd.p.tid')

// tid too short
carrier = {
'x-datadog-trace-id': '1234567890123456789',
'x-datadog-parent-id': '987654321',
'x-datadog-tags': '_dd.p.tid=1234567890abcde'
}
spanContext = propagator.extract(carrier)
expect(spanContext.toTraceId()).to.equal(carrier['x-datadog-trace-id'])
expect(spanContext.toSpanId()).to.equal(carrier['x-datadog-parent-id'])
expect(spanContext._trace.tags).to.not.have.property('_dd.p.tid')
})

// temporary test. On the contrary, it SHOULD extract baggage
it('should not extract baggage when it is the only propagation style', () => {
config = new Config({
Expand Down Expand Up @@ -630,6 +665,30 @@ describe('TextMapPropagator', () => {
expect(spanContext._trace.tags).to.have.property('_dd.parent_id', '2244eeee6666aaaa')
})

it('should preserve trace header tid when tracestate contains an inconsistent tid', () => {
textMap.traceparent = '00-640cfd8d00000000abcdefab12345678-000000003ade68b1-01'
textMap.tracestate = 'dd=t.tid:640cfd8d0000ffff'
config.tracePropagationStyle.extract = ['tracecontext']

const carrier = textMap
const spanContext = propagator.extract(carrier)

expect(spanContext._traceId.toString(16)).to.equal('640cfd8d00000000abcdefab12345678')
expect(spanContext._trace.tags).to.have.property('_dd.p.tid', '640cfd8d00000000')
})

it('should preserve trace header tid when tracestate contains a malformed tid', () => {
textMap.traceparent = '00-640cfd8d00000000abcdefab12345678-000000003ade68b1-01'
textMap.tracestate = 'dd=t.tid:XXXX'
config.tracePropagationStyle.extract = ['tracecontext']

const carrier = textMap
const spanContext = propagator.extract(carrier)

expect(spanContext._traceId.toString(16)).to.equal('640cfd8d00000000abcdefab12345678')
expect(spanContext._trace.tags).to.have.property('_dd.p.tid', '640cfd8d00000000')
})

it('should set the last datadog parent id to zero when p: is NOT in the tracestate', () => {
textMap.traceparent = '00-0000000000000000000000000000007B-0000000000000456-01'
textMap.tracestate = 'other=gg,dd=s:-1;'
Expand Down
Loading