简体   繁体   English

哪种方法更适合在C#中读取Windows事件日志? WMI或EventLog

[英]Which approach is better to read Windows Event log in C#? WMI or EventLog

I need to write an application to grab event log for System/Applications. 我需要编写一个应用程序来获取系统/应用程序的事件日志。 The other requirement is that I need to read event log every minute or so to grab the new event logs since I read last time. 另一个要求是我需要每隔一分钟读取事件日志以获取自上次读取以来的新事件日志。 Currently I am considering to use C# to implement instead of C++. 目前我正在考虑使用C#来实现而不是C ++。

With that I read several webpages and if I understand correctly, I can use either WMI or EventLog class to read event log. 有了这些,我读了几个网页,如果我理解正确,我可以使用WMI或EventLog类来读取事件日志。 It seems to me that I can be notified when the new event log is added using EventLog class but I was not sure that is better than using WMI. 在我看来,当使用EventLog类添加新事件日志时,我会收到通知,但我不确定这比使用WMI更好。 If my understanding is correct, I would like to know which way I should take? 如果我的理解是正确的,我想知道我应该采取哪种方式?

Please give me some advice. 请给我一些建议。 Thanks. 谢谢。

I know this is long after the original post, but I hope this is usefule to future searchers like myself who found the EventLog class too slow. 我知道这是在原帖后很久,但我希望这对于像我这样发现EventLog类太慢的未来搜索者来说是有用的。 Here is some code to demonstrate searching for the most recent System startup events: 以下是一些代码,用于演示搜索最新的系统启动事件:

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"));

If you only want the most recent entry, this code took 0.28 seconds on my machine, compared with 7.11 seconds using EventLog class in place of the for() loop: 如果你只想要最新的条目,我的机器上的代码花了0.28秒,而使用EventLog类代替for()循环则为7.11秒:

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

Hope it helps. 希望能帮助到你。

WMI is crap. WMI是垃圾。 It uses loads of memory and the "events" are achieved by polling internally. 它使用大量内存,“事件”通过内部轮询实现。 You can even set the poll interval. 您甚至可以设置轮询间隔。 You are much better off to use the EventLog class of .NET. 你最好使用.NET的EventLog类。 But if you need to read all logs from Windows Vista+ you must use the EventLogReader where you can read events which define the events not via a message dll file located under 但是,如果您需要从Windows Vista +读取所有日志,则必须使用EventLogReader ,您可以在其中读取定义事件的事件,而不是通过位于下面的消息dll文件

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

but instead there is a ProviderGuid specified which is registered elsewhere. 但是指定了一个在其他地方注册的ProviderGuid。 This makes it impossible to read many OS messages which use the new system. 这使得无法读取使用新系统的许多OS消息。 But you can use the EventLogReader class only on machines with an OS Version >= Vista. 但是,只能在具有OS Version> = Vista的计算机上使用EventLogReader类。 You will need two event log reader implementations depending on the installed OS if you need to get all messages. 如果需要获取所有消息,则需要两个事件日志读取器实现,具体取决于安装的操作系统。 The EventLog class can also be made quite speedy when you read the messages in chunks of eg 100 messages from up to 4 threads which does improve reading speed up to a factor 2-3. 当您从多达4个线程的100条消息中读取消息时,EventLog类也可以非常快速地进行,这确实可以将读取速度提高到2-3倍。 I did get random errors for the Security Event Log on Windows Server 2003 when reading from it from multiple threads but for the others it worked very well from XP 32 Bit up to Windows 7 x64. 当从多个线程读取安全事件日志时,我确实得到了Windows Server 2003上的安全事件日志的随机错误 ,但对于其他线程,它从XP 32 Bit到Windows 7 x64都运行良好。

Check out the classes in the namespace System.Diagnostics.Eventing (and deeper) rather than using the EventLog class. 查看命名空间System.Diagnostics.Eventing(和更深层)中的类,而不是使用EventLog类。

When accessing a remote computer (maybe just Vista and later) using the EventLog class, the remote computer generates around 6 security audit entries as you connect to the logs, and another entry or 2 every time you retrieve a log record in a loop. 使用EventLog类访问远程计算机(可能只是Vista及更高版本)时,远程计算机在连接​​到日志时会生成大约6个安全审核条目,而每次在循环中检索日志记录时会生成另一个条目或2。

But with the EventLogQuery / EventLogReader / EventLogWatcher you can create an EventLogSession that keeps you connected. 但是使用EventLogQuery / EventLogReader / EventLogWatcher,您可以创建一个让您保持连接的EventLogSession。 And you can retrieve specific entries using an XPath query whereas EventLog forces you to iterate over all entries to find an entry. 并且您可以使用XPath查询检索特定条目,而EventLog会强制您迭代所有条目以查找条目。

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

WARNING: To get the event message, the method EventLogRecord.FormatDescription() is hit-or-miss, and the property LevelDisplayName is also hit-or-miss. 警告:要获取事件消息,方法EventLogRecord.FormatDescription()是命中或未命中,属性LevelDisplayName也是命中或未命中。 For this reason I am switching back to the EventLog class for retrieving the entries, and using the EventLogWatcher for watching entries. 出于这个原因,我将切换回EventLog类来检索条目,并使用EventLogWatcher来查看条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM