.net - primera - ¿Cuál es la mejor manera de escribir entradas de registro de eventos?
cómo elaborar una entrada o artículo para un blog o una web (6)
Creo que las excepciones de registro son uno de los pocos casos en los que es mejor que te tragues la excepción. En la mayoría de los casos, no desea que su aplicación falle en esto.
Pero ¿por qué estás escribiendo tu código de registro tú mismo? ¡Usa un framework como NLog o Log4Net! Estos también tragan excepciones como acabo de decir, pero puede redirigir la salida de registro a una ubicación diferente (archivo, cuadro de mensaje, etc.) con solo un cambio de configuración. Esto hace que resolver problemas como este sea mucho más fácil.
Recientemente tuve un problema durante el despliegue de un servicio de Windows. Cuatro computadoras no causaron ningún problema, pero en la quinta falla cualquier intento de iniciar el servicio debido a una excepción. El seguimiento de la pila de excepción se escribe en el registro de eventos, por lo que creo que debería ser fácil identificar la causa:
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("Starting service", EventLogEntryType.Information);
try
{
//...
base.OnStart(args);
}
catch (Exception ex)
{
EventLog.WriteEntry("Service can not start. Stack trace:" + ex.StackTrace, EventLogEntryType.Error);
Stop();
return;
}
EventLog.WriteEntry("Service started", EventLogEntryType.Information);
}
Pero, por desgracia, nunca se escribió información en el registro. Finalmente lo remonté a la primera entrada de registro que se escribe. Lanzó una excepción porque el registro de eventos de la aplicación estaba lleno de entradas recientes y configurado para sobrescribir solo entradas de más de 7 días.
¿Cuáles son las mejores prácticas para escribir en el registro de eventos, teniendo en cuenta que no puedo cambiar la configuración del registro de eventos de la aplicación?
¿Debo siempre poner EventLog.WriteEntry
en un bloque try, en caso afirmativo, cómo debo manejar la excepción (escribirlo en el registro de eventos es probablemente una mala idea), debería verificar el estado del registro de eventos en mi método OnStart
, o hacer ¿Tienes alguna sugerencia mejor?
Busca utilizar el Bloque de aplicaciones de registro .
El Bloque de aplicación de registro de la biblioteca de empresa simplifica la implementación de funciones de registro comunes. Los desarrolladores pueden usar el Bloque de registro para escribir información en una variedad de ubicaciones:
- El registro de eventos
- Un mensaje de correo electrónico
- Una base de datos
- Una cola de mensajes
- Un archivo de texto
- Un evento de WMI
- Ubicaciones personalizadas utilizando puntos de extensión de bloque de aplicación
Use log4net
La ventaja de usar log4net es que puede verificar el registro y controlarlo con mucha más flexibilidad de la que tendrá en cuenta dentro de su código.
Si estaba ingresando al registro de eventos, y viendo problemas y sin entradas de registro de eventos, siempre podría haber cambiado a un registro de archivo-apéndice y haberlo visto funcionando ... lo que le habría dicho que era algo relacionado con el registro de eventos.
log4net también es defensivo, no bloqueará su programa si no puede escribir la entrada de registro. Así que no habría visto esto suceder (por lo que no tendría sus archivos de registro, pero su programa se estaría ejecutando y de nuevo podría haber especificado un segundo método de registro para obtener los archivos de registro).
El bit clave en la documentación de log4net es este:
[log4net] es un sistema de registro de mejor esfuerzo y detención de fallas.
Por "fail-stop", nos referimos a que log4net no arrojará excepciones inesperadas en el tiempo de ejecución, lo que podría causar el bloqueo de la aplicación . Si por alguna razón, log4net arroja una excepción no detectada (a excepción de ArgumentException y ArgumentNullException que pueden arrojarse), envíe un correo electrónico a la lista de correo [email protected]. Las excepciones no detectadas se manejan como errores graves que requieren atención inmediata.
Además, log4net no volverá a System.Console.Out o System.Console.Error cuando su flujo de salida designado no se abra, no se pueda escribir o se llene. Esto evita corromper un programa que de otro modo funcionaría al inundar el terminal del usuario porque el registro falla. Sin embargo, log4net mostrará un mensaje único a System.Console.Error y System.Diagnostics.Trace que indica que no se puede realizar el registro.
(mi énfasis)
Para la mayoría de las cosas, hay una biblioteca que lo hace mejor que tú. Lo mejor es nunca reinventar, log4net resuelve el inicio de sesión en .Net y hará que su vida sea más fácil.
System.Diagnostics.EventLog log =
new System.Diagnostics.EventLog("YourLogNameHere");
log.ModifyOverflowPolicy(
System.Diagnostics.OverflowAction.OverwriteAsNeeded, 0);
Esto debería solucionar su problema de desbordamiento. El registro de eventos es generalmente extremadamente confiable, una vez que está configurado correctamente. Al usar el registro de eventos, solía agregar un registrador de copia de seguridad de emergencia rápido que simplemente escribía en un archivo de texto (esto toma alrededor de 5 minutos para escribir). Nunca fue llamado.
¿No puede simplemente usar el mecanismo predeterminado de registro de eventos que la clase ServiceBase ya proporciona? Si su servicio no se inicia, se escribirá automáticamente una entrada en el registro de eventos que así lo indique (con stacktrace).
Aparte de eso, y con respecto a los comentarios sobre log4net (o cualquier otro sistema de registro de mejor esfuerzo), creo que realmente depende de lo que estés tratando de lograr.
En su ejemplo, usar log4net (o el soporte integrado para el registro de eventos de ServiceBase) probablemente sea correcto.
Sin embargo, hay situaciones en las que incluso el hecho de que haya ocurrido un error y que ese hecho no se haya podido registrar en alguna parte es un problema. Por ejemplo, suponga un sistema de autenticación o autorización. Si no puede registrar con éxito y de manera confiable que, por ejemplo, la autenticación con contraseña no se pudo realizar debido a credenciales incorrectas, es posible que no se le permita continuar (lo mismo, por cierto, si la autenticación con contraseña hubiera sido exitosa).
Por lo tanto, a veces es necesario saber cuándo falló un intento de registro y manejarlo por sí mismo. Hay límites para esto, por supuesto (problema del huevo de gallina), y lo que haces es muy específico para la aplicación o escenario particular.
Demos un paso atrás aquí:
El registro de eventos del sistema está allí para alertar al administrador del sistema de que hay un problema con algo en el sistema. Debe permitir que el servicio comience a fallar. Esto aparecerá en el registro de errores del sistema con una fuente informada de "Administrador de control de servicios". Esto significa que el administrador del sistema sabrá sobre la falla.
A continuación, si necesita solucionar problemas, debe registrar excepciones en un archivo en el disco en el nivel superior de su programa. También debe volver a lanzarlos para que el inicio del servicio falle.
A continuación, puede identificar cualquier problema en los registros de eventos del sistema y hacer una referencia cruzada de la hora de la falla en los registros de la aplicación.