Я пытаюсь написать небольшой монитор процессов IIS (загрузка процессора и памяти), который должен быть как можно более легким для системы. Все, что мне нужно, это имя пула приложений IIS, текущее использование памяти и текущее использование ЦП.
Мне удалось сделать это без больших проблем, используя эти две команды:
using (var srvman = new ServerManager())
{
workerProcesses = srvman.WorkerProcesses;
}
а также
processes = Process.GetProcesses().Where(processItem => processItem.ProcessName.Contains("w3wp") || processItem.ProcessName.Contains("php-cgi"))
Первый возвращает запущенные пулы приложений с идентификатором процесса, а второй возвращает информацию о процессе из системы (поэтому здесь я получаю процессор и использование памяти). Присоединение к этим двум сведениям дает мне почти то, что я хочу. Единственное исключение - это приложения PHP, которые работают в IIS.
Для PHP-приложений php-cgi.exe
процессы php-cgi.exe
, которые мне необходимо сопоставить с рабочим процессом пула приложений IIS. Вы не знаете, как подключить php-cgi.exe
к своим родителям w3wp.exe
?
Вот пример вывода, который я хотел бы создать:
1x w3wp.exe for site.com is using 15MB memory
4x php-cgi.exe is using 4x 15MB = 60MB memory
Я планирую суммировать эту информацию (которая в этом случае будет иметь 75 МБ использования памяти для сайта.com).
Вы можете получить PID родительского процесса, используя бит P/Invoke, как описано Саймоном Мурье. Это недорогая операция и привяжет список всех процессов php-cgi
к их создателям.
using (var srvman = new ServerManager())
{
var procs = from worker in srvman.WorkerProcesses
let workerProcess = Process.GetProcessById(worker.ProcessId)
join cgi in Process.GetProcessesByName("php-cgi")
on workerProcess.Id equals ParentProcessUtilities.GetParentProcess(cgi.Handle).Id
into childProcesses
select new
{
Worker = worker,
WorkerProcess = workerProcess,
Children = childProcesses,
TotalMemoryUse = workerProcess.PrivateMemorySize64
+ childProcesses.Sum(p => p.PrivateMemorySize64)
};
foreach (var proc in procs)
{
Console.WriteLine("Worker {0}:{1} using {2} total bytes", proc.Worker.AppPoolName,
proc.Worker.ProcessId, proc.TotalMemoryUse);
foreach (var child in proc.Children)
{
Console.WriteLine("\tphp-cgi process {0} using {1} bytes", child.Id, child.PrivateMemorySize64);
}
}
}
Вывод
C:\drop> phpProcessTest.exe Worker DefaultAppPool:4396 using 61530112 total bytes php-cgi process 3540 using 7024640 bytes php-cgi process 3144 using 6389760 bytes