Skip to content

Commit 76b5373

Browse files
committed
Fix breadcrumb in subprocess
1 parent 72c1ad8 commit 76b5373

File tree

6 files changed

+72
-20
lines changed

6 files changed

+72
-20
lines changed

sentry_sdk/integrations/clickhouse_driver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def _inner_end(*args: P.args, **kwargs: P.kwargs) -> T:
119119

120120
with capture_internal_exceptions():
121121
span.scope.add_breadcrumb(
122-
message=span._data.pop("query"),
123-
category="query",
122+
message=span._data.pop("query"),
123+
category="query",
124124
data=span._data,
125125
)
126126

sentry_sdk/integrations/stdlib.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
SENSITIVE_DATA_SUBSTITUTE,
1414
capture_internal_exceptions,
1515
ensure_integration_enabled,
16+
get_current_thread_meta,
1617
is_sentry_url,
1718
logger,
1819
safe_repr,
@@ -225,6 +226,24 @@ def sentry_patched_popen_init(self, *a, **kw):
225226
rv = old_popen_init(self, *a, **kw)
226227

227228
span.set_tag("subprocess.pid", self.pid)
229+
230+
with capture_internal_exceptions():
231+
thread_id, thread_name = get_current_thread_meta()
232+
breadcrumb_data = {
233+
"subprocess.pid": self.pid,
234+
"thread.id": thread_id,
235+
"thread.name": thread_name,
236+
}
237+
if cwd:
238+
breadcrumb_data["subprocess.cwd"] = cwd
239+
240+
sentry_sdk.add_breadcrumb(
241+
type="subprocess",
242+
category="subprocess",
243+
message=description,
244+
data=breadcrumb_data,
245+
)
246+
228247
return rv
229248

230249
subprocess.Popen.__init__ = sentry_patched_popen_init # type: ignore

sentry_sdk/tracing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,7 @@ def get_profile_context(self):
15861586
def set_context(self, key, value):
15871587
# type: (str, Any) -> None
15881588
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1589+
15891590
# TODO-neel-potel we cannot add dicts here
15901591

15911592
self.set_attribute(f"{SentrySpanAttribute.CONTEXT}.{key}", value)

sentry_sdk/tracing_utils.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,22 +158,15 @@ def maybe_create_breadcrumbs_from_span(scope, span):
158158
# type: (sentry_sdk.Scope, sentry_sdk.tracing.Span) -> None
159159
if span.op == OP.DB_REDIS:
160160
scope.add_breadcrumb(
161-
message=span.description,
162-
type="redis",
163-
category="redis",
161+
message=span.description,
162+
type="redis",
163+
category="redis",
164164
data=span._tags,
165165
)
166166
elif span.op == OP.HTTP_CLIENT:
167167
scope.add_breadcrumb(
168-
type="http",
169-
category="httplib",
170-
data=span._data,
171-
)
172-
elif span.op == OP.SUBPROCESS:
173-
scope.add_breadcrumb(
174-
type="subprocess",
175-
category="subprocess",
176-
message=span.description,
168+
type="http",
169+
category="httplib",
177170
data=span._data,
178171
)
179172

tests/integrations/stdlib/test_subprocess.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import subprocess
44
import sys
55
from collections.abc import Mapping
6+
from unittest import mock
67

78
import pytest
89

9-
from sentry_sdk import capture_message, start_transaction
10+
from sentry_sdk import capture_exception, capture_message, start_transaction
1011
from sentry_sdk.integrations.stdlib import StdlibIntegration
1112
from tests.conftest import ApproxDict
1213

@@ -224,3 +225,37 @@ def test_subprocess_span_origin(sentry_init, capture_events):
224225

225226
assert event["spans"][2]["op"] == "subprocess.wait"
226227
assert event["spans"][2]["origin"] == "auto.subprocess.stdlib.subprocess"
228+
229+
230+
def test_subprocess_breadcrumb(sentry_init, capture_events):
231+
sentry_init()
232+
events = capture_events()
233+
234+
args = [
235+
sys.executable,
236+
"-c",
237+
"print('hello world')",
238+
]
239+
popen = subprocess.Popen(args)
240+
popen.communicate()
241+
popen.poll()
242+
243+
try:
244+
1 / 0
245+
except ZeroDivisionError as ex:
246+
capture_exception(ex)
247+
248+
(event,) = events
249+
breadcrumbs = event["breadcrumbs"]["values"]
250+
assert len(breadcrumbs) == 1
251+
252+
(crumb,) = breadcrumbs
253+
assert crumb["type"] == "subprocess"
254+
assert crumb["category"] == "subprocess"
255+
assert crumb["message"] == " ".join(args)
256+
assert crumb["timestamp"] == mock.ANY
257+
assert crumb["data"] == {
258+
"subprocess.pid": popen.pid,
259+
"thread.id": mock.ANY,
260+
"thread.name": mock.ANY,
261+
}

tests/test_breadcrumbs.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ def test_breadcrumbs(sentry_init, capture_envelopes):
3333
sentry_sdk.add_breadcrumb(message="breadcrumb1", **add_breadcrumbs_kwargs)
3434

3535
with sentry_sdk.start_span(name="span2", op="function"):
36-
sentry_sdk.add_breadcrumb(message="breadcrumb2", **add_breadcrumbs_kwargs)
36+
sentry_sdk.add_breadcrumb(
37+
message="breadcrumb2", **add_breadcrumbs_kwargs
38+
)
3739

3840
# Spans that create breadcrumbs automatically
3941
with sentry_sdk.start_span(name="span3", op=OP.DB_REDIS) as span3:
@@ -49,14 +51,16 @@ def test_breadcrumbs(sentry_init, capture_envelopes):
4951
span5.set_tag("span5_tag", "tag on the subprocess span")
5052

5153
with sentry_sdk.start_span(name="span6", op="function") as span6:
52-
# This data on the span is not added to custom breadcrumbs.
54+
# This data on the span is not added to custom breadcrumbs.
5355
# Data from the span is only added to automatic breadcrumbs shown above
5456
span6.set_data("span6_data", "data on span6")
5557
span6.set_tag("span6_tag", "tag on the span6")
56-
sentry_sdk.add_breadcrumb(message="breadcrumb6", **add_breadcrumbs_kwargs)
58+
sentry_sdk.add_breadcrumb(
59+
message="breadcrumb6", **add_breadcrumbs_kwargs
60+
)
5761

5862
try:
59-
1/0
63+
1 / 0
6064
except ZeroDivisionError as ex:
6165
sentry_sdk.capture_exception(ex)
6266

@@ -96,7 +100,7 @@ def test_breadcrumbs(sentry_init, capture_envelopes):
96100
"span3_tag": "tag on the redis span",
97101
}
98102
assert breadcrumbs[3]["timestamp"] == mock.ANY
99-
103+
100104
# Check automatic http.client breadcrumbs
101105
assert "message" not in breadcrumbs[4]
102106
assert breadcrumbs[4]["type"] == "http"

0 commit comments

Comments
 (0)