2013年1月16日 星期三

C# 監控外部程式

20120804013.jpg
在做監控windows service的同時

如何也監測其效能呢?

在service的控制中

可以透過下列的方法來取得ServiceController

ServiceController sc = new ServiceController(serviceName, Dns.GetHostName())
serviceName是指定要監控的service的name

這樣帶入後便可取得此service的控制權

可以透過判斷ServiceControllerStatus來監控service是死是活

if (sc.Status == ServiceControllerStatus.Stopped)
判斷service是不是掛了!

sc.Start();
這樣就能把service啟動

透過ServiceController就能夠做簡單的監控

那如果要監測service的效能??

這時候就要透過PerformanceCounter這個類別

那要使用這個類別必須先知道此service的process的name

這樣要如何從ServiceController轉成Process??

ManagementObject service = new ManagementObject(@"Win32_service.Name='" + sc.ServiceName + "'");
object o = service.GetPropertyValue("ProcessId");
int processId = (int)((UInt32)o);
透過這樣的方式

在ManagementObject中把servic的name帶入

便可取得process ID

Process serviceProcess = Process.GetProcessById(processId);
利用Process.GetProcessById便可以取得此process

這時候把process的name帶入PerformanceCounter

便可取得指定的效能數據

PerformanceCounter totalProcessorTimeCounter =
    new PerformanceCounter("Process", "% Processor Time", serviceProcess.ProcessName);

PerformanceCounter userProcessorTimeCounter =
    new PerformanceCounter("Process", "% User Time", serviceProcess.ProcessName);

PerformanceCounter privilegedProcessorTimeCounter =
    new PerformanceCounter("Process", "% Privileged Time", serviceProcess.ProcessName);

PerformanceCounter workingSetMemoryCounter =
    new PerformanceCounter("Process", "Working Set", serviceProcess.ProcessName);

PerformanceCounter workingSetPeakMemoryCounter =
    new PerformanceCounter("Process", "Working Set Peak", serviceProcess.ProcessName);

PerformanceCounter workingSetPrivateMemoryCounter =
    new PerformanceCounter("Process", "Working Set - Private", serviceProcess.ProcessName);

PerformanceCounter threadCountCounter =
    new PerformanceCounter("Process", "Thread Count", serviceProcess.ProcessName);

PerformanceCounter handleCountCounter =
    new PerformanceCounter("Process", "Handle Count", serviceProcess.ProcessName);
上面列的是幾種常見的counterName

與CPU使用率相關的:

% Processor Time

% User Time

% Privileged Time

與記憶體相關的:

Working Set

Working Set Peak

Working Set - Private

與執行序相關的:

Thread Count

在取得CPU相關的數據之前,要先做等待

totalProcessorTimeCounter.NextValue();
userProcessorTimeCounter.NextValue();
privilegedProcessorTimeCounter.NextValue();

System.Threading.Thread.Sleep(1000);// 1 second wait

由於要計算CPU的使用率

所以有一段要注意的就是:System.Threading.Thread.Sleep(1000);// 1 second wait

前面先把值取出來

等待一秒後

才又再去取一次值,這樣的值才會正確!!
(如果直接取NextValue(),CPU相關的都會為0)

Console.WriteLine("CPU使用率 " + totalProcessorTimeCounter.NextValue() / Environment.ProcessorCount + " %");
Console.WriteLine("User Time " + userProcessorTimeCounter.NextValue() / Environment.ProcessorCount + " %");
Console.WriteLine("Privileged Time " + privilegedProcessorTimeCounter.NextValue() / Environment.ProcessorCount + " %");
Console.WriteLine("工作集 " + (int)(workingSetMemoryCounter.NextValue() / (1024*1024)) + " MB");
Console.WriteLine("Working Set Peak " + (int)(workingSetPeakMemoryCounter.NextValue() / (1024 * 1024)) + "MB");
Console.WriteLine("專用 " + (int)(workingSetPrivateMemoryCounter.NextValue() / (1024 * 1024)) + " MB");
Console.WriteLine("執行續 " + threadCountCounter.NextValue());
Console.WriteLine("Handle Count " + handleCountCounter.NextValue());
那如果你測試的機器是多核心

取NextValue()會有問題

由於他是計算所有CPU的使用率

因此要把取出來的值除以CPU核心的數量

totalProcessorTimeCounter.NextValue() / Environment.ProcessorCount

這樣才能取出正確的百分比!!


透過ServiceController跟PerformanceCounter

這兩個類別便能實作簡單的效能監控軟體

指定你想要監控的service

透過定期去詢問的方式判斷service是否掛了

並可留下此service的效能紀錄!!


沒有留言:

張貼留言