@@ -82,6 +82,13 @@ def collect_processes(self) -> List[Dict[str, Any]]:
8282 proc_info ['cmdline' ] = ' ' .join (p .cmdline ()[:3 ])
8383 except (psutil .NoSuchProcess , psutil .AccessDenied ):
8484 pass
85+ else :
86+ try :
87+ uname = self ._resolve_username (proc .pid )
88+ if uname :
89+ proc_info ['username' ] = uname
90+ except Exception :
91+ pass
8592
8693 processes .append (proc_info )
8794 except Exception :
@@ -148,13 +155,27 @@ def _collect_processes_nvidia_smi(self, utilization_map: Dict[int, Dict[str, Any
148155 parts = [p .strip () for p in line .split (',' )]
149156 if len (parts ) >= 4 :
150157 pid = int (parts [1 ])
151- processes . append ( {
158+ proc_info = {
152159 'gpu_index' : 0 ,
153160 'pid' : pid ,
154161 'gpu_memory_mb' : float (parts [2 ]) if parts [2 ] != '[N/A]' else 0 ,
155162 'name' : parts [3 ],
156163 'gpu_utilization' : utilization_map .get (pid , {}).get ('gpu_util' , None ),
157- })
164+ }
165+ try :
166+ if PSUTIL_AVAILABLE :
167+ p = psutil .Process (pid )
168+ proc_info ['username' ] = p .username ()
169+ else :
170+ uname = self ._resolve_username (pid )
171+ if uname :
172+ proc_info ['username' ] = uname
173+ else :
174+ proc_info ['username' ] = 'Unknown'
175+ except Exception :
176+ proc_info ['username' ] = 'Unknown'
177+
178+ processes .append (proc_info )
158179 return processes
159180 except Exception :
160181 return []
@@ -249,3 +270,35 @@ def _collect_nvidia_smi(self) -> List[Dict[str, Any]]:
249270
250271 except Exception as e :
251272 return [{'error' : str (e )}]
273+
274+ def _resolve_username (self , pid : int ) -> str :
275+ """Attempt to resolve the username owning a PID using OS utilities.
276+
277+ Uses `ps` on POSIX and PowerShell/WMI on Windows as a fallback when
278+ psutil is not available or cannot access the process.
279+ Returns empty string if resolution fails.
280+ """
281+ try :
282+ import platform , subprocess
283+ system = platform .system ()
284+ if system == 'Windows' :
285+ # Use WMI via PowerShell to get the process owner
286+ cmd = [
287+ 'powershell' , '-NoProfile' , '-NonInteractive' ,
288+ '-Command' ,
289+ f"(Get-WmiObject -Class Win32_Process -Filter \" ProcessId={ pid } \" ).GetOwner().User"
290+ ]
291+ proc = subprocess .run (cmd , capture_output = True , text = True , timeout = 3 )
292+ out = (proc .stdout or '' ).strip ()
293+ if out :
294+ return out
295+ else :
296+ # POSIX: use ps to get the user for a PID
297+ cmd = ['ps' , '-o' , 'user=' , '-p' , str (pid )]
298+ proc = subprocess .run (cmd , capture_output = True , text = True , timeout = 2 )
299+ out = (proc .stdout or '' ).strip ()
300+ if out :
301+ return out
302+ except Exception :
303+ pass
304+ return ''
0 commit comments