C# 70-536 Chapter 10 Instrumentation

  • 4383
  • 0
  • C#
  • 2011-05-11

C# 70-536 Chapter 10 Instrumentation

Class 1 記錄事件紀錄

在事件檢視器中,可以紀錄一些軟體執行的過程,發生的錯誤等等訊息,讓使用者可以比較清楚的知道應用程式執行的狀況。但使用系統的事件檢視器要特別注意安全性的問題:因為要能夠寫入事件檢器必需要有一定的權限,而且也相當的秏費系統資源,所以一般的Log紀錄可以使用其它的方式處理,而不記錄到事件紀錄。

image

建立事件紀錄非常的簡單:建立eventlog的時候可以傳入logName,可以自訂,也可以傳入目前已有的紀錄簿名稱。

 

//建立
//Applicantion - 應用程式
//System - 系統

EventLog eventLog = new EventLog("StarLog");

eventLog.Source = "StarLog";
eventLog.WriteEntry("Create Event Log called", EventLogEntryType.Information);

//讀取
EventLog readLog = new EventLog();
readLog.Log = "StarLog";
foreach (EventLogEntry entry in readLog.Entries)
{
    Console.WriteLine(entry.Source + ":" + entry.Message);
}

//清除
readLog.Clear();

//關閉
readLog.Close();

//刪除
EventLog.Delete("StarLog");

image

image

EventLog的列舉型別:

 

 

image

 

Class 2 偵錯與追蹤

偵錯一般使用的類別有二種:Debugger & Debug;Debugger提供比較簡易的方法,像是Debugger.Break(類似斷點功能),而Debug則提供了較多方法來進行偵錯,例如:Debug.Assert(評估條件是否達成),Debug.Print(對追蹤監聽項寫入一個訊息-通常是輸出視窗)。使用時必須在Debug模式下建置,如果使用其它的(ex Release),.NET會自動忽略任何的Debug或是Debugger。

另外,還可以指定類別的成員在偵錯視窗顯示的方式:

image

如果要在Release版本上追蹤,則要使用Trace類別,也可以利用Trace類別來建立監聽器,例:TextWriterTraceListener、XmlWriterTraceListener,也可以導到事件紀錄簿(EventLogTraceListener),如果有想要指定的分隔屬性則可以利用DelimitedListTraceListener(Support in 2.0)。

// Create a file for output named TestFile.txt.
Stream myFile = File.Create("TraceLog.txt");

/* Create a new text writer using the output stream, and add it to
 * the trace listeners. */
TextWriterTraceListener myTextListener = new
   TextWriterTraceListener(myFile);
Trace.Listeners.Add(myTextListener);

// Write output to the file.
Trace.Write("Test output ");


// Flush the output.
Trace.Flush();

 

 

註:通常使用這些來做log會比較複雜,一般會使用人家寫好的套件,例如:Log4Net

Class 3 效能監測

要監測效能,就必需要先了解處理程序。取得或是啟動處理程序其實很簡單:(可以利用名稱或是process id取回)

//取得Process
Process p = Process.GetCurrentProcess();
Console.WriteLine("id:" + p.Id);
Console.WriteLine("name:" + p.ProcessName);

//啟動Process
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "notepad.exe";
Process.Start(info);

然後利用PerformanceCounter來進行監測:PerformanceCounter 類別

private static PerformanceCounter HeapCounter = null;
private static PerformanceCounter ExceptionCounter = null;
private static Timer DemoTimer;

static void Main(string[] args)
{
    DemoTimer = new Timer(3000);
    DemoTimer.Elapsed += new ElapsedEventHandler(OnTick);
    DemoTimer.Enabled = true;

    HeapCounter = new PerformanceCounter(".NET CLR Memory", "# Bytes in all Heaps");
    HeapCounter.InstanceName = "_Global_";

    ExceptionCounter = new PerformanceCounter(".NET CLR Exceptions", "# of Exceps Thrown");
    ExceptionCounter.InstanceName = "_Global_";

    Console.WriteLine("Press [Enter] to Quit Program");
    Console.ReadLine();
}

private static void OnTick(object source, ElapsedEventArgs e)
{
    Console.WriteLine("# of Bytes in all Heaps : " + HeapCounter.NextValue().ToString());
    Console.WriteLine("# of Framework Exceptions Thrown : " +
        ExceptionCounter.NextValue().ToString());
}

 

Class 4 偵測管理事件

在System.Management(必須引用System.Management.dll)中籍由Windows Management Instrumentation(WMI)提供了一些工具來監視及管理系統,使用的語法很類似SQL;也可以用來監測事件資訊。

 

//建立連線(若非本機通常需要帳號密碼)
ConnectionOptions options = new ConnectionOptions();

//存取來源\\{電腦名稱}\root\cimv2
ManagementScope scope = new ManagementScope(@"\\shelly-pc\root\cimv2", options);
scope.Connect();

//取得電腦資訊
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
    // Display the remote computer information
    Console.WriteLine("Computer Name : {0}", m["csname"]);
    Console.WriteLine("Windows Directory : {0}", m["WindowsDirectory"]);
    Console.WriteLine("Operating System: {0}", m["Caption"]);
    Console.WriteLine("Version: {0}", m["Version"]);
    Console.WriteLine("Manufacturer : {0}", m["Manufacturer"]);
}

//取得磁碟機資訊
ObjectQuery diskQuery = new ObjectQuery("Select Size, Name From Win32_LogicalDisk where DriveType=3");
ManagementObjectSearcher diskSearcher = new ManagementObjectSearcher(scope, diskQuery);
ManagementObjectCollection diskObjects = diskSearcher.Get();
foreach (ManagementObject disk in diskObjects)
{
    Console.WriteLine("Resource Name: " + disk["Name"]);
    Console.WriteLine("Resource Name: " + disk["Size"]);
}

//訂閱事件記錄
EventQuery eQuery = new EventQuery();
eQuery.QueryString = "SELECT * FROM" +
    " __InstanceCreationEvent WITHIN 1 " +
    "WHERE TargetInstance isa \"Win32_Process\"";

ManagementEventWatcher watcher = new ManagementEventWatcher(eQuery);
watcher.Options.Timeout = new TimeSpan(0, 0, 10);

Console.WriteLine("Open an application to trigger an event.");
ManagementBaseObject e = watcher.WaitForNextEvent();

Console.WriteLine(
    "Process {0} has been created, path is: {1}",
    ((ManagementBaseObject)e
    ["TargetInstance"])["Name"],
    ((ManagementBaseObject)e
    ["TargetInstance"])["ExecutablePath"]);

watcher.Stop();

image

相關連結:

EventQuery 類別

How To: Receive an Event

__InstanceCreationEvent Class