Skip to content

Commit 1522d8a

Browse files
authored
Add NoSuchProcess exception handling (#20059)
* Add NoSuchProcess exception handling * Add changelog * lint * Add log validation in tests
1 parent 5a3638c commit 1522d8a

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

gunicorn/changelog.d/20059.added

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add NoSuchProcess exception handling during initial proc search

gunicorn/datadog_checks/gunicorn/gunicorn.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ def _get_master_proc_by_name(self, name):
151151
try:
152152
if p.cmdline()[0] == master_name:
153153
master_procs.append(p)
154+
except psutil.NoSuchProcess:
155+
self.log.debug("Process %s disappeared while scanning", p.name())
154156
except (IndexError, psutil.Error) as e:
155157
self.log.debug("Cannot read information from process %s: %s", p.name(), e, exc_info=True)
156158
self.log.debug("There are %s master process(es) with the name %s", len(master_procs), name)

gunicorn/tests/test_unit.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# (C) Datadog, Inc. 2019-present
22
# All rights reserved
33
# Licensed under a 3-clause BSD style license (see LICENSE)
4+
import logging
5+
46
import mock
7+
import psutil
58
import pytest
69

710
from datadog_checks.gunicorn import GUnicornCheck
@@ -22,3 +25,29 @@ def test_collect_metadata_parsing_matching(aggregator, datadog_agent, stdout, st
2225
check.check(INSTANCE)
2326

2427
datadog_agent.assert_metadata_count(expect_metadata_count)
28+
29+
30+
def test_process_disappearing_during_scan(aggregator, caplog):
31+
"""Test handling of processes that disappear during scanning"""
32+
caplog.clear()
33+
# Create a mock process that will raise NoSuchProcess when cmdline() is called
34+
mock_process = mock.Mock()
35+
mock_process.cmdline.side_effect = psutil.NoSuchProcess(1234) # 1234 is the pid
36+
mock_process.name.return_value = "dd-test-gunicorn" # For the debug log message
37+
38+
check = GUnicornCheck(CHECK_NAME, {}, [INSTANCE])
39+
caplog.set_level(logging.DEBUG)
40+
41+
# Mock process_iter to return our disappearing process
42+
with mock.patch('psutil.process_iter', return_value=[mock_process]):
43+
check.check(INSTANCE)
44+
45+
# Verify the service check shows critical since no processes were found
46+
aggregator.assert_service_check(
47+
"gunicorn.is_running",
48+
check.CRITICAL,
49+
tags=['app:' + INSTANCE['proc_name']],
50+
message="No gunicorn process with name {} found, skipping worker metrics".format(INSTANCE['proc_name']),
51+
)
52+
53+
assert "Process dd-test-gunicorn disappeared while scanning" in caplog.text

0 commit comments

Comments
 (0)