Skip to content

Commit 0d2d15c

Browse files
committed
celery
1 parent 191b66a commit 0d2d15c

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

sentry_sdk/integrations/celery.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from sentry_sdk.hub import Hub
1212
from sentry_sdk.integrations import Integration, DidNotEnable
1313
from sentry_sdk.integrations.logging import ignore_logger
14-
from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK
14+
from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, TRANSACTION_SOURCE_TASK
1515
from sentry_sdk._types import TYPE_CHECKING
1616
from sentry_sdk.utils import (
1717
capture_internal_exceptions,
@@ -158,14 +158,29 @@ def apply_async(*args, **kwargs):
158158
# Note: kwargs can contain headers=None, so no setdefault!
159159
# Unsure which backend though.
160160
kwarg_headers = kwargs.get("headers") or {}
161+
existing_baggage = kwarg_headers.get(BAGGAGE_HEADER_NAME)
161162
kwarg_headers.update(headers)
163+
if existing_baggage:
164+
kwarg_headers[BAGGAGE_HEADER_NAME] = "{},{}".format(
165+
existing_baggage, headers[BAGGAGE_HEADER_NAME]
166+
)
162167

163168
# https://github.com/celery/celery/issues/4875
164169
#
165170
# Need to setdefault the inner headers too since other
166171
# tracing tools (dd-trace-py) also employ this exact
167172
# workaround and we don't want to break them.
168-
kwarg_headers.setdefault("headers", {}).update(headers)
173+
kwarg_headers.setdefault("headers", {})
174+
existing_baggage = kwarg_headers["headers"].get(
175+
BAGGAGE_HEADER_NAME
176+
)
177+
kwarg_headers["headers"].update(headers)
178+
if existing_baggage:
179+
kwarg_headers["headers"][
180+
BAGGAGE_HEADER_NAME
181+
] = "{},{}".format(
182+
existing_baggage, headers[BAGGAGE_HEADER_NAME]
183+
)
169184

170185
# Add the Sentry options potentially added in `sentry_apply_entry`
171186
# to the headers (done when auto-instrumenting Celery Beat tasks)

tests/integrations/celery/test_celery.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
from celery import Celery, VERSION
1313
from celery.bin import worker
14-
from celery.signals import task_success
1514

1615
try:
1716
from unittest import mock # python 3.3 and above
@@ -493,17 +492,36 @@ def test_task_headers(celery):
493492
"sentry-monitor-check-in-id": "123abc",
494493
}
495494

496-
@celery.task(name="dummy_task")
497-
def dummy_task(x, y):
498-
return x + y
499-
500-
def crons_task_success(sender, **kwargs):
501-
headers = _get_headers(sender)
502-
assert headers == sentry_crons_setup
503-
504-
task_success.connect(crons_task_success)
495+
@celery.task(name="dummy_task", bind=True)
496+
def dummy_task(self, x, y):
497+
return _get_headers(self)
505498

506499
# This is how the Celery Beat auto-instrumentation starts a task
507500
# in the monkey patched version of `apply_async`
508501
# in `sentry_sdk/integrations/celery.py::_wrap_apply_async()`
509-
dummy_task.apply_async(args=(1, 0), headers=sentry_crons_setup)
502+
result = dummy_task.apply_async(args=(1, 0), headers=sentry_crons_setup)
503+
assert result.get() == sentry_crons_setup
504+
505+
506+
def test_baggage_propagation(init_celery):
507+
celery = init_celery(traces_sample_rate=1.0, release="abcdef")
508+
509+
@celery.task(name="dummy_task", bind=True)
510+
def dummy_task(self, x, y):
511+
return _get_headers(self)
512+
513+
with start_transaction() as transaction:
514+
result = dummy_task.apply_async(
515+
args=(1, 0),
516+
headers={"baggage": "custom=value", "headers": {"baggage": "custom=value"}},
517+
).get()
518+
519+
assert sorted(result["baggage"].split(",")) == sorted(
520+
[
521+
"sentry-release=abcdef",
522+
"sentry-trace_id={}".format(transaction.trace_id),
523+
"sentry-environment=production",
524+
"sentry-sample_rate=1.0",
525+
"custom=value",
526+
]
527+
)

0 commit comments

Comments
 (0)