Windows Azure Diagnostics (SDK 1.4)

En este post vamos a pararnos un poco más en profundidad en cada una de las fuentes de diagnóstico disponible a través de Microsoft.WindowsAzure.Diagnostics.dll.
Un punto importante a la hora de utilizar el sistema de diagnósticos de Windows Azure es que este trabaja conjuntamente con Windows Azure Storage, donde vamos a almacenar toda la información que cada una de las fuentes disponibles nos facilite.
Antes de centrarnos en la configuración, veamos qué podemos recuperar de nuestras instancias y dónde se almacena:
 
Fuente Descripción Destino
Windows Azure Logs En estos logs se guardan todas aquellas trazas registradas a través de la clase System.Diagnostics.Trace. Tabla
Performance Counters Se almacenan los contadores de rendimiento configurados previamente. Tabla
Windows Azure Diagnostic Infrastructure Logs Son todos aquellos registros relacionados con el servicio de Windows Azure. Tabla
Windows Event Logs Podemos añadir tanto fuentes predeterminadas de Windows, como System o Application, como aquellas dadas de alta programáticamente. Tabla
Crash Dumps Volcados de memoria de nuestra aplicación. Blob
Custom Error Logs Esta opción nos permite dar de alta nuestros propios logs dentro del proceso de transferencia de Windows Azure Diagnostics para poder recuperar los mismos a través del storage. Blob
IIS 7.0 Logs Podemos recuperar toda la información generada de forma automática relacionada con IIS Blob
Failed Request Logs Almacena información sobre aquellas peticiones fallidas de IIS Blob
Si bien cada una de las fuentes tiene su propia configuración, lo primero que debemos recuperar es la configuración inicial por defecto de los diagnósticos de la siguiente manera:
//We need to get default initial configuration
var config = DiagnosticMonitor.GetDefaultInitialConfiguration();
Generalmente esta configuración se recupera y se modifica en el archivo WebRole.cs o WorkerRole.cs en el método OnStart ya que es el punto de entrada de nuestra aplicación y se ejecuta cuando nuestras instancias se están iniciando.
En los siguientes apartados utilizaremos el objeto config para configurar cada una de las fuentes.

Windows Azure Logs

Esta primera fuente lo que nos va a permitir es almacenar en una tabla, generada de forma automática por el sistema de diagnósticos llamada WADLogsTable, todas aquellas líneas de registro que realicemos en nuestro código a través de System.Diagnostics.Trace, como por ejemplo:
Trace.WriteLine("WorkerRole_Diag entry point called", "Information");
Para poder recuperar estas trazas, debemos añadir el siguiente código:
//Windows Azure Logs. Table: WADLogsTable
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Performance counters

Una de las fuentes más importantes para poder conocer el rendimiento de nuestros sistemas trata de los contadores de rendimiento. Para poder conocer cuál sería el nombre del contador que queremos añadir, podemos localizarlos en nuestro propio sistema:
 
 
Una vez elegidos los que queramos auditar, los agregamos al sistema de diagnóstico de la siguiente manera:
//Performance counters. Table: WADPerformanceCountersTable
 config.PerformanceCounters.DataSources.Add(
    new PerformanceCounterConfiguration
    {
        CounterSpecifier = @"Processor(*)*",
        SampleRate = TimeSpan.FromSeconds(1)
    }
 );

 config.PerformanceCounters.DataSources.Add(
    new PerformanceCounterConfiguration
    {
        CounterSpecifier = @"Memory*",
        SampleRate = TimeSpan.FromSeconds(1)
    }
 );

config.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Windows Azure Diagnostic Infrastructure Log

Cuando trabajamos en local con development fabric podemos visualizar una consola por cada instancia que tengamos de nuestros roles donde nos facilita información de su estado.
 
 
Para poder recuperar esta información utilizaremos DiagnosticInfrastructureLogs para recuperar esta información en forma de tabla, la cual recibirá el nombre WADDiagnosticInfrastructureLogsTable:
//Windows Azure Diagnostic Infrastructure Logs. Table: WADDiagnosticInfrastructureLogsTable
config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Windows Event Logs

