Skip to content

Commit 7ef20df

Browse files
authored
Merge baggage headers (incoming and new created ones) (#3001)
If the incoming headers include a baggage header that also includes sentry trace data, use this incoming trace information and merge with other baggage information of the current transaction. (Before it was just concatenating incoming baggage information with the baggage information from the current transaction which lead sometimes to ever growing baggage headers.)
1 parent 9fc2f44 commit 7ef20df

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

sentry_sdk/integrations/celery/__init__.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, TRANSACTION_SOURCE_TASK
1717
from sentry_sdk._types import TYPE_CHECKING
1818
from sentry_sdk.scope import Scope
19+
from sentry_sdk.tracing_utils import Baggage
1920
from sentry_sdk.utils import (
2021
capture_internal_exceptions,
2122
ensure_integration_enabled,
@@ -168,6 +169,7 @@ def _update_celery_task_headers(original_headers, span, monitor_beat_tasks):
168169
headers = dict(
169170
Scope.get_current_scope().iter_trace_propagation_headers(span=span)
170171
)
172+
171173
if monitor_beat_tasks:
172174
headers.update(
173175
{
@@ -182,10 +184,23 @@ def _update_celery_task_headers(original_headers, span, monitor_beat_tasks):
182184

183185
combined_baggage = sentry_baggage or existing_baggage
184186
if sentry_baggage and existing_baggage:
185-
combined_baggage = "{},{}".format(
186-
existing_baggage,
187-
sentry_baggage,
187+
# Merge incoming and sentry baggage, where the sentry trace information
188+
# in the incoming baggage takes precedence and the third-party items
189+
# are concatenated.
190+
incoming = Baggage.from_incoming_header(existing_baggage)
191+
combined = Baggage.from_incoming_header(sentry_baggage)
192+
combined.sentry_items.update(incoming.sentry_items)
193+
combined.third_party_items = ",".join(
194+
[
195+
x
196+
for x in [
197+
combined.third_party_items,
198+
incoming.third_party_items,
199+
]
200+
if x is not None and x != ""
201+
]
188202
)
203+
combined_baggage = combined.serialize(include_third_party=True)
189204

190205
updated_headers.update(headers)
191206
if combined_baggage:

tests/integrations/celery/test_update_celery_task_headers.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from copy import copy
12
import pytest
23

34
from unittest import mock
45

56
from sentry_sdk.integrations.celery import _update_celery_task_headers
67
import sentry_sdk
8+
from sentry_sdk.tracing_utils import Baggage
79

810

911
BAGGAGE_VALUE = (
@@ -115,17 +117,25 @@ def test_span_with_transaction_custom_headers(sentry_init):
115117

116118
assert updated_headers["sentry-trace"] == span.to_traceparent()
117119
assert updated_headers["headers"]["sentry-trace"] == span.to_traceparent()
118-
# This is probably the cause for https://github.com/getsentry/sentry-python/issues/2916
119-
# If incoming baggage includes sentry data, we should not concatenate a new baggage value to it
120-
# but just keep the incoming sentry baggage values and concatenate new third-party items to the baggage
121-
# I have some code somewhere where I have implemented this.
122-
assert (
123-
updated_headers["baggage"]
124-
== headers["baggage"] + "," + transaction.get_baggage().serialize()
120+
121+
incoming_baggage = Baggage.from_incoming_header(headers["baggage"])
122+
combined_baggage = copy(transaction.get_baggage())
123+
combined_baggage.sentry_items.update(incoming_baggage.sentry_items)
124+
combined_baggage.third_party_items = ",".join(
125+
[
126+
x
127+
for x in [
128+
combined_baggage.third_party_items,
129+
incoming_baggage.third_party_items,
130+
]
131+
if x is not None and x != ""
132+
]
125133
)
126-
assert (
127-
updated_headers["headers"]["baggage"]
128-
== headers["baggage"] + "," + transaction.get_baggage().serialize()
134+
assert updated_headers["baggage"] == combined_baggage.serialize(
135+
include_third_party=True
136+
)
137+
assert updated_headers["headers"]["baggage"] == combined_baggage.serialize(
138+
include_third_party=True
129139
)
130140

131141

0 commit comments

Comments
 (0)