Skip to content

Commit 4946ada

Browse files
authored
fix dd-otel baggage handling
keep span-specific baggage APIs exclusively for legacy, and use global baggage for dd-otel baggage translation
1 parent a6a3694 commit 4946ada

2 files changed

Lines changed: 47 additions & 97 deletions

File tree

packages/dd-trace/src/opentelemetry/context_manager.js

Lines changed: 19 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const { trace, ROOT_CONTEXT, propagation } = require('@opentelemetry/api')
44
const { storage } = require('../../../datadog-core')
5+
const { getAllBaggageItems, setBaggageItem, removeAllBaggageItems } = require('../baggage')
56

67
const tracer = require('../../')
78
const SpanContext = require('./span_context')
@@ -19,31 +20,26 @@ class ContextManager {
1920

2021
const storedSpan = store ? trace.getSpan(store) : null
2122

23+
// Convert DD baggage to OTel format
24+
const baggages = getAllBaggageItems()
25+
const hasBaggage = Object.keys(baggages).length > 0
26+
let otelBaggages
27+
if (hasBaggage) {
28+
const entries = {}
29+
for (const [key, value] of Object.entries(baggages)) {
30+
entries[key] = { value }
31+
}
32+
otelBaggages = propagation.createBaggage(entries)
33+
}
34+
2235
// If stored span wraps the active DD span, prefer the stored context
2336
if (storedSpan && storedSpan._ddSpan === activeSpan) {
24-
const baggages = JSON.parse(activeSpan.getAllBaggageItems())
25-
if (Object.keys(baggages).length > 0) {
26-
const entries = {}
27-
for (const [key, value] of Object.entries(baggages)) {
28-
entries[key] = { value }
29-
}
30-
const otelBaggages = propagation.createBaggage(entries)
31-
return propagation.setBaggage(store, otelBaggages)
32-
}
37+
if (otelBaggages) return propagation.setBaggage(store, otelBaggages)
3338
return store
3439
}
3540

3641
if (!activeSpan) {
37-
const storedBaggageItems = storedSpan?._spanContext?._ddContext?._baggageItems
38-
if (storedBaggageItems) {
39-
const baggages = storedBaggageItems
40-
const entries = {}
41-
for (const [key, value] of Object.entries(baggages)) {
42-
entries[key] = { value }
43-
}
44-
const otelBaggages = propagation.createBaggage(entries)
45-
return propagation.setBaggage(baseContext, otelBaggages)
46-
}
42+
if (otelBaggages) return propagation.setBaggage(baseContext, otelBaggages)
4743
return baseContext
4844
}
4945

@@ -53,18 +49,6 @@ class ContextManager {
5349
ddContext._otelSpanContext = new SpanContext(ddContext)
5450
}
5551

56-
// Convert DD baggage to OTel format
57-
const baggages = JSON.parse(activeSpan.getAllBaggageItems())
58-
const hasBaggage = Object.keys(baggages).length > 0
59-
let otelBaggages
60-
if (hasBaggage) {
61-
const entries = {}
62-
for (const [key, value] of Object.entries(baggages)) {
63-
entries[key] = { value }
64-
}
65-
otelBaggages = propagation.createBaggage(entries)
66-
}
67-
6852
if (store && trace.getSpanContext(store) === ddContext._otelSpanContext) {
6953
return otelBaggages ? propagation.setBaggage(store, otelBaggages) : store
7054
}
@@ -86,22 +70,11 @@ class ContextManager {
8670
if (baggages) {
8771
baggageItems = baggages.getAllEntries()
8872
}
89-
if (span && span._ddSpan) {
90-
// does otel always override datadog?
91-
span._ddSpan.removeAllBaggageItems()
92-
for (const baggage of baggageItems) {
93-
span._ddSpan.setBaggageItem(baggage[0], baggage[1].value)
94-
}
95-
return ddScope.activate(span._ddSpan, run)
96-
}
97-
// span instanceof NonRecordingSpan
98-
const ddContext = span?._spanContext?._ddContext
99-
if (ddContext && ddContext._baggageItems) {
100-
ddContext._baggageItems = {}
101-
for (const baggage of baggageItems) {
102-
ddContext._baggageItems[baggage[0]] = baggage[1].value
103-
}
73+
removeAllBaggageItems()
74+
for (const baggage of baggageItems) {
75+
setBaggageItem(baggage[0], baggage[1].value)
10476
}
77+
if (span && span._ddSpan) return ddScope.activate(span._ddSpan, run)
10578
return run()
10679
}
10780

packages/dd-trace/test/opentelemetry/context_manager.spec.js

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,12 @@ const assert = require('node:assert/strict')
55
const { describe, it, beforeEach } = require('mocha')
66
const { context, propagation, trace, ROOT_CONTEXT } = require('@opentelemetry/api')
77
const api = require('@opentelemetry/api')
8+
const { getAllBaggageItems, setBaggageItem, removeBaggageItem } = require('../../src/baggage')
89

910
require('../setup/core')
1011
const ContextManager = require('../../src/opentelemetry/context_manager')
1112
const TracerProvider = require('../../src/opentelemetry/tracer_provider')
12-
const tracer = require('../../').init()
13-
14-
function makeSpan (...args) {
15-
const tracerProvider = new TracerProvider()
16-
tracerProvider.register()
17-
const tracer = tracerProvider.getTracer()
18-
return tracer.startSpan(...args)
19-
}
13+
require('../../').init()
2014

2115
function getTracer () {
2216
const tracerProvider = new TracerProvider()
@@ -138,63 +132,46 @@ describe('OTel Context Manager', () => {
138132
}
139133
const baggage = propagation.createBaggage(entries)
140134
const contextWithBaggage = propagation.setBaggage(context.active(), baggage)
141-
const span = makeSpan('otel-to-dd')
142-
const contextWithSpan = trace.setSpan(contextWithBaggage, span)
143-
api.context.with(contextWithSpan, () => {
144-
assert.strictEqual(tracer.scope().active().getBaggageItem('foo'), 'bar')
135+
api.context.with(contextWithBaggage, () => {
136+
assert.deepStrictEqual(getAllBaggageItems(), { foo: 'bar' })
145137
})
146138
})
147139

148140
it('should propagate baggage from a datadog span to an otel span', () => {
149-
const baggageKey = 'raccoon'
150-
const baggageVal = 'chunky'
151-
const ddSpan = tracer.startSpan('dd-to-otel')
152-
ddSpan.setBaggageItem(baggageKey, baggageVal)
153-
tracer.scope().activate(ddSpan, () => {
154-
const baggages = propagation.getActiveBaggage().getAllEntries()
155-
assert.strictEqual(baggages.length, 1)
156-
const baggage = baggages[0]
157-
assert.strictEqual(baggage[0], baggageKey)
158-
assert.strictEqual(baggage[1].value, baggageVal)
159-
})
141+
setBaggageItem('raccoon', 'chunky')
142+
assert.deepStrictEqual(propagation.getActiveBaggage().getAllEntries(),
143+
[['raccoon', { value: 'chunky' }]]
144+
)
160145
})
161146

162147
it('should handle dd-otel baggage conflict', () => {
163-
const ddSpan = tracer.startSpan('dd')
164-
ddSpan.setBaggageItem('key1', 'dd1')
165-
let contextWithUpdatedBaggages
166-
tracer.scope().activate(ddSpan, () => {
167-
let baggages = propagation.getBaggage(api.context.active())
168-
baggages = baggages.setEntry('key1', { value: 'otel1' })
169-
baggages = baggages.setEntry('key2', { value: 'otel2' })
170-
contextWithUpdatedBaggages = propagation.setBaggage(api.context.active(), baggages)
171-
})
172-
assert.deepStrictEqual(JSON.parse(ddSpan.getAllBaggageItems()), { key1: 'dd1' })
148+
setBaggageItem('key1', 'dd1')
149+
let baggages = propagation.getActiveBaggage()
150+
baggages = baggages.setEntry('key1', { value: 'otel1' })
151+
baggages = baggages.setEntry('key2', { value: 'otel2' })
152+
const contextWithUpdatedBaggages = propagation.setBaggage(context.active(), baggages)
153+
assert.deepStrictEqual(getAllBaggageItems(), { key1: 'dd1' })
173154
api.context.with(contextWithUpdatedBaggages, () => {
174-
assert.deepStrictEqual(JSON.parse(ddSpan.getAllBaggageItems()), { key1: 'otel1', key2: 'otel2' })
175-
ddSpan.setBaggageItem('key2', 'dd2')
176-
assert.deepStrictEqual(propagation.getActiveBaggage().getAllEntries(),
177-
[['key1', { value: 'otel1' }], ['key2', { value: 'dd2' }]]
178-
)
155+
assert.deepStrictEqual(getAllBaggageItems(), { key1: 'otel1', key2: 'otel2' })
179156
})
157+
setBaggageItem('key2', 'dd2')
158+
assert.deepStrictEqual(propagation.getActiveBaggage().getAllEntries(),
159+
[['key1', { value: 'otel1' }], ['key2', { value: 'dd2' }]]
160+
)
180161
})
181162

182163
it('should handle dd-otel baggage removal', () => {
183-
const ddSpan = tracer.startSpan('dd')
184-
ddSpan.setBaggageItem('key1', 'dd1')
185-
ddSpan.setBaggageItem('key2', 'dd2')
186-
let contextWithUpdatedBaggages
187-
tracer.scope().activate(ddSpan, () => {
188-
let baggages = propagation.getBaggage(api.context.active())
189-
baggages = baggages.removeEntry('key1')
190-
contextWithUpdatedBaggages = propagation.setBaggage(api.context.active(), baggages)
191-
})
192-
assert.deepStrictEqual(JSON.parse(ddSpan.getAllBaggageItems()), { key1: 'dd1', key2: 'dd2' })
164+
setBaggageItem('key1', 'dd1')
165+
setBaggageItem('key2', 'dd2')
166+
let baggages = propagation.getActiveBaggage()
167+
baggages = baggages.removeEntry('key1')
168+
const contextWithUpdatedBaggages = propagation.setBaggage(context.active(), baggages)
169+
assert.deepStrictEqual(getAllBaggageItems(), { key1: 'dd1', key2: 'dd2' })
193170
api.context.with(contextWithUpdatedBaggages, () => {
194-
assert.deepStrictEqual(JSON.parse(ddSpan.getAllBaggageItems()), { key2: 'dd2' })
195-
ddSpan.removeBaggageItem('key2')
196-
assert.deepStrictEqual(propagation.getActiveBaggage().getAllEntries(), [])
171+
assert.deepStrictEqual(getAllBaggageItems(), { key2: 'dd2' })
197172
})
173+
removeBaggageItem('key2')
174+
assert.deepStrictEqual(propagation.getActiveBaggage(), undefined)
198175
})
199176

200177
it('should return active span', () => {

0 commit comments

Comments
 (0)