2011-05-05 16 views
9

Estoy tratando de configurar un agregador smtp en el archivo log4net.config que tengo. El problema es que he buscado en Internet y no puedo encontrar cómo enviar un correo electrónico cuando ocurre un error con toda la información de registro incluida, como información, depuración, error, fatal. Solo cuando la aplicación finaliza (NO cada vez que ocurre un ERROR).Log4Net smtp appender solo envía un correo electrónico cuando se produce un error con el registro completo (depuración, información y error). Solo cuando la aplicación finaliza

Así que sólo quieren recibir este correo electrónico cuando: Los extremos de aplicaciones + Con toda la información de registro (depuración, información, ERROR FATAL) + Sólo si ha ocurrido un error.

Esto se debe más a la forma en que manejo mis excepciones en c sharp, con manejo de múltiples niveles por todas partes y si ocurre un error no importa cuántas veces solo quiero recibir un correo electrónico. Además, no quiero utilizar varios registros, sino más bien solo uno en la raíz.

Gracias.

Respuesta

6

SmtpAppender no puede lograr esto solo. Entonces, lo que hice fue crear otro appender que a un appender del tipo MemoryAppender. Establecí un umbral en este registrador para incluir solo los mensajes que deberían desencadenar el SmtpAppender, p. Error. Usamos esto para luego determinar si queremos enviar el correo electrónico que tiene más niveles registrados.

En realidad, no nos importan los mensajes en el MemoryAppender; nos importa que contenga mensajes al final. Los mensajes que recibimos por correo electrónico en realidad provienen del SmtpAppender.

Al final de mi programa, verifico el appender de memoria para ver si GetEvents() contiene algún evento. Si es así, I no para que el SmtpAppender funcione normalmente.

configuraciones Log4net para ambos appenders:

<appender name="ErrorHolder" type="log4net.Appender.MemoryAppender" > 
    <onlyFixPartialEventData value="true" /> 
    <!-- if *any* message is logged with this level, the email appender will 
     be used with its own level --> 
    <threshold value="ERROR" /> 
</appender> 

<appender name="Email" type="log4net.Appender.SmtpAppender">  
    <!-- the level you want to see in the email IF ErrorHolder finds anything --> 
    <threshold value="INFO"/> 
    <bufferSize value="512" /> 
    <lossy value="false" /> <!-- important! --> 
    <to value="[email protected]" /> 
    <from value="[email protected]" /> 
    <subject value="ERROR: subject" /> 
    <smtpHost value="smtpserver" />  
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> 
    </layout>  
</appender> 

<root> 
    <level value="ALL" /> 
    <appender-ref ref="ErrorHolder" /> 
    <appender-ref ref="Email" /> 
</root> 

Al final de la aplicación ejecutar esta opción para desactivar el SmtpAppender si el ErrorHolder appender está vacía:

// trigger loggers if errors occurred: 
var memoryAppender = ((Hierarchy)LogManager.GetRepository()) 
    .Root.Appenders.OfType<MemoryAppender>().FirstOrDefault(); 

if (memoryAppender != null && memoryAppender.GetEvents().Length == 0) 
{ 
    // there was no error so don't email anything 
    var smtpAppender = ((Hierarchy)LogManager.GetRepository()) 
     .Root.Appenders.OfType<SmtpAppender>().FirstOrDefault(); 

    if (smtpAppender != null) 
    { 
     smtpAppender.Threshold = Level.Off; 
     smtpAppender.ActivateOptions(); 
    } 
} 
+0

Esta parece ser una versión bastante compleja de lo que sugerí en mi solución. – IAmTimCorey

+3

Eso es correcto, tenías razón. Tuve tu idea de verificar al final, eso es verdad. Pero cuando se busca cómo mirar dentro de los appenders para ciertas ocurrencias de nivel (estar aquí). No pude encontrar nada con respecto a los appenders si pudiera obtener los eventos dentro de ellos. Entonces, el único que pude encontrar es un MemoryAppender y lo usé. –

+2

Aquí hay una publicación sobre el seguimiento de los problemas de log4net: http://stackoverflow.com/questions/756125/how-to-track-down-log4net-problems – Nickz

2

Esto suena como un problema de configuración de la aplicación en lugar de un problema de configuración de log4net. Sugeriría poner un método al final de su aplicación que le envíe un correo electrónico al archivo de registro si detecta que hay un error dentro de él. Puede detectar este error volteando una variable global de falso a verdadero en cada lugar donde registra errores o puede esperar hasta el final de su aplicación y luego leer el archivo de registro para ver si contiene errores. El primer método sería más rápido al apagar pero significa modificar tu código en múltiples lugares. Este último le permitiría simplemente agregar un método, pero podría tomar más tiempo en un archivo grande.

Una tercera opción sería enviar errores a un segundo archivo de registro (por lo que van dos lugares) utilizando log4net. Luego, cuando su aplicación se está cerrando y está revisando si debe enviar un correo electrónico al registro, simplemente verifique la existencia del archivo de solo error. Si existe, elimínelo (para que no esté allí la próxima vez) y envíe por correo electrónico el registro completo.

+3

¿Cómo se comprueba al final del programa si se han producido errores, qué es lo que se busca? en logger, appender ?, qué métodos usaron y campos. ¿Puedes pegar algún código por favor? –

+0

Descubrí que puede encontrarse con problemas de archivos con E/S cuando intenta enviar el archivo de registro real (otro proceso lo tiene abierto). Incluso si vacía el archivoAppender, libere el bloqueo y cópielo, aun así, me encontré con problemas de IO si log4Net estaba ejecutando los archivos de registro en ese momento. –

0

cambio de umbral de error. Además, el registro 4net solo envía el correo electrónico cuando la aplicación está cerrada. Puede enviarlo antes. pero antes debe copiarlo (porque el archivo org todavía está en uso) y puede enviar la copia por correo electrónico.

Cuestiones relacionadas