Skip to content

Commit 858cacd

Browse files
authored
Implement span limits on span processor (#3881)
1 parent 5a4bdde commit 858cacd

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

sentry_sdk/integrations/arq.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import sys
22

3-
from opentelemetry.trace.status import StatusCode
4-
53
import sentry_sdk
64
from sentry_sdk.consts import OP, SPANSTATUS
75
from sentry_sdk.integrations import DidNotEnable, Integration

sentry_sdk/integrations/logging.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
# Note: Ignoring by logger name here is better than mucking with thread-locals.
4141
# We do not necessarily know whether thread-locals work 100% correctly in the user's environment.
4242
_IGNORED_LOGGERS = set(
43-
["sentry_sdk.errors", "urllib3.connectionpool", "urllib3.connection", "opentelemetry.*"]
43+
[
44+
"sentry_sdk.errors",
45+
"urllib3.connectionpool",
46+
"urllib3.connection",
47+
"opentelemetry.*",
48+
]
4449
)
4550

4651

sentry_sdk/integrations/opentelemetry/span_processor.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
from sentry_sdk._types import Event
4444

4545

46+
DEFAULT_MAX_SPANS = 1000
47+
48+
4649
class SentrySpanProcessor(SpanProcessor):
4750
"""
4851
Converts OTel spans into Sentry spans so they can be sent to the Sentry backend.
@@ -79,7 +82,7 @@ def on_end(self, span):
7982
# if have a root span ending, we build a transaction and send it
8083
self._flush_root_span(span)
8184
else:
82-
self._children_spans[span.parent.span_id].append(span)
85+
self._append_child_span(span)
8386

8487
# TODO-neel-potel not sure we need a clear like JS
8588
def shutdown(self):
@@ -150,6 +153,20 @@ def _flush_root_span(self, span):
150153

151154
sentry_sdk.capture_event(transaction_event)
152155

156+
def _append_child_span(self, span):
157+
# type: (ReadableSpan) -> None
158+
if not span.parent:
159+
return
160+
161+
max_spans = (
162+
sentry_sdk.get_client().options["_experiments"].get("max_spans")
163+
or DEFAULT_MAX_SPANS
164+
)
165+
166+
children_spans = self._children_spans[span.parent.span_id]
167+
if len(children_spans) < max_spans:
168+
children_spans.append(span)
169+
153170
def _collect_children(self, span):
154171
# type: (ReadableSpan) -> List[ReadableSpan]
155172
if not span.context:

tests/tracing/test_misc.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88
from sentry_sdk.utils import Dsn
99

1010

11+
def test_span_trimming(sentry_init, capture_events):
12+
sentry_init(traces_sample_rate=1.0, _experiments={"max_spans": 3})
13+
events = capture_events()
14+
15+
with start_span(name="hi"):
16+
for i in range(10):
17+
with start_span(op="foo{}".format(i)):
18+
pass
19+
20+
(event,) = events
21+
22+
assert len(event["spans"]) == 3
23+
24+
span1, span2, span3 = event["spans"]
25+
assert span1["op"] == "foo0"
26+
assert span2["op"] == "foo1"
27+
assert span3["op"] == "foo2"
28+
29+
1130
def test_transaction_naming(sentry_init, capture_events):
1231
sentry_init(traces_sample_rate=1.0)
1332
events = capture_events()

0 commit comments

Comments
 (0)