File tree Expand file tree Collapse file tree
sentry_sdk/integrations/opentelemetry
tests/integrations/opentelemetry Expand file tree Collapse file tree Original file line number Diff line number Diff 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
Original file line number Diff line number Diff line change @@ -83,6 +83,8 @@ class SentrySpanProcessor(SpanProcessor):
8383 # The currently open spans. Elements will be discarded after SPAN_MAX_TIME_OPEN_MINUTES
8484 open_spans : "dict[int, set[str]]" = {}
8585
86+ initialized : "bool" = False
87+
8688 def __new__ (cls ) -> "SentrySpanProcessor" :
8789 if not hasattr (cls , "instance" ):
8890 cls .instance = super ().__new__ (cls )
@@ -91,10 +93,15 @@ def __new__(cls) -> "SentrySpanProcessor":
9193 return cls .instance # type: ignore[misc]
9294
9395 def __init__ (self ) -> None :
96+ if self .initialized :
97+ return
98+
9499 @add_global_event_processor
95100 def global_event_processor (event : "Event" , hint : "Hint" ) -> "Event" :
96101 return link_trace_context_to_error_event (event , self .otel_span_map )
97102
103+ self .initialized = True
104+
98105 def _prune_old_spans (self : "SentrySpanProcessor" ) -> None :
99106 """
100107 Prune spans that have been open for too long.
Original file line number Diff line number Diff line change 1+ from sentry_sdk .integrations .opentelemetry .integration import (
2+ OpenTelemetryIntegration ,
3+ )
4+ from opentelemetry import trace
5+ from sentry_sdk .scope import global_event_processors
6+
7+
18import pytest
29
310from unittest import mock
@@ -298,3 +305,21 @@ def test_inject_sentry_span_baggage():
298305 "baggage" ,
299306 baggage .serialize (),
300307 )
308+
309+
310+ def test_inject_no_memory_leak ():
311+
312+ OpenTelemetryIntegration .setup_once ()
313+
314+ tracer = trace .get_tracer (__name__ )
315+ propagator = SentryPropagator ()
316+
317+ cnt_before = len (global_event_processors )
318+
319+ with tracer .start_as_current_span ("bar" ) as new_span :
320+ context = set_span_in_context (new_span )
321+ carrier = "any_carrier"
322+ propagator .inject (carrier , context )
323+
324+ cnt_after = len (global_event_processors )
325+ assert cnt_after == cnt_before
Original file line number Diff line number Diff line change 1+ from sentry_sdk .scope import global_event_processors
12import time
23from datetime import datetime , timezone
34from unittest import mock
@@ -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
You can’t perform that action at this time.
0 commit comments