Skip to content

Commit 504b649

Browse files
merge master
2 parents 349f70a + 7b2cd99 commit 504b649

5 files changed

Lines changed: 44 additions & 2 deletions

File tree

sentry_sdk/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from contextlib import contextmanager
44
from typing import TYPE_CHECKING
55

6-
from sentry_sdk import tracing_utils, Client # isort: skip
6+
from sentry_sdk import Client, tracing_utils
77
from sentry_sdk._init_implementation import init
88
from sentry_sdk.consts import INSTRUMENTER
99
from sentry_sdk.crons import monitor

sentry_sdk/integrations/opentelemetry/propagator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def inject(
109109

110110
span_id = trace.format_span_id(current_span_context.span_id)
111111

112-
span_map = SentrySpanProcessor().otel_span_map
112+
span_map = SentrySpanProcessor.otel_span_map
113113
sentry_span = span_map.get(span_id, None)
114114
if not sentry_span:
115115
return

sentry_sdk/integrations/opentelemetry/span_processor.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class SentrySpanProcessor(SpanProcessor):
8787
# The currently open spans. Elements will be discarded after SPAN_MAX_TIME_OPEN_MINUTES
8888
open_spans: "dict[int, set[str]]" = {}
8989

90+
initialized: "bool" = False
91+
9092
def __new__(cls) -> "SentrySpanProcessor":
9193
if not hasattr(cls, "instance"):
9294
cls.instance = super().__new__(cls)
@@ -95,10 +97,15 @@ def __new__(cls) -> "SentrySpanProcessor":
9597
return cls.instance # type: ignore[misc]
9698

9799
def __init__(self) -> None:
100+
if self.initialized:
101+
return
102+
98103
@add_global_event_processor
99104
def global_event_processor(event: "Event", hint: "Hint") -> "Event":
100105
return link_trace_context_to_error_event(event, self.otel_span_map)
101106

107+
self.initialized = True
108+
102109
def _prune_old_spans(self: "SentrySpanProcessor") -> None:
103110
"""
104111
Prune spans that have been open for too long.

tests/integrations/opentelemetry/test_propagator.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from unittest.mock import MagicMock
33

44
import pytest
5+
from opentelemetry import trace
56
from opentelemetry.context import get_current
67
from opentelemetry.trace import (
78
SpanContext,
@@ -14,8 +15,12 @@
1415
SENTRY_BAGGAGE_KEY,
1516
SENTRY_TRACE_KEY,
1617
)
18+
from sentry_sdk.integrations.opentelemetry.integration import (
19+
OpenTelemetryIntegration,
20+
)
1721
from sentry_sdk.integrations.opentelemetry.propagator import SentryPropagator
1822
from sentry_sdk.integrations.opentelemetry.span_processor import SentrySpanProcessor
23+
from sentry_sdk.scope import global_event_processors
1924
from sentry_sdk.tracing_utils import Baggage
2025

2126

@@ -297,3 +302,21 @@ def test_inject_sentry_span_baggage():
297302
"baggage",
298303
baggage.serialize(),
299304
)
305+
306+
307+
def test_inject_no_memory_leak():
308+
309+
OpenTelemetryIntegration.setup_once()
310+
311+
tracer = trace.get_tracer(__name__)
312+
propagator = SentryPropagator()
313+
314+
cnt_before = len(global_event_processors)
315+
316+
with tracer.start_as_current_span("bar") as new_span:
317+
context = set_span_in_context(new_span)
318+
carrier = "any_carrier"
319+
propagator.inject(carrier, context)
320+
321+
cnt_after = len(global_event_processors)
322+
assert cnt_after == cnt_before

tests/integrations/opentelemetry/test_span_processor.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
SentrySpanProcessor,
1212
link_trace_context_to_error_event,
1313
)
14+
from sentry_sdk.scope import global_event_processors
1415
from sentry_sdk.tracing import Span, Transaction
1516
from sentry_sdk.tracing_utils import extract_sentrytrace_data
1617
from sentry_sdk.utils import Dsn
@@ -621,3 +622,14 @@ def test_pruning_old_spans_on_end():
621622
span_processor.on_end(otel_span)
622623
assert sorted(list(span_processor.otel_span_map.keys())) == ["111111111abcdef"]
623624
assert sorted(list(span_processor.open_spans.values())) == [{"111111111abcdef"}]
625+
626+
627+
def test_no_memory_leak():
628+
span_processor_1 = SentrySpanProcessor()
629+
cnt_before = len(global_event_processors)
630+
631+
span_processor_2 = SentrySpanProcessor()
632+
633+
cnt_after = len(global_event_processors)
634+
assert span_processor_1 is span_processor_2
635+
assert cnt_before == cnt_after

0 commit comments

Comments
 (0)