From 36a7887c29c7997f36081da10033845aafaac84a Mon Sep 17 00:00:00 2001 From: Matt Perpick Date: Fri, 8 Jul 2016 03:27:15 +0000 Subject: [PATCH] tracer: fix leaking spans when submission is disabled When trace submission was disabled, we weren't properly cleaning up the parent child hiearchy causing all spans to be buffered in memory. This should fix that. --- ddtrace/tracer.py | 17 +++++++++-------- tests/test_tracer.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ddtrace/tracer.py b/ddtrace/tracer.py index ddb187bdd8f..4327f331134 100644 --- a/ddtrace/tracer.py +++ b/ddtrace/tracer.py @@ -91,9 +91,6 @@ def current_span(self): def record(self, span): """ Record the given finished span. """ - if not self.enabled: - return - spans = [] with self._spans_lock: self._spans.append(span) @@ -108,12 +105,16 @@ def record(self, span): def write(self, spans): """ Submit the given spans to the agent. """ - if spans: - if self.debug_logging: - log.debug("submitting %s spans", len(spans)) - for span in spans: - log.debug("\n%s", span.pprint()) + if not spans: + return # nothing to do + + if self.debug_logging: + log.debug("writing %s spans (enabled:%s)", len(spans), self.enabled) + for span in spans: + log.debug("\n%s", span.pprint()) + if self.enabled: + # only submit the spans if we're actually enabled. self._writer.write(spans, self._services) def set_service_info(self, service, app, app_type): diff --git a/tests/test_tracer.py b/tests/test_tracer.py index 8d2309cd63b..6a2230d3b73 100644 --- a/tests/test_tracer.py +++ b/tests/test_tracer.py @@ -90,6 +90,20 @@ def test_tracer_disabled(): s.set_tag("a", "b") assert not writer.pop() +def test_tracer_disabled_mem_leak(): + # ensure that if the tracer is disabled, we still remove things from the + # span buffer upon finishing. + writer = DummyWriter() + tracer = Tracer(writer=writer) + tracer.enabled = False + s1 = tracer.trace("foo") + s1.finish() + p1 = tracer.current_span() + s2 = tracer.trace("bar") + assert not s2._parent, s2._parent + s2.finish() + assert not p1, p1 + def test_sampling(): writer = DummyWriter() tracer = Tracer(writer=writer, sample_rate=0.5)