Skip to content

Commit 6fe893d

Browse files
authored
fix(otel): Prevent baggage from being overwritten (#6709)
1 parent 1cf0ae0 commit 6fe893d

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

packages/opentelemetry-node/src/propagator.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import {
2+
Baggage,
23
Context,
34
isSpanContextValid,
5+
propagation,
46
TextMapGetter,
5-
TextMapPropagator,
67
TextMapSetter,
78
trace,
89
TraceFlags,
910
} from '@opentelemetry/api';
10-
import { isTracingSuppressed } from '@opentelemetry/core';
11+
import { isTracingSuppressed, W3CBaggagePropagator } from '@opentelemetry/core';
1112
import {
1213
baggageHeaderToDynamicSamplingContext,
13-
dynamicSamplingContextToSentryBaggageHeader,
1414
extractTraceparentData,
15+
SENTRY_BAGGAGE_KEY_PREFIX,
1516
} from '@sentry/utils';
1617

1718
import {
@@ -25,7 +26,7 @@ import { SENTRY_SPAN_PROCESSOR_MAP } from './spanprocessor';
2526
/**
2627
* Injects and extracts `sentry-trace` and `baggage` headers from carriers.
2728
*/
28-
export class SentryPropagator implements TextMapPropagator {
29+
export class SentryPropagator extends W3CBaggagePropagator {
2930
/**
3031
* @inheritDoc
3132
*/
@@ -41,10 +42,18 @@ export class SentryPropagator implements TextMapPropagator {
4142

4243
if (span.transaction) {
4344
const dynamicSamplingContext = span.transaction.getDynamicSamplingContext();
44-
const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
45-
if (sentryBaggageHeader) {
46-
setter.set(carrier, SENTRY_BAGGAGE_HEADER, sentryBaggageHeader);
47-
}
45+
46+
const baggage = propagation.getBaggage(context) || propagation.createBaggage({});
47+
const baggageWithSentryInfo = Object.entries(dynamicSamplingContext).reduce<Baggage>(
48+
(b, [dscKey, dscValue]) => {
49+
if (dscValue) {
50+
return b.setEntry(`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`, { value: dscValue });
51+
}
52+
return b;
53+
},
54+
baggage,
55+
);
56+
super.inject(propagation.setBaggage(context, baggageWithSentryInfo), carrier, setter);
4857
}
4958
}
5059
}

packages/opentelemetry-node/test/propagator.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { defaultTextMapGetter, defaultTextMapSetter, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api';
1+
import {
2+
defaultTextMapGetter,
3+
defaultTextMapSetter,
4+
propagation,
5+
ROOT_CONTEXT,
6+
trace,
7+
TraceFlags,
8+
} from '@opentelemetry/api';
29
import { suppressTracing } from '@opentelemetry/core';
310
import { Hub, makeMain } from '@sentry/core';
411
import { addExtensionMethods, Transaction } from '@sentry/tracing';
@@ -138,6 +145,27 @@ describe('SentryPropagator', () => {
138145
expect(carrier[SENTRY_TRACE_HEADER]).toBe(sentryTrace);
139146
});
140147

148+
it('should include existing baggage', () => {
149+
const transactionContext = {
150+
name: 'sampled-transaction',
151+
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
152+
spanId: '6e0c63257de34c92',
153+
sampled: true,
154+
};
155+
const spanContext = {
156+
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
157+
spanId: '6e0c63257de34c92',
158+
traceFlags: TraceFlags.SAMPLED,
159+
};
160+
createTransactionAndMaybeSpan(type, transactionContext);
161+
const context = trace.setSpanContext(ROOT_CONTEXT, spanContext);
162+
const baggage = propagation.createBaggage({ foo: { value: 'bar' } });
163+
propagator.inject(propagation.setBaggage(context, baggage), carrier, defaultTextMapSetter);
164+
expect(carrier[SENTRY_BAGGAGE_HEADER]).toBe(
165+
'foo=bar,sentry-environment=production,sentry-release=1.0.0,sentry-transaction=sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b',
166+
);
167+
});
168+
141169
it('should NOT set baggage and sentry-trace header if instrumentation is supressed', () => {
142170
const spanContext = {
143171
traceId: 'd4cda95b652f4a1592b449d5929fda1b',

0 commit comments

Comments
 (0)