我需要编写一个应用程序来获取系统/应用程序的事件日志 . 另一个要求是我需要每隔一分钟读取事件日志以获取自上次读取以来的新事件日志 . 目前我正在考虑使用C#来代替C来实现 .
有了这些,我读了几个网页,如果我理解正确,我可以使用WMI或EventLog类来读取事件日志 . 在我看来,当使用EventLog类添加新事件日志时,我会收到通知,但我不确定这比使用WMI更好 . 如果我的理解是正确的,我想知道我应该采取哪种方式?
请给我一些建议 . 谢谢 .
WMI是垃圾 . 它使用大量内存,并通过内部轮询实现"events" . 您甚至可以设置轮询间隔 . 你最好使用.NET的EventLog类 . 但是,如果您需要从Windows Vista中读取所有日志,则必须使用EventLogReader,您可以在其中读取定义事件的事件,而不是通过位于下面的消息dll文件
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\EventLogName\EventSourceName\EventMessageFile
但是指定了一个在其他地方注册的ProviderGuid . 这使得无法读取使用新系统的许多OS消息 . 但是,只能在具有OS Version> = Vista的计算机上使用EventLogReader类 . 如果需要获取所有消息,则需要两个事件日志读取器实现,具体取决于安装的操作系统 . 当您以例如块的形式读取消息时,也可以非常快速地使用EventLog类 . 来自最多4个线程的100条消息确实提高了读取速度,最高可达2-3倍 . 当从多个线程读取它时,我确实得到了Windows Server 2003上的安全事件日志random errors,但对于其他线程,它从XP 32 Bit到Windows 7 x64都运行良好 .
我知道这是在原帖后很久,但我希望这对于像我这样发现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秒,而使用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();
希望能帮助到你 .
查看命名空间System.Diagnostics.Eventing(和更深层)中的类,而不是使用EventLog类 .
使用EventLog类访问远程计算机(可能只是Vista及更高版本)时,远程计算机在连接到日志时会生成大约6个安全审核条目,而每次在循环中检索日志记录时会生成另一个条目或2 .
但是使用EventLogQuery / EventLogReader / EventLogWatcher,您可以创建一个让您保持连接的EventLogSession . 并且您可以使用XPath查询检索特定条目,而EventLog会强制您迭代所有条目以查找条目 .
http://msdn.microsoft.com/en-us/library/bb671200.aspx
警告:要获取事件消息,方法EventLogRecord.FormatDescription()是命中或未命中,属性LevelDisplayName也是命中或未命中 . 出于这个原因,我将切换回EventLog类来检索条目,并使用EventLogWatcher来查看条目 .
3 回答
WMI是垃圾 . 它使用大量内存,并通过内部轮询实现"events" . 您甚至可以设置轮询间隔 . 你最好使用.NET的EventLog类 . 但是,如果您需要从Windows Vista中读取所有日志,则必须使用EventLogReader,您可以在其中读取定义事件的事件,而不是通过位于下面的消息dll文件
但是指定了一个在其他地方注册的ProviderGuid . 这使得无法读取使用新系统的许多OS消息 . 但是,只能在具有OS Version> = Vista的计算机上使用EventLogReader类 . 如果需要获取所有消息,则需要两个事件日志读取器实现,具体取决于安装的操作系统 . 当您以例如块的形式读取消息时,也可以非常快速地使用EventLog类 . 来自最多4个线程的100条消息确实提高了读取速度,最高可达2-3倍 . 当从多个线程读取它时,我确实得到了Windows Server 2003上的安全事件日志random errors,但对于其他线程,它从XP 32 Bit到Windows 7 x64都运行良好 .
我知道这是在原帖后很久,但我希望这对于像我这样发现EventLog类太慢的未来搜索者来说是有用的 . 以下是一些代码,用于演示搜索最新的系统启动事件:
如果你只想要最新的条目,我的机器上的代码花了0.28秒,而使用EventLog类代替for()循环则为7.11秒:
希望能帮助到你 .
查看命名空间System.Diagnostics.Eventing(和更深层)中的类,而不是使用EventLog类 .
使用EventLog类访问远程计算机(可能只是Vista及更高版本)时,远程计算机在连接到日志时会生成大约6个安全审核条目,而每次在循环中检索日志记录时会生成另一个条目或2 .
但是使用EventLogQuery / EventLogReader / EventLogWatcher,您可以创建一个让您保持连接的EventLogSession . 并且您可以使用XPath查询检索特定条目,而EventLog会强制您迭代所有条目以查找条目 .
http://msdn.microsoft.com/en-us/library/bb671200.aspx
警告:要获取事件消息,方法EventLogRecord.FormatDescription()是命中或未命中,属性LevelDisplayName也是命中或未命中 . 出于这个原因,我将切换回EventLog类来检索条目,并使用EventLogWatcher来查看条目 .