diff --git a/scripts/procdockerstatsd b/scripts/procdockerstatsd index 427a7214..6f5a29c0 100755 --- a/scripts/procdockerstatsd +++ b/scripts/procdockerstatsd @@ -24,6 +24,7 @@ REDIS_HOSTIP = "127.0.0.1" class ProcDockerStats(daemon_base.DaemonBase): + all_process_obj = {} def __init__(self, log_identifier): super(ProcDockerStats, self).__init__(log_identifier) @@ -137,10 +138,25 @@ class ProcDockerStats(daemon_base.DaemonBase): def update_processstats_command(self): processdata = [] - for process in psutil.process_iter(['pid', 'ppid', 'memory_percent', 'cpu_percent', 'create_time', 'cmdline']): + pid_set = set() + + processes_all = [] + for process_obj in psutil.process_iter(['pid', 'ppid', 'memory_percent', 'cpu_percent', 'create_time', 'cmdline']): + processes_all.append(process_obj) + sorted_processes = sorted(processes_all, key=lambda x: x.cpu_percent(), reverse=True) + top_processes = sorted_processes[:1024] + + for process_obj in top_processes: try: + pid = process_obj.pid + pid_set.add(pid) + # store process object and reuse for CPU utilization + if pid in self.all_process_obj: + process = self.all_process_obj[pid] + else: + self.all_process_obj[pid] = process_obj + process = process_obj uid = process.uids()[0] - pid = process.pid ppid = process.ppid() mem = process.memory_percent() cpu = process.cpu_percent() @@ -156,6 +172,14 @@ class ProcDockerStats(daemon_base.DaemonBase): except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): pass + # erase dead process + remove_keys = [] + for id in self.all_process_obj: + if id not in pid_set: + remove_keys.append(id) + for id in remove_keys: + del self.all_process_obj[id] + # wipe out all data before updating with new values self.state_db.delete_all_by_pattern('STATE_DB', 'PROCESS_STATS|*') diff --git a/tests/procdockerstatsd_test.py b/tests/procdockerstatsd_test.py index a15563bc..4e39561f 100644 --- a/tests/procdockerstatsd_test.py +++ b/tests/procdockerstatsd_test.py @@ -115,13 +115,21 @@ def test_update_processstats_command(self): valid_create_time2 = int((current_time - timedelta(days=2)).timestamp()) # Create a list of mocked processes mocked_processes = [ - MockProcess(uids=[1000], pid=1234, ppid=5678, memory_percent=10.5, cpu_percent=20.5, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0), - MockProcess(uids=[1000], pid=5678, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0) + MockProcess(uids=[1000], pid=1234, ppid=0, memory_percent=10.5, cpu_percent=99.0, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0), + MockProcess(uids=[1000], pid=5678, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0), + MockProcess(uids=[1000], pid=3333, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0) + ] + mocked_processes2 = [ + MockProcess(uids=[1000], pid=1234, ppid=0, memory_percent=10.5, cpu_percent=20.5, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0), + MockProcess(uids=[1000], pid=6666, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0) ] with patch("procdockerstatsd.psutil.process_iter", return_value=mocked_processes) as mock_process_iter: + pdstatsd.all_process_obj = {1234: mocked_processes2[0], + 6666: mocked_processes2[1]} pdstatsd.update_processstats_command() mock_process_iter.assert_called_once() + assert(len(pdstatsd.all_process_obj)== 3) @patch('procdockerstatsd.getstatusoutput_noshell_pipe', return_value=([0, 0], '')) def test_update_fipsstats_command(self, mock_cmd):