Skip to content

Commit f01cb0f

Browse files
committed
Remove scope.span = setter and make sure scope.span reference is
correct in context manager regardless of source of span.
1 parent a012fe4 commit f01cb0f

File tree

9 files changed

+40
-46
lines changed

9 files changed

+40
-46
lines changed

MIGRATION_GUIDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
168168
- `span_id`
169169
- `parent_span_id`: you can supply a `parent_span` instead
170170
- The `Scope.transaction` property has been removed. To obtain the root span (previously transaction), use `Scope.root_span`. To set the root span's (transaction's) name, use `Scope.set_transaction_name()`.
171+
- The `Scope.span =` setter has been removed.
171172
- Passing a list or `None` for `failed_request_status_codes` in the Starlette integration is no longer supported. Pass a set of integers instead.
172173
- The `span` argument of `Scope.trace_propagation_meta` is no longer supported.
173174
- Setting `Scope.user` directly is no longer supported. Use `Scope.set_user()` instead.

sentry_sdk/integrations/celery/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ def setup_once():
100100
def _set_status(status):
101101
# type: (str) -> None
102102
with capture_internal_exceptions():
103-
scope = sentry_sdk.get_current_scope()
104-
if scope.span is not None:
105-
scope.span.set_status(status)
103+
span = sentry_sdk.get_current_span()
104+
if span is not None:
105+
span.set_status(status)
106106

107107

108108
def _capture_exception(task, exc_info):

sentry_sdk/opentelemetry/contextvars_context.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from typing import cast, TYPE_CHECKING
22

3-
from opentelemetry.trace import set_span_in_context
3+
from opentelemetry.trace import get_current_span, set_span_in_context
4+
from opentelemetry.trace.span import INVALID_SPAN
45
from opentelemetry.context import Context, get_value, set_value
56
from opentelemetry.context.contextvars_context import ContextVarsRuntimeContext
67

78
import sentry_sdk
9+
from sentry_sdk.tracing import Span
810
from sentry_sdk.opentelemetry.consts import (
911
SENTRY_SCOPES_KEY,
1012
SENTRY_FORK_ISOLATION_SCOPE_KEY,
@@ -60,6 +62,12 @@ def attach(self, context):
6062
else:
6163
new_scope = current_scope.fork()
6264

65+
# carry forward a wrapped span reference since the otel context is always the
66+
# source of truth for the active span
67+
current_span = get_current_span(context)
68+
if current_span != INVALID_SPAN:
69+
new_scope._span = Span(otel_span=get_current_span(context))
70+
6371
if should_use_isolation_scope:
6472
new_isolation_scope = should_use_isolation_scope
6573
elif should_fork_isolation_scope:

sentry_sdk/scope.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -732,12 +732,6 @@ def span(self):
732732
"""Get current tracing span."""
733733
return self._span
734734

735-
@span.setter
736-
def span(self, span):
737-
# type: (Optional[Span]) -> None
738-
"""Set current tracing span."""
739-
self._span = span
740-
741735
@property
742736
def profile(self):
743737
# type: () -> Optional[Profile]

sentry_sdk/tracing.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from opentelemetry.sdk.trace import ReadableSpan
1616
from opentelemetry.version import __version__ as otel_version
1717

18-
import sentry_sdk
1918
from sentry_sdk.consts import (
2019
DEFAULT_SPAN_NAME,
2120
DEFAULT_SPAN_ORIGIN,
@@ -280,10 +279,6 @@ def __enter__(self):
280279
# set as the implicit current context
281280
self._ctx_token = context.attach(ctx)
282281

283-
# get the new scope that was forked on context.attach
284-
self.scope = sentry_sdk.get_current_scope()
285-
self.scope.span = self
286-
287282
return self
288283

289284
def __exit__(self, ty, value, tb):

tests/integrations/rust_tracing/test_rust_tracing.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def test_nested_on_new_span_on_close(sentry_init, capture_events):
176176
assert "version" not in second_span_data
177177

178178

179-
def test_on_new_span_without_transaction(sentry_init):
179+
def test_no_spans_without_transaction(sentry_init):
180180
rust_tracing = FakeRustTracing()
181181
integration = RustTracingIntegration(
182182
"test_on_new_span_without_transaction", rust_tracing.set_layer_impl
@@ -185,11 +185,9 @@ def test_on_new_span_without_transaction(sentry_init):
185185

186186
assert sentry_sdk.get_current_span() is None
187187

188-
# Should still create a span hierarchy, it just will not be under a txn
189188
rust_tracing.new_span(RustTracingLevel.Info, 3)
190189
current_span = sentry_sdk.get_current_span()
191-
assert current_span is not None
192-
assert current_span.root_span is None
190+
assert current_span is None
193191

194192

195193
def test_on_event_exception(sentry_init, capture_events):
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from opentelemetry import trace
2+
3+
import sentry_sdk
4+
from sentry_sdk.tracing import Span
5+
6+
7+
tracer = trace.get_tracer(__name__)
8+
9+
10+
def test_scope_span_reference_started_with_sentry(sentry_init):
11+
sentry_init(traces_sample_rate=1.0)
12+
13+
with sentry_sdk.start_span(name="test") as span:
14+
assert sentry_sdk.get_current_span() == span
15+
assert sentry_sdk.get_current_scope().span == span
16+
17+
18+
def test_scope_span_reference_started_with_otel(sentry_init):
19+
sentry_init(traces_sample_rate=1.0)
20+
21+
with tracer.start_as_current_span("test") as otel_span:
22+
wrapped_span = Span(otel_span=otel_span)
23+
assert sentry_sdk.get_current_span() == wrapped_span
24+
assert sentry_sdk.get_current_scope().span == wrapped_span

tests/opentelemetry/test_potel.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111

1212
@pytest.fixture(autouse=True)
1313
def sentry_init_potel(sentry_init):
14-
sentry_init(
15-
traces_sample_rate=1.0,
16-
_experiments={"otel_powered_performance": True},
17-
)
14+
sentry_init(traces_sample_rate=1.0)
1815

1916

2017
def test_root_span_transaction_payload_started_with_otel_only(capture_envelopes):

tests/test_api.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,6 @@
2121
from tests.conftest import SortedBaggage
2222

2323

24-
@pytest.mark.forked
25-
def test_get_current_span():
26-
fake_scope = mock.MagicMock()
27-
fake_scope.span = mock.MagicMock()
28-
assert get_current_span(fake_scope) == fake_scope.span
29-
30-
fake_scope.span = None
31-
assert get_current_span(fake_scope) is None
32-
33-
34-
@pytest.mark.forked
35-
def test_get_current_span_current_scope(sentry_init):
36-
sentry_init()
37-
38-
assert get_current_span() is None
39-
40-
scope = get_current_scope()
41-
fake_span = mock.MagicMock()
42-
scope.span = fake_span
43-
44-
assert get_current_span() == fake_span
45-
46-
4724
@pytest.mark.forked
4825
def test_get_current_span_current_scope_with_span(sentry_init):
4926
sentry_init()

0 commit comments

Comments
 (0)