.net - Riesgo de que falten eventos en el registro de ETW con EventSource
logging etw-eventsource (3)
Intente ver el registro semántico (MS Enterprise Library 6) http://msdn.microsoft.com/en-us/library/dn440729(v=pandp.60).aspx
Puede usar el Origen de eventos y crear un oyente para grabar su registro en el visor de eventos o un archivo o db (o crear una solución personalizada)
Actualización: detecto el Id. De evento 806/807 incluso en un escenario IoC. En un interceptor, había una parte del código que crea una instancia de mi clase EventSource: si pierde la referencia de la primera instancia, todos los demás fallaron en el constructor y generaron los identificadores de evento 806/807 cuando se escriben eventos
Para el registro de big data es posible aplicar técnicas de división de mensajes.
Estoy instrumentando mis aplicaciones .NET 4.5 para emitir eventos ETW usando la clase EventSource
. El objetivo es poder capturar algunos de estos eventos (los eventos de nivel de error) para el registro de errores.
Después de leer y realizar pruebas, me preocupa la confiabilidad de este enfoque para el registro de errores, específicamente con respecto a la posibilidad de eventos perdidos o perdidos. Si mi registro de errores no funciona, necesito que la aplicación se cierre (en mi caso, no es seguro que se ejecute con errores no reportados). Al usar ETW y EventSource
, ¿cómo puedo estar seguro de que mis errores se están registrando correctamente?
Obviamente, parte de la respuesta dependerá de lo que esté escuchando los eventos. En mi caso, planeo usar el "Bloque de aplicaciones de registro semántico" de la última biblioteca de MS Enterprise.
Aquí hay una fuente donde Microsoft habla sobre las posibles causas de eventos perdidos: Acerca del seguimiento de eventos
Allí se listan estas posibles causas de eventos perdidos.
El tamaño total del evento es mayor que 64K. Esto incluye el encabezado ETW más los datos o la carga útil. Un usuario no tiene control sobre estos eventos que faltan, ya que el tamaño del evento está configurado por la aplicación.
El tamaño del búfer de ETW es más pequeño que el tamaño total del evento. Un usuario no tiene control sobre estos eventos faltantes ya que el tamaño del evento es configurado por la aplicación que registra los eventos.
Para el registro en tiempo real, el consumidor en tiempo real no está consumiendo eventos lo suficientemente rápido o no está presente del todo y luego el archivo de respaldo se está llenando. Esto puede ocurrir si el servicio de registro de eventos se detiene y se inicia cuando se están registrando eventos. Un usuario no tiene control sobre estos eventos que faltan.
Al iniciar sesión en un archivo, el disco es demasiado lento para mantenerse al día con la velocidad de registro.
Para ver si estas inquietudes se mitigaron de alguna manera utilizando la clase EventSource (por ejemplo, si trunca las cargas útiles grandes) hice algunas pruebas. Intenté registrar cadenas largas y me fallaron entre 30,000 y 35,000 caracteres (justo en línea con la carga útil máxima del evento de 64KB). Simplemente no hace nada por lo que puedo decir de las cadenas demasiado grandes, no hay eventos en absoluto en mi registro de Bloqueo de aplicaciones de registro semántico. Los eventos antes y después fueron escritos como de costumbre.
Entonces, ¿cada vez que tengo una cadena en mi carga útil tengo que pasarla a través de algún truncador? ¿Tendré que evitar manualmente la generación de eventos "demasiado rápido" también (y cómo sería eso posible)?
Se supone que los patrones y prácticas de Microsoft nos llevarán a buenos ... patrones y prácticas ... así que tal vez me esté perdiendo algo aquí.
Actualizar:
Bueno, aparentemente hay algún aviso en la aplicación de consumo para la condición "Eventos demasiado rápidos". Recibí esto hoy por primera vez:
Nivel: Advertencia, Mensaje: Algunos eventos se perderán debido a desbordamientos del búfer o retrasos en la sincronización del esquema en la sesión de rastreo: Microsoft-SemanticLogging-Etw-svcRuntime
Y luego al cerrar la sesión:
Nivel: Advertencia, Mensaje: Se detectó la pérdida de 1 eventos en la sesión de seguimiento ''Microsoft-SemanticLogging-Etw-svcRuntime''.
Actualización2:
La Guía de Desarrolladores de la Biblioteca Empresarial describe el comportamiento que acabo de mencionar.
Debe supervisar los mensajes de registro generados por el Bloque de aplicaciones de registro semántico para detectar cualquier indicio de que los búferes se hayan desbordado y que haya perdido mensajes. Por ejemplo, los mensajes de registro con los id. De evento 900 y 901 indican que los buffers internos de un sumidero se han desbordado; en el escenario fuera de proceso, los identificadores de evento 806 y 807 indican que los buffers de ETW se han desbordado. Puede modificar las opciones de configuración del búfer para los sumideros para reducir la posibilidad de que los búferes se desborden con sus cargas de trabajo típicas.
Mi pregunta sigue siendo: ¿puedo usar el registro semántico mientras aseguro que mi aplicación no se ejecuta si se eliminan los errores? Los eventos de rastreo normal se podrían eliminar ...
Mi idea actual es registrar los errores "críticos" con una clase separada que usa técnicas de registro anticuadas y mantener los errores menos críticos (así como los eventos de tipo depuración) que pasan por la tubería de ETW. Eso no sería tan malo en realidad ... podría publicarlo como una solución si no puedo encontrar una mejor sugerencia.
Actualización 3:
La advertencia de "eventos perdidos" que recibí no tuvo nada que ver con los desbordamientos de búfer, resulta que este es el mensaje que se recibe si se pasa una string
nula como valor de carga útil.
La clase EventSource
viene en dos versiones, una incluida con .NET Framework y otra en el paquete NuGet Microsoft EventSource Library . Supongo que utiliza el paquete NuGet porque contiene código más nuevo.
El constructor para la clase base EventSource
tiene una sobrecarga que toma un argumento booleano throwOnEventWriteErrors
con la siguiente documentación (paquete NuGet versión 1.0.26.0):
De manera predeterminada, los métodos de ''WriteEvent'' NO generan errores (descartan el evento en silencio). Esto se debe a que, en la mayoría de los casos, los usuarios asumen que el registro no es "valioso" y NO desea que las fallas en el registro se bloqueen en el programa. Sin embargo, para aquellas aplicaciones donde el registro es ''precioso'' y si falla, la persona que llama desea reaccionar, al configurar ''throwOnEventWriteErrors'' causará una excepción si WriteEvent falla. Tenga en cuenta que el hecho de que EventWrite sea exitoso no significa necesariamente que el evento haya alcanzado su destino, solo que la operación de escritura no falló.
Desafortunadamente, la última oración contiene un aviso de advertencia, pero si busca en el código fuente de EventSource
, puede ver que los códigos de retorno subyacentes de las llamadas del sistema operativo se usan para NoFreeBuffers
diferentes excepciones para NoFreeBuffers
y EventTooBig
(y otros errores).
Por lo tanto, si throwOnEventWriteErrors
obtendrá excepciones si la clase EventSource
no puede entregar el evento a ETW. Sin embargo, si ETW falla por otro motivo, no obtendrá ninguna excepción, pero si se asegura de que los canales de ETW estén configurados correctamente, esto rara vez sucederá. Sin embargo, como no puede tolerar la pérdida de eventos de error, probablemente debería probar los casos de error extremo para asegurarse de que el ETW se comporte como espera.
Una cosa es que hay dos puntos importantes que no se aclaran en la discusión anterior.
TODOS los problemas asociados con los eventos eliminados tienen que ver con ETW (Seguimiento de eventos para Windows), no con EventSource. Es lógico que EventSOurces hable con EventListeners, y hay un escucha integrado que reenvía a ETW. Obviamente, cuando se habla de eventos perdidos, la restricción de CUALQUIER enlace en la cadena afectará los datos que fluyen a través de la cadena. Por lo tanto, una forma de garantizar la confiabilidad completa es usar un EventListener que no usa ETW pero va directamente a donde quiera que desee que vayan los datos. Creo que el (Bloqueo de aplicación de registro semántico) tiene tal oyente.
ETW se ha utilizado con éxito para reenviar eventos de manera confiable, pero tiene que vivir dentro de las restricciones mencionadas anteriormente (el tamaño de los eventos debe mantenerse <64K y debe mantener la tasa de eventos bajo control. Tenga en cuenta que si la tasa es demasiado alto sabrá esto porque WriteEvent fallará, por lo que puede volver a intentarlo (después de una pausa), y así hacer algo que sea completamente confiable (a costa de ralentizar el programa). Tenga en cuenta que este tipo de pérdida de datos simplemente no es una Un tema interesante si realmente está hablando de errores (que no deberían estar ocurriendo a una velocidad enorme, y si están ocurriendo a una velocidad alta, es probable que sean redundantes (lo mismo ocurre con rapidez).
Así que, en conclusión, EventSource admite eventos confiables de manera predeterminada, ETW no lo admite de forma predeterminada, pero se puede hacer que lo respalde, pero a menudo, los valores predeterminados de ETW están más que bien.