Какой подход лучше читать журнал событий Windows в C #?WMI или EventLog - PullRequest
12 голосов
/ 23 марта 2011

Мне нужно написать приложение, чтобы получить журнал событий для Системы / Приложения. Другое требование - мне нужно каждую минуту или около того читать журнал событий, чтобы получить новые журналы событий с тех пор, как я читал в прошлый раз. В настоящее время я рассматриваю возможность использования C # для реализации вместо C ++.

После этого я читаю несколько веб-страниц и, если я правильно понимаю, я могу использовать класс WMI или EventLog для чтения журнала событий. Мне кажется, что я могу получить уведомление, когда новый журнал событий добавляется с помощью класса EventLog, но я не был уверен, что это лучше, чем с помощью WMI. Если мое понимание верно, я хотел бы знать, каким путем я должен идти?

Пожалуйста, дайте мне несколько советов. Спасибо.

Ответы [ 3 ]

8 голосов
/ 07 апреля 2012

Я знаю, что это намного позже оригинального поста, но я надеюсь, что это будет полезно для будущих искателей, таких как я, которые считают класс EventLog слишком медленным.Вот некоторый код для демонстрации поиска самых последних событий запуска системы:

EventLog ev = new EventLog()
{
    Log = "System"
};
SystemSession sess;

DateTime t1 = DateTime.Now;
DateTime t2 = DateTime.Now;
DateTime fromDate = DateTime.Now.AddDays(-30);
TimeSpan t;
int i, j=0;

t1 = DateTime.Now;
for (i = ev.Entries.Count - 1; i >= 0; i--)
{
    if (ev.Entries[i].TimeGenerated < fromDate) break;

    if (ev.Entries[i].InstanceId == 12)
    {
        //do something ...
        break;
    }
}
t2 = DateTime.Now;

t = new TimeSpan(t2.Ticks - t1.Ticks);
string duration = String.Format("After {0} iterations, elapsed time = {2}",
    ev.Entries.Count - i,
    t.ToString("c"));

Если вам нужна только самая последняя запись, этот код занял 0,28 секунды на моем компьютере по сравнению с 7,11 секундами с использованием класса EventLog вместо цикла for ():

var entry = (from EventLogEntry e in ev.Entries
         where (e.InstanceId == 12)
         && e.TimeGenerated >= fromDate
         orderby e.TimeGenerated
         select e).LastOrDefault();

Надеюсь, это поможет.

6 голосов
/ 24 марта 2011

WMI это дерьмо. Он использует много памяти, а «события» достигаются внутренним опросом. Вы даже можете установить интервал опроса. Вам гораздо лучше использовать класс EventLog .NET. Но если вам нужно прочитать все журналы из Windows Vista +, вы должны использовать EventLogReader , где вы можете читать события, которые определяют события, не через файл DLL сообщения, расположенный в

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\EventLogName\EventSourceName\EventMessageFile

но вместо этого указан ProviderGuid, который зарегистрирован в другом месте. Это делает невозможным чтение многих сообщений ОС, которые используют новую систему. Но вы можете использовать класс EventLogReader только на машинах с версией ОС> = Vista. Для получения всех сообщений вам потребуются две реализации программы чтения журнала событий в зависимости от установленной ОС. Класс EventLog также можно сделать довольно быстрым, когда вы читаете сообщения, например, кусками. 100 сообщений от 4 потоков, что повышает скорость чтения до 2-3 раз. Я получил случайных ошибок для журнала событий безопасности в Windows Server 2003 при чтении из него из нескольких потоков, но для других он работал очень хорошо от XP 32 Bit до Windows 7 x64.

1 голос
/ 13 декабря 2012

Проверьте классы в пространстве имен System.Diagnostics.Eventing (и более подробно) вместо использования класса EventLog.

При доступе к удаленному компьютеру (возможно, только в Vista и более поздних версиях) с использованием класса EventLog, удаленный компьютер генерирует около 6 записей аудита безопасности при подключении к журналам и еще одну запись или 2 каждый раз, когда вы извлекаете запись журнала в цикл.

Но с помощью EventLogQuery / EventLogReader / EventLogWatcher вы можете создать EventLogSession, который позволит вам оставаться на связи. И вы можете получить определенные записи, используя запрос XPath, тогда как EventLog заставляет вас перебирать все записи, чтобы найти запись.

http://msdn.microsoft.com/en-us/library/bb671200.aspx

ПРЕДУПРЕЖДЕНИЕ. Чтобы получить сообщение о событии, метод EventLogRecord.FormatDescription () имеет тип попадания или пропуска, а свойство LevelDisplayName - также попадания или пропуска. По этой причине я переключаюсь обратно в класс EventLog для получения записей и использую EventLogWatcher для просмотра записей.

...