Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions sentry_sdk/integrations/opentelemetry/span_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(self):
self._children_spans = defaultdict(
list
) # type: DefaultDict[int, List[ReadableSpan]]
self._dropped_spans = defaultdict(lambda: 0) # type: DefaultDict[int, int]

def on_start(self, span, parent_context=None):
# type: (Span, Optional[Context]) -> None
Expand Down Expand Up @@ -143,12 +144,17 @@ def _flush_root_span(self, span):
if not transaction_event:
return

collected_spans, dropped_spans = self._collect_children(span)
spans = []
for child in self._collect_children(span):
for child in collected_spans:
span_json = self._span_to_json(child)
if span_json:
spans.append(span_json)

transaction_event["spans"] = spans
if dropped_spans > 0:
transaction_event["_dropped_spans"] = dropped_spans

# TODO-neel-potel sort and cutoff max spans

sentry_sdk.capture_event(transaction_event)
Expand All @@ -166,25 +172,29 @@ def _append_child_span(self, span):
children_spans = self._children_spans[span.parent.span_id]
if len(children_spans) < max_spans:
children_spans.append(span)
else:
self._dropped_spans[span.parent.span_id] += 1

def _collect_children(self, span):
# type: (ReadableSpan) -> List[ReadableSpan]
# type: (ReadableSpan) -> tuple[List[ReadableSpan], int]
if not span.context:
return []
return [], 0

children = []
dropped_spans = 0
bfs_queue = deque() # type: Deque[int]
bfs_queue.append(span.context.span_id)

while bfs_queue:
parent_span_id = bfs_queue.popleft()
node_children = self._children_spans.pop(parent_span_id, [])
dropped_spans += self._dropped_spans.pop(parent_span_id, 0)
children.extend(node_children)
bfs_queue.extend(
[child.context.span_id for child in node_children if child.context]
)

return children
return children, dropped_spans

# we construct the event from scratch here
# and not use the current Transaction class for easier refactoring
Expand Down
5 changes: 2 additions & 3 deletions tests/tracing/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_span_trimming(sentry_init, capture_events):

with start_span(name="hi"):
for i in range(10):
with start_span(op="foo{}".format(i)):
with start_span(op=f"foo{i}"):
pass

(event,) = events
Expand All @@ -29,7 +29,6 @@ def test_span_trimming(sentry_init, capture_events):

assert event["_meta"]["spans"][""]["len"] == 10
assert "_dropped_spans" not in event
assert "dropped_spans" not in event


def test_span_data_scrubbing_and_trimming(sentry_init, capture_events):
Expand All @@ -42,7 +41,7 @@ def test_span_data_scrubbing_and_trimming(sentry_init, capture_events):
span.set_data("datafoo", "databar")

for i in range(10):
with start_span(op="foo{}".format(i)):
with start_span(op=f"foo{i}"):
pass

(event,) = events
Expand Down
Loading