El visor de eventos de Windows creo que es algo que no necesita presentación :D . También podemos recuperar esta información a excepción de la fuente Security. Estos datos se nos presentarán a través de la tabla WADWindowsEventLogsTable.
//Windows Event Logs. Table: WADWindowsEventLogsTable
config.WindowsEventLog.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.DataSources.Add("System!*");
config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Crash Dumps

Uno de los clásicos no podía faltar :) Todo lo relacionado con los volcados de memoria se puede conseguir utilizando estas líneas:
//Crash Dumps. Blob. Container: wad-crash-dumps
CrashDumps.EnableCollection(true);
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
En este caso debemos tener en cuenta dos pasos: CrashDumps.EnableCollection nos permite habilitar la recolección tanto de mini dumps (parámetro a false) o full dumps (parámetro a true). Si sólo indicamos esta línea lo que vamos a conseguir es el almacenamiento local de estos volcados de memoria, pero no serán transferidos a nuestro storage. Para conseguir este segundo paso debemos especificar cada cuánto tiempo vamos a realizar la transferencia de los directorios de diagnóstico a través de config.Directories.ScheduledTransferPeriod como se indica en la segunda línea del código anterior.

Custom Error Logs

Imaginemos que ya tenemos un sistema de diagnóstico de terceros que no deseamos modificar, pero aun así queremos recuperar los ficheros generados de todas las instancias para poder procesarlos. En este caso podemos crear nuevos directorios de diagnóstico, lo cual nos va a permitir que los mismos sean transferidos cada cierto tiempo a los blobs de nuestra cuenta de storage:
//Custom Error Logs
var localResource = RoleEnvironment.GetLocalResource("CustomErrorStorage");
var directoryConfiguration = new DirectoryConfiguration
{
    Container = "wad-mycustom-log-container",
    DirectoryQuotaInMB = localResource.MaximumSizeInMegabytes,
    Path = localResource.RootPath
};

config.Directories.DataSources.Add(directoryConfiguration);
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

IIS Logs

En el caso de los logs de IIS basta con configurar el tiempo de transferencia del apartado Directories, ya que se genera una carpeta donde almacena de forma automática la información:
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Failed Request Logs

Esta fuente está relacionada también con Internet Information Services tras la cual podemos recuperar todas aquellas peticiones fallidas. A excepción del resto, para poder configurar la misma debemos modificar el archivo web.config de nuestro web role para añadir la sección tracing dentro de system.webServer:
<system.webServer>
   <!-- Blob. Container: wad-iis-failedreqlogfiles -->
     <tracing>
       <traceFailedRequests>
          <add path="*">
             <traceAreas>
                <add provider="ASP" verbosity="Verbose" />
                <add provider="ASPNET"
                     areas="Infrastructure,Module,Page,AppServices"
                     verbosity="Verbose" />
                <add provider="ISAPI Extension" verbosity="Verbose" />
                <add provider="WWW Server"
                areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module"
                verbosity="Verbose" />
            </traceAreas>
            <failureDefinitions timeTaken="00:00:15" statusCodes="400-599" />
          </add>
        </traceFailedRequests>
      </tracing>
 <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Al generar esta información dentro de un archivo, necesitamos indicar el tiempo de transferencia de los directorios de diagnóstico como en los casos anteriores:
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
Nota: Todas aquellas fuentes que se almacenan en blobs generan una carpeta dentro del directorio DiagnosticStore para almacenar los archivos con la información. Para poder ser transferidos necesitamos indicar cada cuánto tiempo queremos que se envíe la información a Windows Azure Storage. Este tiempo de transferencia basta con definirlo una vez para todas las fuentes que usen este sistema.
Para que todos estos cambios tengan efecto, debemos iniciar la nueva configuración tomando como parámetros el nombre de la cadena de conexión que utilizará Windows Azure Diagnostics (por defecto Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString) y el objeto config que hemos personalizado:
//Start with new configuration
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
Por último, como recomendación, existe una aplicación de Cerebrata llamada Azure Diagnostics Manager la cual nos va a facilitar mucho la interpretación de toda esta información de una forma muy visual y organizada.
Adjunto un proyecto de ejemplo donde podemos probar cada uno de los casos ;)
 
Espero que sea de utilidad :D
 
¡Saludos!

 

2 comentarios en “Windows Azure Diagnostics (SDK 1.4)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *