views:

6791

answers:

5

I am working on a background program that will be running for a long time, and I have a external logging program (SmartInspect) that I want to feed with some values periodically, to monitor it in realtime when debugging.

I know I can simply fire up multiple programs, like the Task Manager, or IARSN TaskInfo, but I'd like to keep everything in my own program for this, as I also wants to add some simple rules like if the program uses more than X% CPU, flag this in the log.

I have a background thread that periodically feeds some statistics to SmartInspect, like memory consumption, working set, etc.

Is it possible for this thread to get a reasonably accurate measure of how much of the computer's CPU resources it consumes? The main program is a single-threaded application (apart from the watchdog thread that logs statistics) so if a technique is limited to how much does a single thread use then that would be good too.

I found some entries related to something called rusage for Linux and C. Is there something similar I can use for this?


Edit: Ok, I tried the performance counter way, but it added quite a lot of GC-data each time called, so the graph for memory usage and garbage collection skyrocketed. I guess I'll just leave this part out for now.

+6  A: 

Have a look at System.Diagnostics.PerformanceCounter. If you run up perfmon.exe, you'll see the range of performance counters available to you (set the 'performance object' to 'Process'), one of which is '% Processor Time'.

Sunlight
+2  A: 

You can through the System.Diagnostic.PerformanceCounter class. Here's an example of somebody monitoring CPU usage:

http://blogs.msdn.com/dotnetinterop/archive/2007/02/02/system-diagnostics-performancecounter-and-processor-time-on-multi-core-or-multi-cpu.aspx

Note that this does require elevated privileges. And there may be a performance hit using it.

Keltex
+17  A: 

You can also use System.Diagnostics.Process.TotalProcessorTime and System.Diagnostics.ProcessThread.TotalProcessorTime properties to calculate your processor usage as this article describes.

axk
This worked much better and did not add that much pressure on GC, just a slight increase. Thanks!
Lasse V. Karlsen
+1  A: 

It is good that you are logging to monitors like smartinspect. But windows itself gathers the data for each resource in this case your program (or process). WMI is the standard for Application monitoring. We can view the data captured by WMI. Many application management, health monitoring or applicaiton monitoring tools support WMI out of the box.

So I would not recommend you to log your CPU usage within the application to a log file.

If you think availablity and performance is critical then go for solutions like Microsoft Operations manager solution.

To get an idea about WMI and to get the list of process see below: - Win32_PerfFormattedData_PerfProc_Process to get Cpu time, filter is processID See this article - You can get the processID from Win32_process class.

WMI Made Easy For C# by Kevin Matthew Goss

oConn.Username = "JohnDoe";
oConn.Password = "JohnsPass";

System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\MachineX", oConn);    

//get Fixed disk stats
System.Management.ObjectQuery oQuery = new System.Management.ObjectQuery("select FreeSpace,Size,Name from Win32_LogicalDisk where DriveType=3");

//Execute the query 
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs,oQuery);

//Get the results
ManagementObjectCollection oReturnCollection = oSearcher.Get();   

//loop through found drives and write out info
foreach( ManagementObject oReturn in oReturnCollection )
{
    // Disk name
    Console.WriteLine("Name : " + oReturn["Name"].ToString());
    // Free Space in bytes
    Console.WriteLine("FreeSpace: " + oReturn["FreeSpace"].ToString());
    // Size in bytes
    Console.WriteLine("Size: " + oReturn["Size"].ToString());
}

You can monitor the process from Remote system as well.

sundar venugopal
This is strictly a debugging tool, and the code that logs this won't even be compiled into the release build. Only method-level logging will be compiled in for that, in case I need to try to reproduce a weird crash on a different machine. Thanks for the detailed info though, I have made a note of it
Lasse V. Karlsen
A: 

This code project article describes how to use the high performance timer:

http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx

You can use it to time the execution of your code.

Here you can find a number of open source C# profilers:

http://csharp-source.net/open-source/profile

Ashley Davis
I didn't need a timer, I needed a way to measure how much CPU the program was using over a period of time, this is not directly related to the time taken, there could be I/O operations that block for instance.
Lasse V. Karlsen