2016-01-29 4 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 не все. Некоторые из Google считают, что нет никакого способа обойти это, и MS не создали возможность читать все журналы Hyper-V в WMI. Поэтому мне нужен другой подход.

Подробнее Googling нашел код C# для чтения журналов событий, и это будет хорошо, поскольку я счастлив использовать C# вместо VBScript. Проблема в том, что, хотя я могу читать стандартные журналы, например Система и Приложение Я не могу разобраться, как читать журнал Hyper-V, который я хочу. Код выглядит следующим образом:

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

foreach (EventLogEntry log in eventLog.Entries) 
{ 

Если установить eventLogName в «System», то он работает и читает обратно все записи журнала (и это впечатляюще быстро). Но мне нужны записи из журнала Microsoft-Windows-Hyper-V-VMMS-Admin. Если установить eventLogName в "Microsoft-Windows-Hyper-V-VMMS-Admin" я получаю исключение:

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#, чтобы получить записи в журнале администратора VMMS Hyper-V.

Сервер, на котором я тестирую, - это 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, что позволяет поставлять a bookmark, поэтому вы не постоянно перечитываете и фильтруете старые события.

+0

Это работает!Спасибо Jeroen :-) Я пробовал использовать EventLogQuery/EventLogReader, но, очевидно, неправильно понял. Во всяком случае, теперь он работает. –

Смежные вопросы