Skip to content

Commit ab3de3a

Browse files
authored
feat(subprocess): Instrument more methods (getsentry#497)
* feat(subprocess): Instrument more methods Avoiding parsing arguments for now because that really backfired in the past and it's probably not that useful. * fix: Fix copypaste error * fix: Linting
1 parent cce401d commit ab3de3a

File tree

2 files changed

+62
-7
lines changed

2 files changed

+62
-7
lines changed

sentry_sdk/integrations/stdlib.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,41 @@ def sentry_patched_popen_init(self, *a, **kw):
184184
with hub.start_span(op="subprocess", description=description) as span:
185185
span.set_data("subprocess.cwd", cwd)
186186

187-
return old_popen_init(self, *a, **kw)
187+
rv = old_popen_init(self, *a, **kw)
188+
189+
span.set_tag("subprocess.pid", self.pid)
190+
return rv
188191

189192
subprocess.Popen.__init__ = sentry_patched_popen_init # type: ignore
190193

194+
old_popen_wait = subprocess.Popen.wait
195+
196+
def sentry_patched_popen_wait(self, *a, **kw):
197+
hub = Hub.current
198+
199+
if hub.get_integration(StdlibIntegration) is None:
200+
return old_popen_wait(self, *a, **kw)
201+
202+
with hub.start_span(op="subprocess.wait") as span:
203+
span.set_tag("subprocess.pid", self.pid)
204+
return old_popen_wait(self, *a, **kw)
205+
206+
subprocess.Popen.wait = sentry_patched_popen_wait # type: ignore
207+
208+
old_popen_communicate = subprocess.Popen.communicate
209+
210+
def sentry_patched_popen_communicate(self, *a, **kw):
211+
hub = Hub.current
212+
213+
if hub.get_integration(StdlibIntegration) is None:
214+
return old_popen_communicate(self, *a, **kw)
215+
216+
with hub.start_span(op="subprocess.communicate") as span:
217+
span.set_tag("subprocess.pid", self.pid)
218+
return old_popen_communicate(self, *a, **kw)
219+
220+
subprocess.Popen.communicate = sentry_patched_popen_communicate # type: ignore
221+
191222

192223
def get_subprocess_traceparent_headers():
193224
return EnvironHeaders(os.environ, prefix="SUBPROCESS_")

tests/integrations/stdlib/test_subprocess.py

+30-6
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,38 @@ def test_subprocess_basic(
137137

138138
assert transaction_event["type"] == "transaction"
139139

140-
subprocess_span, = transaction_event["spans"]
141-
142-
assert subprocess_span["data"] == data
140+
subprocess_init_span, subprocess_wait_span, subprocess_communicate_span = transaction_event[
141+
"spans"
142+
]
143+
144+
assert subprocess_init_span["op"] == "subprocess"
145+
assert subprocess_communicate_span["op"] == "subprocess.communicate"
146+
assert subprocess_wait_span["op"] == "subprocess.wait"
147+
148+
# span hierarchy
149+
assert (
150+
subprocess_wait_span["parent_span_id"] == subprocess_communicate_span["span_id"]
151+
)
152+
assert (
153+
subprocess_communicate_span["parent_span_id"]
154+
== subprocess_init_span["parent_span_id"]
155+
== transaction_event["contexts"]["trace"]["span_id"]
156+
)
157+
158+
# common data
159+
assert (
160+
subprocess_init_span["tags"]["subprocess.pid"]
161+
== subprocess_wait_span["tags"]["subprocess.pid"]
162+
== subprocess_communicate_span["tags"]["subprocess.pid"]
163+
)
164+
165+
# data of init span
166+
assert subprocess_init_span["data"] == data
143167
if iterator:
144-
assert "iterator" in subprocess_span["description"]
145-
assert subprocess_span["description"].startswith("<")
168+
assert "iterator" in subprocess_init_span["description"]
169+
assert subprocess_init_span["description"].startswith("<")
146170
else:
147-
assert sys.executable + " -c" in subprocess_span["description"]
171+
assert sys.executable + " -c" in subprocess_init_span["description"]
148172

149173

150174
def test_subprocess_invalid_args(sentry_init):

0 commit comments

Comments
 (0)