2016-01-29 132 views
2

我需要能夠檢索Hyper-V的事件日誌條目,作爲我們使用的監控系統的一部分。目前,我使用VBScript和WMI,並做一些事情,如:閱讀Hyper-V事件日誌

query = "Select * from Win32_NTLogEvent where LogFile = 'System' and TimeGenerated >= '" & last_check & "'" 
set wmi_objectset = wmi_service.ExecQuery(query, "WQL", &h30) 

並能正常工作,但它只能獲取一些在Hyper-V日誌不是全部。一些谷歌搜索表明,沒有辦法解決這個問題,MS也沒有建立將所有Hyper-V日誌讀入WMI的能力。所以我需要一種不同的方法。

更多谷歌搜索發現一些C#代碼讀取事件日誌,這將做得很好,因爲我很高興使用C#而不是VBScript。麻煩的是,雖然我可以閱讀標準日誌,如系統應用程序我無法解決如何閱讀我想要的Hyper-V日誌。代碼如下:

eventLog = new EventLog(); 
eventLog.Log = eventLogName; 

foreach (EventLogEntry log in eventLog.Entries) 
{ 

如果我設置的EventLogName「系統」,那麼它的工作原理並重新讀取所有的日誌條目(和它的令人印象深刻的快)。但我需要的是來自日誌Microsoft-Windows-Hyper-V-VMMS-Admin的條目。如果我設置的EventLogName爲 「Microsoft-Windows的Hyper-V的-VMMS-管理員」 我得到一個異常:

Unhandled Exception: System.InvalidOperationException: The event log 'Microsoft-Windows-Hyper-V-VMMS-Admin' on computer '.' does not exist. 

日誌確實存在,而且PowerShell命令:

Get-WinEvent -LogName Microsoft-Windows-Hyper-V-VMMS-Admin 

做檢索事件,所以問題可能只是爲EventLog對象指定日誌名稱的正確方法。

所以我的問題只是在我的C#程序中使用什麼來獲取Hyper-V VMMS管理日誌中的條目。

我測試的服務器是2012R2,但我不認爲問題與Windows的確切版本有關。還有其他一些獲取日誌數據的方法,比如Get-WinEvent或wevtutil,但我更願意讓C#程序工作,並使用替代方法是最後的手段。

回答

1

發生這種情況是因爲System.Diagnostics.EventLog只支持「舊式」事件日誌。 「新樣式」事件日誌是您在「應用程序和服務日誌」下的事件查看器中看到的(然後是其中的子文件夾,而不是其中的子文件夾),並且它不支持讀取這些日誌。要閱讀這些內容,您需要使用System.Diagnostics.Eventing.Reader中提供的類。請注意,這些接口具有不同的接口,更適合實時事件檢索。示例代碼:

using (var reader = new EventLogReader("Microsoft-Windows-Hyper-V-VMMS-Admin")) { 
    EventRecord eventRecord; 
    while ((eventRecord = reader.ReadEvent()) != null) { 
     Console.WriteLine("{0:s} {1}", eventRecord.TimeCreated, eventRecord.FormatDescription()); 
    } 
} 

如果你在最近發生的事件特別感興趣,這是更有效地對它們進行查詢以相反的順序,並將其篩選的方式。隨着一點點的枚舉幫手,我們可以在LINQ拋出:

IEnumerable<EventRecord> ReadEventsReverse(string logName) { 
    using (
     var reader = new EventLogReader(
      new EventLogQuery(logName, PathType.LogName) { ReverseDirection = true } 
     ) 
    ) { 
     EventRecord eventRecord; 
     while ((eventRecord = reader.ReadEvent()) != null) { 
      yield return eventRecord; 
     } 
    } 
} 

然後

var reverseEvents = ReadEventsReverse("Microsoft-Windows-Hyper-V-VMMS-Admin"); 
var reverseEventsToday = reverseEvents.TakeWhile(e => e.TimeCreated >= DateTime.Now.Date); 
foreach (var eventRecord in reverseEventsToday) { 
    Console.WriteLine("{0:s} {1}", eventRecord.TimeCreated, eventRecord.FormatDescription()); 
} 

如果你在閱讀新的活動特別感興趣,它更有效地使用the overload,使您可以提供一個bookmark,所以你不會不斷重讀和過濾舊事件。

+0

它的工作原理!謝謝Jeroen :-)我曾嘗試使用EventLogQuery/EventLogReader,但顯然有錯誤的標記。無論如何它現在工作。 –