c# - 高性能事件日志

标签 c# winapi wmi event-log

所以我一直在尝试各种方法来批量获取事件日志数据(1000 多条记录/秒)。

我需要一些可以过滤掉旧日志的东西,现在我存储最后记录的事件记录 ID 并检索事件 ID 大于该记录的所有记录....

我已经尝试过 EventLogQuery/EventLogReader,这工作速度很快,除非我想提取消息数据,为了获得安全日志的格式化消息,我需要调用 EventLogRecord.FormattedMessage(),这使我的日志速度大约为150/秒,易于格式化的日志,复杂的日志更糟。

我试过 System.Diagnoistics.EventLog,这不允许我构建过滤器,所以每次我运行它时它都必须加载所有事件日志,然后我可以解析任何重复项(来自上次扫描)。我的服务器在过去两天有 20 万条事件日志,因此内存使用率变得很糟糕,所以这是不行的。

我尝试过使用 System.Management.ManagementObjectCollection 的 WMI,它具有过滤功能并且可以快速从安全事件日志中提取消息数据(接近 ~1000/秒),但是它会达到大约 50/60k 并开始拖动它的脚,下降到大约 1-2/秒,最终我会得到一个配额违规错误。 :(

所以要么:

有没有办法避免配额违规错误,或者我是否想使用其他方法以这种速度拉取事件日志?

编辑:

我写了一篇博文,详细说明了我对此的了解:

http://www.roushtech.net/2013/10/30/high-performance-event-log-reading/

大多数情况下:WINAPI 是您最好的选择,要么编写 C++/CLR,要么使用 PInvoke。

最佳答案

我可能会查看命令行实用程序:

C:/> Wevtutil.exe qe Application /f:XML

文档:http://technet.microsoft.com/en-us/library/cc732848(WS.10).aspx

它将保存一个书签并从书签继续,并用于处理更复杂的查询。

例如,假设您想要所有 ID 为 1530 的事件,以 1000 个为一组,从您保存的最后一个书签开始,以英语预呈现:

Wevtutil qe Application /f:RenderedXml /bm:bookmark.pos /sbm:bookmark.pos /c:1000 /e:Log /l:en-us /q:Event[System/EventID='1530']

这产生的事件看起来像:

<Log>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>
      <Provider Name="Microsoft-Windows-User Profiles Service" Guid="{89B1E9F0-5AFF-44A6-9B44-0A07A7CE5845}"/>
      <EventID>1530</EventID>
      <Version>0</Version>
      <Level>3</Level>
      <Task>0</Task>
      <Opcode>0</Opcode>
      <Keywords>0x8000000000000000</Keywords>
      <TimeCreated SystemTime="2011-06-16T22:55:32.305140500Z"/>
      <EventRecordID>26196</EventRecordID>
      <Correlation/>
      <Execution ThreadID="4168" ProcessID="1660"/>
      <Channel>Application</Channel>
      <Computer>hostname.WORKGROUP</Computer>
      <Security UserID="S-1-5-18"/>
    </System>
    <EventData Name="EVENT_HIVE_LEAK">
      <Data Name="Detail">0 user registry handles leaked from \Registry\User\S-1-5-82: </Data>
    </EventData>
    <RenderingInfo Culture="en-US">
      <Message>Windows detected your registry file is still in use by other applications or services. The file will be unloaded now. The applications or services that hold your registry file may not function properly afterwards. DETAIL - 0 user registry handles leaked from \Registry\User\S-1-5-82: </Message>
      <Level>Warning</Level>
      <Task/>
      <Opcode>Info</Opcode>
      <Channel>Application</Channel>
      <Provider>Microsoft-Windows-User Profile Service</Provider>
      <Keywords/>
    </RenderingInfo>
  </Event>

使用快速的轻量级 xml 解析器,您应该能够在并行生成下一个结果页面的同时分析这些数据。如果您直接捕获过程输出,则甚至不需要将其写入磁盘。请确保您还捕获了 std::error,因为此实用程序还会将错误写入该输出。

关于c# - 高性能事件日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6933610/

相关文章:

C++ COM 设计。组合与多重继承

c++ - 如何在 Windows 映射我的程序的 DLL 之前保留内存区域?

visual-c++ - 将 bstr 转换为日期时间格式

c# - 检测 SQL 集群

c# - 将项目添加到嵌套列表中的嵌套列表的 View

c# - 使用 OpenXML 使用目录文件填充 Excel 工作表列

c# - 正确使用 CancellationToken

c# - 使用Unity3D的IPointerDownHandler方法,但使用 “the whole screen”

delphi - 如何将 ISO 639-1 代码转换为语言 ID

将 "string array"AKA SAFEARRAY 的内容转换为 wchar