【问题标题】:IIS process monitor to list IIS w3wp.exe processes with their PHP (php-cgi.exe) processesIIS 进程监视器列出 IIS w3wp.exe 进程及其 PHP (php-cgi.exe) 进程
【发布时间】:2015-03-09 21:10:00
【问题描述】:

我正在尝试编写小型 IIS 进程监视器(CPU 和内存使用情况),它应该对系统尽可能轻。我只需要 IIS 应用程序池名称、当前内存使用情况和当前 CPU 使用情况。

使用这两个命令我已经成功地做到了,没有更大的问题:

using (var srvman = new ServerManager())
{
    workerProcesses = srvman.WorkerProcesses;
}

processes = Process.GetProcesses().Where(processItem => processItem.ProcessName.Contains("w3wp") || processItem.ProcessName.Contains("php-cgi"))

第一个返回带有进程 ID 的正在运行的应用程序池,第二个返回来自系统的进程信息(所以这里是我获取 CPU 和内存使用情况的地方)。加入这两个信息几乎可以满足我的需求。一个例外是在 IIS 上运行的 PHP 应用程序。

对于 PHP 应用程序,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

我打算汇总这些信息(在这种情况下,site.com 的内存使用量为 75 MB)。

【问题讨论】:

标签: c# php iis windows-server


【解决方案1】:

您可以使用 P/Invoke as described by Simon Mourier 获取父进程 PID。这样做是一种低成本的操作,并且会将所有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 使用 61530112 总字节 php-cgi 进程 3540 使用 7024640 字节 php-cgi 进程 3144 使用 6389760 字节

【讨论】:

  • 哇。那很快。我今天会检查它。您还可以帮助我监控 w3wp 及其子 php-cgi 进程在 X(默认 60)秒间隔内的 CPU(当前)使用情况吗?我想知道在我们以 60 秒为间隔检查 CPU 使用率的情况下,60 秒是否是 100% CPU 使用率,而 TotalProcessorTime 在 0 和 60 秒之间的差异是否是这段时间内的实际应用程序 CPU 使用率。
  • 它可以工作,但看起来有点太耗费资源了。如果可能的话,我会尽量让它更轻。请记住,我正在尝试在运行大约 600 个 w3wp 进程并查询所有进程正在使用 CPU 资源的系统上运行它。
  • 我认为使用一个进程列表变量 (public static Process[] processes = null;) 刷新每次检查并从代码的所有部分访问它已经解决了高使用率问题。我正在从您提供的 LINQ 以及 ParentProcessUtilities 类访问此变量。
  • @GrZeCh,回复:CPU,这会给你一个 CPU 使用率,但它与你在任务管理器中看到的不匹配,因为采样周期要长得多。没有错,只是不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2012-08-13
  • 2019-09-14
  • 1970-01-01
  • 2019-09-14
  • 2011-12-04
相关资源
最近更新 更多