|
|
@@ -263,12 +263,21 @@ class HostMonitor:
|
|
|
self.previous_timestamp = current_timestamp
|
|
|
|
|
|
# Processes - top CPU and memory consumers
|
|
|
+ # Convert iterator to list to ensure it's fully consumed and closed
|
|
|
processes = []
|
|
|
- for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
|
|
|
- try:
|
|
|
- processes.append(proc.info)
|
|
|
- except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
|
- pass
|
|
|
+ total_threads = 0
|
|
|
+ try:
|
|
|
+ proc_list = list(psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent', 'num_threads']))
|
|
|
+ for proc in proc_list:
|
|
|
+ try:
|
|
|
+ info = proc.info
|
|
|
+ processes.append(info)
|
|
|
+ # Count threads while we're iterating
|
|
|
+ total_threads += info.get('num_threads', 0)
|
|
|
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
|
+ pass
|
|
|
+ except Exception as e:
|
|
|
+ print(f"[HostMonitor] Error collecting process list: {e}")
|
|
|
|
|
|
top_cpu = sorted(processes, key=lambda p: p.get('cpu_percent', 0), reverse=True)[:5]
|
|
|
top_mem = sorted(processes, key=lambda p: p.get('memory_percent', 0), reverse=True)[:5]
|
|
|
@@ -327,8 +336,8 @@ class HostMonitor:
|
|
|
'net_drops_in': net_io.dropin,
|
|
|
'net_drops_out': net_io.dropout,
|
|
|
# Processes
|
|
|
- 'process_count': len(psutil.pids()),
|
|
|
- 'thread_count': sum(p.num_threads() for p in psutil.process_iter() if p.is_running()),
|
|
|
+ 'process_count': len(processes), # Use already collected process list
|
|
|
+ 'thread_count': total_threads, # Already counted during iteration
|
|
|
'top_cpu_processes': top_cpu_clean,
|
|
|
'top_mem_processes': top_mem_clean,
|
|
|
}
|