2016-01-29 98 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,但显然有错误的标记。无论如何它现在工作。 –