c# - Registro de eventos de alto rendimiento
winapi wmi (2)
Podría ver la utilidad de línea de comandos:
C:/> Wevtutil.exe qe Application /f:XML
Documentación: http://technet.microsoft.com/en-us/library/cc732848(WS.10).aspx
Guardará un marcador y continuará desde el marcador además de servir para procesar consultas mucho más complicadas.
Por ejemplo, supongamos que quieres todos los eventos de id 1530, en un grupo de 1000, desde el último marcador guardado, pre-renderizado en inglés:
Wevtutil qe Application /f:RenderedXml /bm:bookmark.pos /sbm:bookmark.pos /c:1000 /e:Log /l:en-us /q:Event[System/EventID=''1530'']
Esto produce eventos que se parecen a:
<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>
Utilizando un analizador xml rápido y liviano, debe ser capaz de hacer un chirrido a través de estos datos mientras está en paralelo produciendo la siguiente página de resultados. Ni siquiera es necesario escribir esto en el disco si captura la salida del proceso directamente. Solo asegúrese de que también está capturando el error estándar :: ya que esta utilidad también escribirá errores en esa salida.
Así que he estado probando varias formas de obtener datos del registro de eventos a granel (más de 1000 registros / segundo).
Necesito algo que pueda filtrar los registros antiguos, ahora almaceno el último ID de registro de eventos grabados y recupero todos los registros donde el ID del evento es mayor que eso ....
He intentado EventLogQuery / EventLogReader, esto funciona rápido, excepto cuando quiero extraer datos de mensajes, para obtener un mensaje formateado para los registros de seguridad, necesito llamar a EventLogRecord.FormattedMessage (), esto lleva mi velocidad de registro a aproximadamente 150 / segundo con registros fáciles de formatear, incluso peor con los complicados.
He intentado System.Diagnoistics.EventLog, esto no me permite crear filtros, por lo que cada vez que ejecuto esto, debe cargar TODOS los registros de eventos, luego puedo analizar los duplicados (desde el último escaneo). Tengo un servidor que tiene 200k registros de eventos en los últimos dos días, el uso de memoria se vuelve terrible debido a esto, por lo que es un no-go.
He intentado con WMI usando System.Management.ManagementObjectCollection, este tiene filtrado y puede extraer datos de mensajes del registro de eventos de seguridad RÁPIDO (acercándose a ~ 1000 / segundo), sin embargo, irá a unos 50 / 60k y comenzará a arrastrar sus pies, hasta aproximadamente 1-2 / segundo, eventualmente obtendré un error de Violación de cuota. :(
Entonces o bien:
¿Hay alguna manera de evitar el error de violación de la cuota, o quiero usar algún otro método para extraer registros de eventos a esta velocidad?
Editar:
Escribí una publicación en el blog que detallaba lo que aprendí sobre esto:
http://www.roushtech.net/2013/10/30/high-performance-event-log-reading/
Principalmente: WINAPI es su mejor opción, ya sea escribir C ++ / CLR o usar PInvoke.
Descubrí que el código administrado era demasiado lento y terminé usando las API win32 para recuperar los registros de eventos (locales y / o remotos). Son fáciles de implementar y hay muchos ejemplos de cómo hacerlo. También será mucho más rápido que cualquier cosa que intentes hacer con xml.
Nueva API: http://msdn.microsoft.com/en-us/library/aa385780(v=vs.85).aspx
API anterior: http://msdn.microsoft.com/en-us/library/aa363652(v=vs.85).aspx
También descubrí que la API previa a la vista funcionaba bien para lo que necesitaba y, en realidad, funcionaba mejor que la nueva API en máquinas posteriores a la vista.