用PerformanceCounter做进程的CPU内存IO监控示例

 

1.PerformanceCounter有很多Category,监控进程时Category为Process。它下面有一些windows已实现的PerformanceCounter

public static void GetCounterNameValueList(string CategoryName, string instanceName)
        {
            string[] instanceNames;
            ArrayList counters = new ArrayList();
            PerformanceCounterCategory mycat = new PerformanceCounterCategory(CategoryName);
            try
            {
                counters.AddRange(mycat.GetCounters(instanceName));
                foreach (PerformanceCounter counter in counters)
                {
                    Console.WriteLine(string.Format("{0,-30}:{1,20}", counter.CounterName, counter.RawValue));
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to list the counters for this category");
            }
        }

 

输出:

% Processor Time              :        404226406250
% User Time                   :        388479531250
% Privileged Time             :         15746875000
Virtual Bytes Peak            :          1362882560
Virtual Bytes                 :          1222418432
Page Faults/sec               :           423652248
Working Set Peak              :           741462016
Working Set                   :           613257216
Page File Bytes Peak          :           713129984
Page File Bytes               :           546553856
Private Bytes                 :           546553856
Thread Count                  :                  41
Priority Base                 :                   8
Elapsed Time                  :  130114216825494053
ID Process                    :                4376
Creating Process ID           :                3980
Pool Paged Bytes              :             1098488
Pool Nonpaged Bytes           :              154480
Handle Count                  :                1051
IO Read Operations/sec        :              197726
IO Write Operations/sec       :              777888
IO Data Operations/sec        :              975614
IO Other Operations/sec       :             4481054
IO Read Bytes/sec             :          9662784036
IO Write Bytes/sec            :         14714361072
IO Data Bytes/sec             :         24377145108
IO Other Bytes/sec            :            59853109
Working Set - Private         :           458493952

 

2.内存值可以调用NextValue直接得到,但Cpu、IO是计数器,需要至少两个时间点的值来计算这段时间的平均值。

private static void PrintProcessInfo(string name)
        {
            PerformanceCounter PTCounter = new PerformanceCounter("Process", "% Processor Time", name);
            PerformanceCounter DiskReadCounter = new PerformanceCounter("Process", "IO Read Bytes/sec", name);
            PerformanceCounter DiskWriteCounter = new PerformanceCounter("Process", "IO Write Bytes/sec", name);
            CounterSample cpuSample1 = PTCounter.NextSample();
            CounterSample diskReadSample1 = DiskReadCounter.NextSample();
            CounterSample diskWriteSample1 = DiskWriteCounter.NextSample();
            Thread.Sleep(1000);
            CounterSample cpuSample2 = PTCounter.NextSample();
            CounterSample diskReadSample2 = DiskReadCounter.NextSample();
            CounterSample diskWriteSample2 = DiskWriteCounter.NextSample();
            Console.WriteLine(CounterSampleCalculator.ComputeCounterValue(cpuSample1, cpuSample2));
            Console.WriteLine(CounterSampleCalculator.ComputeCounterValue(diskReadSample1, diskReadSample2));
            Console.WriteLine(CounterSampleCalculator.ComputeCounterValue(diskWriteSample1, diskWriteSample2)/1024/1024 + " MByte/s");

            //内存
            //PerformanceCounter WSCounter = new PerformanceCounter("Process", "Working Set", name);
            PerformanceCounter WSCounter = new PerformanceCounter("Process", "Working Set - Private", name);
            Console.WriteLine("Working Set:" + ((double) WSCounter.NextValue()/1024/1024).ToString());
            //内存最高值
            PerformanceCounter MemeryCounter = new PerformanceCounter("Process", "Working Set Peak", name);
            Console.WriteLine("Working Set Peak:" + ((double) MemeryCounter.NextValue()/1024/1024).ToString());
        }

 

 

3.PerformanceCounter 的构造方法,不能使用进程pid,只能用程序名,多个同名时,第一个是原名,第二个加#1,例如:firefox,firefox#1,firefox#2.....

4.一个完整的示例

using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;

namespace Logic
{
    public class ProcessMonitor
    {
        private class ProcessCounterSamples
        {
            public CounterSample CpuSample;
            public CounterSample DiskReadSample;
            public CounterSample DiskWriteSample;
            public CounterSample DiskReadWriteSample;
        }

        private class ProcessInfo
        {
            public float CpuPercentage { get; set; }
            public float DiskRead { get; set; }
            public float DiskWrite { get; set; }
            public float DiskReadWrite { get; set; }
            public float Memory { get; set; }
            public float MemoryMax { get; set; }
        }

        private const int RowsOfBuffer = 10;
        private const float Mega = (float)1024 * 1024;

        private string filePath;

        private Timer timer;
        
        private List monitorResults;
        private object fileLock=new object();
        private int timerCount;
        private ProcessCounterSamples lastSample;
        private PerformanceCounter cpuCounter;
        private PerformanceCounter diskReadCounter;
        private PerformanceCounter diskWriteCounter;
        private PerformanceCounter diskReadWriteCounter;
        private PerformanceCounter memoryCounter;
        private PerformanceCounter memoryMaxCounter;

        //processName:no path, no extension
        //statFilePath:absolute path, extension
        public ProcessMonitor(string processName, string statFilePath, int statInterval)
        {
            filePath = statFilePath;

            InitPerformanceCounter(processName);
            monitorResults=new List();

            timer = new Timer(statInterval);
            timer.Elapsed += DoStatistics;
        }
        public void StartMonitor()
        {
            timer.Start();
        }
        public void StopMonitor()
        {
            timer.Stop();
            AppendSave(filePath);
        }
        private void DoStatistics(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            int threadsLeft, dummy;
            ThreadPool.GetAvailableThreads(out threadsLeft, out dummy);
            if (threadsLeft < 2) return; 

            ProcessInfo info = GetProcessInfo();
            monitorResults.Add(info);

            if (timerCount % RowsOfBuffer == 0) AppendSave(filePath);
        }
        private void AppendSave(string fileName)
        {
            lock (fileLock)
            {
                using (StreamWriter sw = new StreamWriter(fileName, true))
                {
                    var list = monitorResults;
                    monitorResults = new List();
                    foreach (ProcessInfo info in list)
                    {
                        sw.WriteLine("{0},{1},{2},{3},{4},{5}", info.CpuPercentage, info.Memory, info.MemoryMax, info.DiskRead, info.DiskWrite, info.DiskReadWrite);
                    }
                    sw.Close();
                }
            }
        }
        private ProcessInfo GetProcessInfo()
        {
            ProcessInfo result = new ProcessInfo();

            ProcessCounterSamples currentSample = new ProcessCounterSamples();
            currentSample.CpuSample = cpuCounter.NextSample();
            currentSample.DiskReadSample = diskReadCounter.NextSample();
            currentSample.DiskWriteSample = diskWriteCounter.NextSample();
            currentSample.DiskReadWriteSample = diskReadWriteCounter.NextSample();

            if (lastSample == null)
            {
                result.CpuPercentage = 0f;
                result.DiskRead = 0f;
                result.DiskWrite = 0f;
                result.DiskReadWrite = 0f;
            }
            else
            {
                result.CpuPercentage = CounterSampleCalculator.ComputeCounterValue(lastSample.CpuSample, currentSample.CpuSample);
                result.DiskRead = CounterSampleCalculator.ComputeCounterValue(lastSample.DiskReadSample, currentSample.DiskReadSample) / Mega;
                result.DiskWrite = CounterSampleCalculator.ComputeCounterValue(lastSample.DiskWriteSample, currentSample.DiskWriteSample) / Mega;
                result.DiskReadWrite = CounterSampleCalculator.ComputeCounterValue(lastSample.DiskReadWriteSample, currentSample.DiskReadWriteSample) / Mega;
            }
            lastSample = currentSample;

            result.Memory = memoryCounter.NextValue() / Mega;
            result.MemoryMax = memoryMaxCounter.NextValue() / Mega;

            return result;
        }

        private void InitPerformanceCounter(string processName)
        {
            cpuCounter = new PerformanceCounter("Process", "% Processor Time", processName);
            diskReadCounter = new PerformanceCounter("Process", "IO Read Bytes/sec", processName);
            diskWriteCounter = new PerformanceCounter("Process", "IO Write Bytes/sec", processName);
            diskReadWriteCounter = new PerformanceCounter("Process", "IO Data Bytes/sec", processName);
            memoryCounter = new PerformanceCounter("Process", "Working Set - Private", processName);//memory
            memoryMaxCounter = new PerformanceCounter("Process", "Working Set Peak", processName);//memory peak
        }

        
    }
}

 

调用:

ProcessMonitor monitor2 = new ProcessMonitor("firefox", "D:\\tempData\\tmp2.csv", 1000);
            monitor2.StartMonitor();
            Thread.Sleep(21000);
            monitor2.StopMonitor();

 

-----------

用timer写法不正确,可能会造成多线程时计数器同时访问的情况,从而计算出很大的结果。

 

performanceCounter的访问可能需要管理员权限

http://openpdc.codeplex.com/discussions/247310

http://social.msdn.microsoft.com/Forums/zh-CN/vstswebtest/thread/c54247d9-6035-4d77-9293-e9986517e310

 

 

转载于:https://www.cnblogs.com/devourer/archive/2013/05/09/3069165.html

你可能感兴趣的:(用PerformanceCounter做进程的CPU内存IO监控示例)