在远程计算机上读取事件日志的最快方法是什么?

我正在开发一个从远程机器读取事件日志(应用程序)的应用程序。 我正在使用.net中的EventLog类,然后迭代日志条目,但这非常慢。 在某些情况下,某些计算机具有40000多个日志条目,并且需要花费数小时来迭代条目。 完成这项任务的最佳方法是什么? .net中是否有其他类更快或其他任何技术?

伙计,我感觉到你的痛苦。 我们的应用程序中存在完全相同的问题。

您的解决方案有一个分支,具体取决于您运行的服务器版本以及运行“目标”计算机的服务器版本。

如果您同时使用Vista或Windows Server 2008,那么您很幸运。 您应该查看System.Diagnostics.Eventing.Reader.EventLogQuerySystem.Diagnostics.Eventing.Reader.EventLogReader 。 这些是.net 3.5中的新function。

基本上,您可以使用XML构建查询并将其发送到远程计算机上运行。 也许您只是在搜索特定类型的事件,或者只是搜索特定时间点的新事件。 搜索在远程计算机上运行,​​然后您只需返回匹配的事件。 新类比旧的.net 2.0方式快得多,但同样,它们仅在Vista或Windows Server 2008上受支持。

对于我们的应用程序,当目标不在Vista / Win2008上时,我们从远程系统下载了原始.evt文件,然后使用其二进制格式解析该文件。 关于.evt文件(Vista之前)的事件日志格式有几个数据来源,包括链接文本和我在codeproject.com上回忆起的有一些c#代码的文章。

Vista和Windows Server 2008计算机使用新的.evtx格式,这是一种新格式,因此您无法在所有版本中使用相同的二进制解析方法。 但是新的EventLogQuery和EventLogReader类是如此之快,以至于你不必这么做。 现在使用内置类非常快速。

事件日志阅读器非常慢……太慢了。 WTF微软?

使用LogParser 2.2 – 在Internet上搜索C#和LogParser(或者您可以使用命令行中的日志解析器命令)。 我不想复制其他人已经贡献的作品。

我将日志导出为EVTX文件,从远程系统中提取日志。 然后我从远程系统复制文件。 这个过程非常快 – 即使是跨越地球的网络(我将日志导出到网络资源也有问题)。 一旦将其置于本地,您就可以进行搜索和处理。

拥有EVTX有多种原因 – 我不会深入了解为什么要这样做。

以下是将日志副本另存为EVTX的代码的工作示例:(注意:“device”是网络主机名或IP。“LogName”是所需日志的名称:“System”,“安全“或”应用程序“.outputPathOnRemoteSystem是远程计算机上的路径,例如”c:\ temp \%hostname%。%LogName%。%YYYYMMDD_HH.MM%.evtx“。)

  static public bool DumpLog(string device, string LogName, string outputPathOnRemoteSystem, out string errMessage) { bool wasExported = false; string errorMessage = ""; try { System.Diagnostics.Eventing.Reader.EventLogSession els = new System.Diagnostics.Eventing.Reader.EventLogSession(device); els.ExportLogAndMessages(LogName, PathType.LogName, "*", outputPathOnRemoteSystem); wasExported = true; } catch (UnauthorizedAccessException e) { errorMessage = "Unauthorized - Access Denied: " + e.Message; } catch (EventLogNotFoundException e) { errorMessage = "Event Log Not Found: " + e.Message; } catch (EventLogException e) { errorMessage = "Export Failed: " + e.Message + ", Log: " + LogName + ", Device: " + device; } errMessage = errorMessage; return wasExported; } 

可以在MSDN上找到一个很好的解释/示例。

 EventLogSession session = new EventLogSession(Environment.MachineName); // [System/Level=2] filters out the errors // Where "Log" is the log you want to get data from. EventLogQuery query = new EventLogQuery("Log", PathType.LogName, "*[System/Level=2]"); EventLogReader reader = new EventLogReader(query); for (EventRecord eventInstance = reader.ReadEvent(); null != eventInstance; eventInstance = reader.ReadEvent()) { // Output or save your event data here. } 

使用旧代码等待5-20分钟时,这个代码在不到10秒的时间内完成。

也许WMI可以帮助你:

使用C#的WMI

您是否尝试过使用PowerShell 2.0中的远程处理function? 它们允许您在远程计算机上执行cmdlet(如读取事件日志的cmdlet)并将结果(当然是对象)返回给调用会话。

您可以将程序放在那些将日志保存到文件并将其发送到您的web应用程序的计算机上,我认为这样可以更快,因为您可以执行循环本地但我不知道如何操作,所以我不能使用任何代码: (

也许远程计算机可以进行一些计算。 所以这样你的服务器只会处理相关信息。 它将是一种使用远程计算机进行一些光过滤的集群,服务器将是分析部分。