Skip to content

Commit 48a5db2

Browse files
fix(otlp)!: Keep setup_propagator, default it to False
Follow the sentry-ruby approach (getsentry/sentry-ruby#3063) and keep setup_propagator as an opt-in instead of removing it. Co-Authored-By: Ivana Kellyer <ivana.kellyer@sentry.io>
1 parent 2c3f6c7 commit 48a5db2

3 files changed

Lines changed: 25 additions & 14 deletions

File tree

‎MIGRATION_GUIDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
5252
- Whether the MCP integration records tool arguments, tool results, and prompt contents is now controlled by `data_collection`'s new `mcp` setting (`{"inputs": bool, "outputs": bool}`, both `True` by default) instead of the `gen_ai` setting.
5353
- With `handled_tool_call_exceptions=True` (the default), the Pydantic AI integration now reports an error for every failed tool argument validation attempt, including retries. Previously, only one error was reported per tool call.
5454
- The Pydantic AI integration no longer sets the `gen_ai.response.streaming` span attribute.
55-
- The `OTLPIntegration` no longer sets up a propagator, and its `setup_propagator` option was removed. Distributed tracing now uses the propagators configured in OpenTelemetry (by default, W3C `traceparent` and `baggage`). If you need to propagate Sentry's `sentry-trace` and `baggage` headers, for example to talk to services instrumented with Sentry SDKs instead of OpenTelemetry, set up the `SentryOTLPPropagator` manually:
55+
- The `OTLPIntegration` no longer sets up a propagator by default: `setup_propagator` now defaults to `False`. Distributed tracing now uses the propagators configured in OpenTelemetry (by default, W3C `traceparent` and `baggage`) instead of Sentry's `sentry-trace` and `baggage` headers. To get the old behavior back, set `OTLPIntegration(setup_propagator=True)`. To propagate both W3C and Sentry headers, set up the `SentryOTLPPropagator` manually instead:
5656

5757
```python
5858
from opentelemetry.propagate import set_global_textmap

‎sentry_sdk/integrations/otlp.py‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
set_value,
2525
)
2626
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
27+
from opentelemetry.propagate import set_global_textmap
2728
from opentelemetry.propagators.textmap import (
2829
CarrierT,
2930
Getter,
@@ -131,14 +132,6 @@ def _sentry_patched_record_exception(
131132

132133
class SentryOTLPPropagator(TextMapPropagator):
133134
"""
134-
Propagator for the Sentry-specific ``sentry-trace`` and ``baggage`` headers.
135-
136-
The OTLPIntegration doesn't set up any propagator. OpenTelemetry's default
137-
propagators (W3C ``traceparent`` and ``baggage``) are used unless configured
138-
otherwise. If you need to continue traces from or propagate traces to services
139-
that only understand Sentry's headers, set this propagator up manually with
140-
``opentelemetry.propagate.set_global_textmap``.
141-
142135
!!! Note regarding baggage:
143136
We cannot meaningfully populate a new baggage as a head SDK
144137
when we are using OTLP since we don't have any sort of transaction semantic to
@@ -245,6 +238,8 @@ class OTLPIntegration(Integration):
245238
Set to False to setup the TracerProvider manually.
246239
:param collector_url: URL of your own OpenTelemetry collector, defaults to None.
247240
When set, the exporter will send traces to this URL instead of the Sentry OTLP endpoint derived from the DSN.
241+
:param setup_propagator: Replace the global OpenTelemetry propagator with the Sentry Propagator, defaults to False.
242+
By default, the propagators configured in OpenTelemetry are used for Distributed Tracing.
248243
:param capture_exceptions: Intercept and capture exceptions on the OpenTelemetry Span in Sentry as well, defaults to False.
249244
Set to True to turn on capturing but be aware that since Sentry captures most exceptions, duplicate exceptions might be dropped by DedupeIntegration in many cases.
250245
"""
@@ -255,10 +250,12 @@ def __init__(
255250
self,
256251
setup_otlp_traces_exporter: bool = True,
257252
collector_url: "Optional[str]" = None,
253+
setup_propagator: bool = False,
258254
capture_exceptions: bool = False,
259255
) -> None:
260256
self.setup_otlp_traces_exporter = setup_otlp_traces_exporter
261257
self.collector_url = collector_url
258+
self.setup_propagator = setup_propagator
262259
self.capture_exceptions = capture_exceptions
263260

264261
@staticmethod
@@ -274,4 +271,9 @@ def setup_once_with_options(
274271
dsn: "Optional[str]" = options.get("dsn") if options else None
275272
setup_otlp_traces_exporter(dsn, collector_url=self.collector_url)
276273

274+
if self.setup_propagator:
275+
logger.debug("[OTLP] Setting up propagator for distributed tracing")
276+
# TODO-neel better propagator support, chain with existing ones if possible instead of replacing
277+
set_global_textmap(SentryOTLPPropagator())
278+
277279
setup_capture_exceptions()

‎tests/integrations/otlp/test_otlp.py‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def test_does_not_setup_exporter_when_disabled(sentry_init):
151151
assert tracer_provider is existing_tracer_provider
152152

153153

154-
def test_does_not_set_propagator(sentry_init):
154+
def test_does_not_set_propagator_by_default(sentry_init):
155155
sentry_init(
156156
dsn="https://mysecret@bla.ingest.sentry.io/12312012",
157157
integrations=[OTLPIntegration()],
@@ -160,6 +160,15 @@ def test_does_not_set_propagator(sentry_init):
160160
assert get_global_textmap() is original_propagator
161161

162162

163+
def test_sets_propagator_if_enabled(sentry_init):
164+
sentry_init(
165+
dsn="https://mysecret@bla.ingest.sentry.io/12312012",
166+
integrations=[OTLPIntegration(setup_propagator=True)],
167+
)
168+
169+
assert isinstance(get_global_textmap(), SentryOTLPPropagator)
170+
171+
163172
def test_otel_propagation_context(sentry_init):
164173
sentry_init(
165174
dsn="https://mysecret@bla.ingest.sentry.io/12312012",
@@ -181,11 +190,11 @@ def test_otel_propagation_context(sentry_init):
181190
def test_propagator_inject_head_of_trace(sentry_init):
182191
sentry_init(
183192
dsn="https://mysecret@bla.ingest.sentry.io/12312012",
184-
integrations=[OTLPIntegration()],
193+
integrations=[OTLPIntegration(setup_propagator=True)],
185194
)
186195

187196
tracer = trace.get_tracer(__name__)
188-
propagator = SentryOTLPPropagator()
197+
propagator = get_global_textmap()
189198
carrier = {}
190199

191200
with tracer.start_as_current_span("foo") as span:
@@ -205,11 +214,11 @@ def test_propagator_inject_head_of_trace(sentry_init):
205214
def test_propagator_inject_continue_trace(sentry_init):
206215
sentry_init(
207216
dsn="https://mysecret@bla.ingest.sentry.io/12312012",
208-
integrations=[OTLPIntegration()],
217+
integrations=[OTLPIntegration(setup_propagator=True)],
209218
)
210219

211220
tracer = trace.get_tracer(__name__)
212-
propagator = SentryOTLPPropagator()
221+
propagator = get_global_textmap()
213222
carrier = {}
214223

215224
incoming_headers = {

0 commit comments

Comments
 (0)