viernes, 20 de noviembre de 2009

Tracing en ASP.Net

Por muchos es bien conocido las herramientas de diagnóstico y tracing de Microsoft ASP.Net. En este contexto teníamos objetos como el Debug y el Trace. Con el objeto Trace la gente tendía mucho a confundirse, ya que existían dos tipos diferentes, el objeto trace de System.Diagnostics que era el que trabajaba con los famosos Listeners (por ejemplo, un archivo de texto, el Event Viewer, o un tipo custom, para guardar por ejemplo en una base de datos) y que tenía métodos como el “TraceInformation”, “TraceError”, “Write”, etc; y estaba el objeto Trace del contexto de la página con métodos como el “Write” y el “Warn” (que escribía un texto en rojo).

Una buena forma de tracear información tocando lo menos posible la aplicación y haciendo una combinación de estos dos objetos trace es la siguiente; en el archivo de configuración de la aplicación habilitar el trace a nivel de página dentro de la sección “system.web”:


< trace enabled="true" writeToDiagnosticsTrace ="true" pageOutput="false" traceMode="SortByTime" requestLimit="20"/>


Con valor de “false” en el atributo “pageOutput“, se evita ver la información de traceo en cada página, para utilizar la página genérica, http://servidor/directorioRaizApp/Trace.axd. Aquí el atributo clave es “writeToDiagnosticsTrace”, el cual lo estamos asignando a “true” con el fin de que todo lo que procese por el Trace de la página, se redireccione a los listeners de System.Diagnostics, que dicho sea de paso, aunque se pueden agregar por código, también se pueden agregar por archivo de configuración, dentro de la sección “configuration”, como se muestra a continuación:


< system.diagnostics>
< trace autoflush="true" indentsize="2">
< listeners>
< remove name="Default"/>
< add name="EventLogListener" type="System.Diagnostics.EventLogTraceListener" initializeData="MiSource"/>
< add name="LogFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\TraceInfo.txt" />
< /listeners>
< /trace>
< /system.diagnostics>


Con esto estaríamos viendo la información, tanto en el Trace.axd, como en el archivo de texto y el Event Log respectivo. Y enviar información adicional sería tan fácil como utilizar la siguiente línea de código:


Trace.Warn(string.Format("Paso anterior al proceso a las {0}", DateTime.Now.Ticks));


Por supuesto esto se puede combinar también con un Switch para también contolar a través de archivo de configuración de la aplicación si se va a instrumentar o no, a través del siguiente código dentro de la sección “configuration” dentro del archivo de configuración de la aplicación, se muestra cómo hacer esto:


< system.diagnostics>
< switches>
< add name="SwitchApp" value="4"/>
< /switches>
< /system.diagnostics>


En este caso estamos asignando un nivel de “Verbose”. El código de la aplicación sería el siguiente:


TraceSwitch SwitchApp = new TraceSwitch("SwitchApp", "Switch de la aplicación");

if (SwitchApp.Level >= System.Diagnostics.TraceLevel.Verbose)
Trace.Warn(string.Format("Paso anterior al proceso a las {0}", DateTime.Now.Ticks));



Como en el caso anterior, estoy usando un nivel de “Verbose” para tomar la decisión de si instrumento o no. Obviamente este trabajo se puede hacer más simple y reutilizable a través del uso de clases utilitarias.