Poul K. Sørensen
Poul K. Sørensen

Reputation: 17530

Measuring CPU time per asp.net web application / app pool

By using below code its easy to find the pid of w3wp processes and get the CPU time used by the process. My setup one aspnet application has its own app pool.

    using (ServerManager serverManager = new ServerManager())
    {
        foreach (var appPool in serverManager.ApplicationPools)
        {

            if (appPool.WorkerProcesses.Any())
            {

            }
        }
     }

If this process have spawned any other processes. (Webapplication running cmd processes), is there any easy way to get those processes such those cpu time also can be messured.

Been looking into using performance conunters to get process id and created process id but it all seems to become complicated and I am wondering if there is something out there.

I have also used

  AddPerformanceCounterIfNotExist(dmConfig, string.Format(@"\ASP.NET Applications(_LM_W3SVC_{0}_ROOT)\Requests/Sec", ids[site.Name]));
  AddPerformanceCounterIfNotExist(dmConfig, string.Format(@"\ASP.NET Applications(_LM_W3SVC_{0}_ROOT)\% Managed Processor Time (estimated)", ids[site.Name]));
  AddPerformanceCounterIfNotExist(dmConfig, string.Format(@"\ASP.NET Applications(_LM_W3SVC_{0}_ROOT)\Managed Memory Used (estimated)", ids[site.Name]));

to get some information about the asp.net application that w3wp is running, but only requests per sec is actually giving messurements. The two others just reports 0.

Upvotes: 0

Views: 1283

Answers (2)

a-h
a-h

Reputation: 4274

The MSDN article at http://msdn.microsoft.com/en-us/library/vstudio/s57a598e(v=vs.100).aspx, states that you need to enable it in the aspnet.config file in the .NET Framework folder.

<?xml version="1.0" encoding="UTF-8" ?> 
<configuration> 
  <runtime> 
    <appDomainResourceMonitoring enabled="true"/> 
  </runtime> 
</configuration>

See the section "Performance Monitoring for Individual Applications in a Single Worker Process".

Upvotes: 1

Sebastian
Sebastian

Reputation: 3864

I would suggest performance counters to measure CPU time but if you don't like them :) then try performance metrics available in Process class. The following properies are available:

  • PrivilegedProcessorTime
  • UserProcessorTime
  • TotalProcessorTime

Remember though that in order to calculate CPU usage in % you will need to get system times. A sample task manager which uses those properties might look as follows:

public static class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool GetSystemTimes(out long lpIdleTime, out long lpKernelTime, out long lpUserTime);

    internal class SystemTimes
    {
        internal long idle;
        internal long kernel;
        internal long user;

        public TimeSpan IdleTime {
            get { return new TimeSpan(idle); }
        }

        public TimeSpan KernelTime {
            get { return new TimeSpan(kernel); }
        }

        public TimeSpan UserTime {
            get { return new TimeSpan(user); }
        }

        public TimeSpan TotalTime {
            get { return new TimeSpan(user + kernel); }
        }
    }

    static SystemTimes GetSystemTimesManaged() {
        var st = new SystemTimes();

        if (!GetSystemTimes(out st.idle, out st.kernel, out st.user)) {
            throw new Win32Exception();
        }
        return st;
    }

    public static void Main() {
        long lastSystemTime = 0;
        var lastProcCpuTimes = new Dictionary<int, long>(100);
        while (true) {
            var procs = Process.GetProcesses();
            for (int j = 0; j < 10; j++) {
                var sdiff = GetSystemTimesManaged().TotalTime.Ticks - lastSystemTime;
                Console.Clear();
                Console.WriteLine("                      Name           PID      CPU");
                Console.WriteLine("                      ----           ---      ---");
                for (int i = 0; i < procs.Length; i++) {
                    try {
                        var proc = procs[i];
                        if (proc != null && !proc.HasExited) {
                            proc.Refresh();
                            if (!lastProcCpuTimes.ContainsKey(proc.Id)) {
                                lastProcCpuTimes.Add(proc.Id, proc.TotalProcessorTime.Ticks);
                                Console.WriteLine("{0,30}{1,10}     N/A", proc.ProcessName, proc.Id);
                            } else {
                                var diff = proc.TotalProcessorTime.Ticks - lastProcCpuTimes[proc.Id];
                                Console.WriteLine("{0,30}{1,10}{2,8:0.00}%", proc.ProcessName, proc.Id,
                                        (diff * 100.0 / sdiff));
                                lastProcCpuTimes[proc.Id] = proc.TotalProcessorTime.Ticks;
                            }
                        }
                    } catch (System.ComponentModel.Win32Exception) {
                        // probably access denied - just ignore it
                        procs[i] = null;
                    }
                }
                lastSystemTime = GetSystemTimesManaged().TotalTime.Ticks;
                Thread.Sleep(1000);
            }
        }
    }
}

Almost in the same way you may measure AppDomain CPU time with AppDomain.MonitoringTotalProcessorTime property but you need to set AppDomain.MonitoringIsEnabled to true.

Upvotes: 0

Related Questions