diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index e71c2450c0..b9e08520a6 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -52,6 +52,19 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - 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. - 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. - The Pydantic AI integration no longer sets the `gen_ai.response.streaming` span attribute. +- 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: + + ```python + from opentelemetry.propagate import set_global_textmap + from opentelemetry.propagators.composite import CompositePropagator + from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator + + from sentry_sdk.integrations.otlp import SentryOTLPPropagator + + set_global_textmap( + CompositePropagator([TraceContextTextMapPropagator(), SentryOTLPPropagator()]) + ) + ``` #### Span operation consolidation diff --git a/sentry_sdk/integrations/otlp.py b/sentry_sdk/integrations/otlp.py index bbf3ffb9cf..da6e4e50a9 100644 --- a/sentry_sdk/integrations/otlp.py +++ b/sentry_sdk/integrations/otlp.py @@ -238,8 +238,8 @@ class OTLPIntegration(Integration): Set to False to setup the TracerProvider manually. :param collector_url: URL of your own OpenTelemetry collector, defaults to None. When set, the exporter will send traces to this URL instead of the Sentry OTLP endpoint derived from the DSN. - :param setup_propagator: Automatically configure the Sentry Propagator for Distributed Tracing, defaults to True. - Set to False to configure propagators manually or to disable propagation. + :param setup_propagator: Replace the global OpenTelemetry propagator with the Sentry Propagator, defaults to False. + By default, the propagators configured in OpenTelemetry are used for Distributed Tracing. :param capture_exceptions: Intercept and capture exceptions on the OpenTelemetry Span in Sentry as well, defaults to False. 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. """ @@ -250,7 +250,7 @@ def __init__( self, setup_otlp_traces_exporter: bool = True, collector_url: "Optional[str]" = None, - setup_propagator: bool = True, + setup_propagator: bool = False, capture_exceptions: bool = False, ) -> None: self.setup_otlp_traces_exporter = setup_otlp_traces_exporter diff --git a/tests/integrations/otlp/test_otlp.py b/tests/integrations/otlp/test_otlp.py index 0537b3192e..1bb5228d4f 100644 --- a/tests/integrations/otlp/test_otlp.py +++ b/tests/integrations/otlp/test_otlp.py @@ -151,26 +151,22 @@ def test_does_not_setup_exporter_when_disabled(sentry_init): assert tracer_provider is existing_tracer_provider -def test_sets_propagator(sentry_init): +def test_does_not_set_propagator_by_default(sentry_init): sentry_init( dsn="https://mysecret@bla.ingest.sentry.io/12312012", integrations=[OTLPIntegration()], ) - propagator = get_global_textmap() - assert isinstance(get_global_textmap(), SentryOTLPPropagator) - assert propagator is not original_propagator + assert get_global_textmap() is original_propagator -def test_does_not_set_propagator_if_disabled(sentry_init): +def test_sets_propagator_if_enabled(sentry_init): sentry_init( dsn="https://mysecret@bla.ingest.sentry.io/12312012", - integrations=[OTLPIntegration(setup_propagator=False)], + integrations=[OTLPIntegration(setup_propagator=True)], ) - propagator = get_global_textmap() - assert not isinstance(propagator, SentryOTLPPropagator) - assert propagator is original_propagator + assert isinstance(get_global_textmap(), SentryOTLPPropagator) def test_otel_propagation_context(sentry_init): @@ -194,7 +190,7 @@ def test_otel_propagation_context(sentry_init): def test_propagator_inject_head_of_trace(sentry_init): sentry_init( dsn="https://mysecret@bla.ingest.sentry.io/12312012", - integrations=[OTLPIntegration()], + integrations=[OTLPIntegration(setup_propagator=True)], ) tracer = trace.get_tracer(__name__) @@ -218,7 +214,7 @@ def test_propagator_inject_head_of_trace(sentry_init): def test_propagator_inject_continue_trace(sentry_init): sentry_init( dsn="https://mysecret@bla.ingest.sentry.io/12312012", - integrations=[OTLPIntegration()], + integrations=[OTLPIntegration(setup_propagator=True)], ) tracer = trace.get_tracer(__name__)