Log4net: trazando nuestras aplicaciones

En ocasiones聽es importante almacenar un registro con informaci贸n sobre los procesos realizados, principalmente en el entorno de desarrollo. Otra de las necesidades comunes puede ser recibir un correo cuando una acci贸n finaliza correcta y/o incorrectamente o simplemente mantener un registro de un determinado nivel de informaci贸n. Log4net cubre todas estas necesidades por nosotros de una forma altamente configurable 馃榾

Esta librer铆a es fruto de su antecesora log4j (log for Java) la cual ha derivado para diferentes lenguajes como C++, PHP y por supuesto .NET.

Configuraci贸n

Toda la configuraci贸n de la librer铆a puede estar incluida en el archivo de configuraci贸n o program谩ticamente. Personalmente pienso que la configuraci贸n debe estar contenida en los archivos que tienen ese fin 馃檪

<configSections>
聽聽 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>

Una vez que tenemos definida la secci贸n en configSections, personalizamos un apartado con la configuraci贸n para nuestras trazas. En este post mostrar茅 una configuraci贸n para mostrar las mismas a trav茅s de la consola y por email.

<log4net>
聽聽聽 <logger name="Program">
聽聽聽聽聽 <level value="INFO" />
聽聽聽聽聽 <appender-ref ref="ConsoleAppender" />
聽聽聽 </logger>
聽聽聽 <logger name="ProductosRepository">
聽聽聽聽聽 <level value="WARN" />
聽聽聽聽聽 <appender-ref ref="SmtpAppender" />
聽聽聽 </logger>
聽聽聽 <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
聽聽聽聽聽 <layout type="log4net.Layout.PatternLayout">
聽聽聽聽聽聽聽 <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
聽聽聽聽聽 </layout>
聽聽聽 </appender>
聽聽聽 <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
聽聽聽聽聽 <to value="destinatario@returngis.net" />
聽聽聽聽聽 <from value="remitente@returngis.net" />
聽聽聽聽聽 <subject value="Asunto del correo" />
聽聽聽聽聽 <smtpHost value="smtp.returngis.net" />
聽聽聽聽聽 <bufferSize value="512" />
聽聽聽聽聽 <lossy value="true" />
聽聽聽聽聽 <evaluator type="log4net.Core.LevelEvaluator,log4net">
聽聽聽聽聽聽聽 <threshold value="ERROR" />
聽聽聽聽聽 </evaluator>
聽聽聽聽聽 <layout type="log4net.Layout.PatternLayout,log4net">
聽聽聽聽聽聽聽 <conversionPattern value="%property{log4net:HostName} :: %level :: %message %newlineLogger: %logger%newlineThread: %thread%newlineDate: %date%newlineNDC: %newline%newline" />
聽聽聽聽聽 </layout>
聽聽聽 </appender>
</log4net>

Si nos fijamos en la configuraci贸n expuesta, vemos que tenemos en realidad dos apartados repetidos: logger y appender.

Elemento logger

Este elemento define la configuraci贸n para ser utilizada en聽un apartado espec铆fico de nuestro c贸digo. Me explico: Supongamos que queremos mostrar informaci贸n por pantalla de los pasos que se van completando en una capa de nuestra aplicaci贸n, para saber qu茅 parte de nuestro c贸digo se est谩 ejecutando. Por otro lado, necesitamos recibir un email cada vez que en聽la l贸gica relacionada con la base de datos o los servicios聽se produzca聽un error. Gracias a este apartado, podemos definir diferentes configuraciones para poder usarlas conjuntamente en una misma aplicaci贸n. Como par谩metros tenemos el nivel de informaci贸n que queremos registrar y el tipo de salida (appender).

聽El nivel de error es acumulativo, es decir, si nuestro nivel de error es de tipo INFO abarcar谩 los niveles聽informaci贸n, warnings, errores y errores fatales. Si por el contrario el nivel establecido es ERROR, este s贸lo cubrir谩 los errores y los errores fatales. Por lo tanto, el modo que habilita todos los niveles ser铆a el modo DEBUG.

Elemento appender

Por otro lado, los appenders son los tipos de salida que podemos configurar. En este post voy a mostrar solamente la salida por consola y por SMTP para el env铆o de correos. Para m谩s ejemplos sobre otros tipos pod茅is echar un vistazo a este enlace.

Como valores significativos podemos mencionar:

Pattern.Layout para definir informaci贸n a mostrar a trav茅s de patrones. En el caso del ConsoleAppender que tenemos definido en el ejemplo聽la informaci贸n ser铆a mostrada de la siguiente forma:

Lossy se utiliza de forma conjunta con el elemento evaluator para evitar el consumo excesivo de recursos en producci贸n cuando la ejecuci贸n de nuestro programa es normal. Sin embargo, si la aplicaci贸n registra un error registrar谩 esta informaci贸n con un peque帽o batch de lo ocurrido momentos antes de la excepci贸n 馃檪

Los appenders que soportan esta opci贸n son los siguientes:

  • log4net.Appender.AdoNetAppender
  • log4net.Appender.RemotingAppender
  • log4net.Appender.SmtpAppender
  • log4net.Appender.SmtpPickupDirAppender
  • log4net.Appender.BufferingForwardingAppender

Recuperar la configuraci贸n

Como coment茅 en el apartado anterior, dependiendo del cu谩l queramos que sea el nivel y el tipo de salida, debemos solicitar una configuraci贸n u otra a la hora de la creaci贸n de nuestro objeto del tipo ILog. A trav茅s del mismo podremos registrar las trazas necesarias. En este caso, he utilizado el nombre de la clase en la que me encuentro para dar nombre a los distintos apartados, pero podr铆amos utilizar, por ejemplo, el nombre del proyecto o cualquier otro nombre significativo.

private static readonly ILog Logger = LogManager.GetLogger(typeof(Program).Name);

El siguiente paso ser铆a cargar la configuraci贸n desde el archivo de configuraci贸n, a trav茅s del siguiente m茅todo:

XmlConfigurator.Configure();

A partir de este momento estamos listos para comenzar a trazar nuestro c贸digo 馃榾 Para ello, basta con utilizar el objeto logger creado anteriormente de manera bastante similar a Trace.

Logger.Info("Retrieving files...");

Del mismo modo, podemos formatear strings:

Logger.ErrorFormat("{0}:{1}", ex.InnerException, ex.StackTrace);

Espero que sea de utilidad 馃檪

隆Saludos!