Artículo original publicado el miércoles, 24 de agosto de 2011

Sé que ha habido varias entradas y artículos sobre la utilización de diagnósticos en Windows Azure. De hecho, eso fue parte del problema cuando fui a investigar la información que había disponible recientemente. Encontré un montón de artículos diferentes pero dispersados por varias versiones de Azure, de modo que se necesita mucho tiempo para entender lo que funcionaría con el último SDK de Azure (1.4). Espero que esta entrada reúna los puntos principales para utilizar los diagnósticos de Azure con la versión 1.4 del SDK.

 

Para empezar, como muchos de ustedes sabrán, Azure incluye una escucha de seguimiento (Trace) que toma los comandos Trace.* (como Trace.Write, Trace.WriteLine, Trace.TraceInformation, etc.) y los almacena en la memoria. Sin embargo, necesita “hacer algo” para moverlo desde la memoria hasta el almacenaje persistente. Podría ser iniciar una transferencia manual de los datos o la configuración de una programación de las transferencias que se producirán. Además de eso, también puede elegir trasladar la información desde los registros de eventos, capturar los contadores de rendimiento y trasladar los registros IIS así como los registros personalizados.

 

Además de todas las herramientas típicas de registro y depuración como las mencionadas anteriormente, también puede configurar la implementación para poder realizar un protocolo de escritorio remoto (RDP) al servidor Azure en el que se hospeda su aplicación, así como habilitar IntelliTrace para realizar una depuración limitada en una aplicación que se haya implementado. Revisemos estas diferentes piezas.

 

Para configurar los diferentes componentes de diagnóstico, como la frecuencia en la que persisten los datos en el almacenamiento, cuánto almacenamiento debe asignarse, qué contadores de rendimiento se deben capturar, etc., puede hacerse más fácilmente escribiendo código en el archivo WebRole.cs que viene con la aplicación estándar Web Role Azure (y creo que la mayoría de las características de Azure, aparte del rol VM, tienen algo análogo a la clase WebRole, como el archivo WorkerRole.cs con un proyecto de rol de trabajo).  Antes de empezar a hablar sobre el código, es recomendable ir al proyecto de rol de Azure y marcar la casilla de la ficha Configuración que indica “Especifique las credenciales de la cuenta de almacenamiento para los resultados de diagnósticos:”. Utilice el botón selector que hay allí para seleccionar una cuenta de almacenamiento que tenga en Azure; no utilice desarrollo local. Así se guardará la nueva cadena de conexión en un proyecto denominado Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString.

 

Ahora, miremos todo el código de la clase de rol web y detallaré algunas partes específicas:

 

public override bool OnStart()

{

   // Para obtener información sobre cómo tratar los cambios de configuración

   // consulte el tema de MSDN en http://go.microsoft.com/fwlink/?LinkId=166357.

 

   try

   {

       //inicializar el marco de configuración

                Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>

       {

          configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

       });

 

       //obtener la cuenta de almacenamiento mediante la cadena de conexión predeterminada Diag

       CloudStorageAccount cs =

          CloudStorageAccount.FromConfigurationSetting(

          "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString");

 

       //obtener el administrador de diag

       RoleInstanceDiagnosticManager dm = cs.CreateRoleInstanceDiagnosticManager(

          RoleEnvironment.DeploymentId,

          RoleEnvironment.CurrentRoleInstance.Role.Name,

          RoleEnvironment.CurrentRoleInstance.Id);

 

       //obtener la configuración actual

       DiagnosticMonitorConfiguration dc = dm.GetCurrentConfiguration();

 

       //si eso no funcionó, obtenga los valores desde un archivo config

       if (dc == null)

          dc = DiagnosticMonitor.GetDefaultInitialConfiguration();

 

       //Registro de Windows Azure

       dc.Logs.BufferQuotaInMB = 10;

       dc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

       dc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

 

       //Registros de eventos de Windows

       dc.WindowsEventLog.BufferQuotaInMB = 10;

       dc.WindowsEventLog.DataSources.Add("System!*");

       dc.WindowsEventLog.DataSources.Add("Application!*");

       dc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(15);

 

       //Contadores de rendimiento

       dc.PerformanceCounters.BufferQuotaInMB = 10;

       PerformanceCounterConfiguration perfConfig =

          new PerformanceCounterConfiguration();

       perfConfig.CounterSpecifier = @"\Processor(_Total)\% Processor Time";

       perfConfig.SampleRate = System.TimeSpan.FromSeconds(60);

      dc.PerformanceCounters.DataSources.Add(perfConfig);

       dc.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(10);

 

       //Registros de solicitudes con error

       dc.Directories.BufferQuotaInMB = 10;

       dc.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(30);

 

       //Registros de infrastructura

       dc.DiagnosticInfrastructureLogs.BufferQuotaInMB = 10;

       dc.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter =

          LogLevel.Verbose;

       dc.DiagnosticInfrastructureLogs.ScheduledTransferPeriod =

          TimeSpan.FromMinutes(60);

 

       //Volcados de memoria

       CrashDumps.EnableCollection(true);

 

       //cuota general; debe ser mayor que la suma de todos los elementos

       dc.OverallQuotaInMB = 5000;

 

       //guardar la configuración

       dm.SetCurrentConfiguration(dc);

   }

   catch (Exception ex)

   {

       System.Diagnostics.Trace.Write(ex.Message);

   }

 

   return base.OnStart();

}

 

Ahora revisemos el código en más detalle. Empiezo obteniendo el valor de la cadena de conexión que se utiliza en los diagnósticos para poder conectar a la cuenta de almacenamiento que se está utilizando. Dicha cuenta de almacenamiento se utiliza para llegar a la clase de configuración de supervisión de diagnósticos. Hecho esto, puedo comenzar a configurar los distintos componentes de registro.

 

Las llamadas Trace.* se guardan en los registros de Windows Azure. Lo configuro para almacenar hasta 10MB de datos en la tabla que utiliza y que persista la escritura en la tabla cada 5 minutos para todas las escrituras que sean más detalladas. Por cierto, para ver una lista de diferentes tablas y colas que utiliza Windows Azure para almacenar estos datos de registro, consulte http://msdn.microsoft.com/en-us/library/hh180875.aspx  y http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.diagnostics.diagnosticmonitorconfiguration.aspx. Los registros de infraestructura y de diagnóstico son virtualmente idénticos.

 

Para las entradas de evento, he agregado cada registro que quiero capturar a la lista de DataSources para la clase WindowsEventLog. Los valores que he podido proporcionar son Application!*, System!* o UserData!*. Las demás propiedades son las mismas que se describen en los registros de Windows Azure.

 

Para los contadores de rendimiento, debo describir qué contadores deseo capturar y con qué frecuencia deben tomar muestras de datos. En el ejemplo de arriba, he agregado un contador para la CPU y lo he configurado para tomar muestras de datos cada 60 segundos.

 

Finalmente, las últimas cosas que he hecho han sido habilitar la captura de volcados de memoria, cambiar la cuota para todos los datos de registro a aproximadamente 5GB y guardar los cambios.  Es muy importante incrementar la cuota general, de lo contrario se producirá una excepción que dice que no hay suficiente almacenamiento disponible para realizar los cambios descritos arriba. Hasta ahora, parece que 5GB es un valor seguro, pero por supuesto la cantidad puede variar.

 

Ya está todo listo, de modo que es hora de publicar la aplicación. Cuando publique la aplicación en Visual Studio, hay un par de cosas más a tener en cuenta:

 

 

En el diálogo Configuración de la publicación, debe marcar la casilla Habilitar IntelliTrace; luego explicaré la razón. Además, recomiendo que haga clic en el vínculo para configurar conexiones con escritorios remoto. Me di cuenta de que, a veces, esa era la única manera de poder resolver un problema. Debido a que la documentación sobre escritorios remotos ya no es muy actual, permítame que le sugiera que utilice el diálogo en lugar de editar manualmente los archivos de configuración.  Aparecerá un diálogo como este:

 

 

Lo más importante a tener en cuenta es lo siguiente:

  1. Parece que puede utilizar cualquier certificado para el que tenga un archivo PFX.  Tenga en cuenta que ES NECESARIO cargar este certificado al servicio de host antes de publicar la aplicación.
  2. En el campo Nombre de usuario puede poner lo que desee; se creará una cuenta local con ese nombre de usuario y contraseña.

 

Complete ambos diálogos y publique la aplicación.  Inicie la aplicación una vez para arrancarla y asegúrese de que se ejecuta el código de rol web.  Hecho esto, deberá ser capaz de examinar la configuración de diagnósticos de la aplicación y ver que se han implementado sus personalizaciones, como se muestra aquí (NOTA: estoy utilizando las herramientas CodePlex para gestionar Azure que pueden descargarse en http://wapmmc.codeplex.com/):

 

 

Una vez se haya ejecutado algo de código y haya esperado hasta el siguiente período de transferencia programada de los registros de Windows Azure, podré ver que aparecen las llamadas Trace.* en la tabla WADLogsTable, como se muestra aquí:

 

 

Además, debido a que he configurado la compatibilidad con RDP en mi aplicación, cuando haga clic en el rol web, estará habilitada la opción para realizar una conexión RDP en la barra de herramientas del Portal para desarrolladores de Azure:

 

 

Ya tengo todos los registros y seguimientos de mi aplicación disponibles y puedo realizar protocolos a escritorios remotos si tengo que investigar más a fondo. Otra estupenda característica que he habilitado es IntelliSense. La descripción de IntelliSense va más allá del ámbito de esta entrada, pero puede encontrar muy buena información aquí: http://blogs.msdn.com/b/jnak/archive/2010/06/07/using-intellitrace-to-debug-windows-azure-cloud-services.aspx y aquí: http://blogs.msdn.com/b/ianhu/archive/2010/03/16/intellitrace-what-we-collect.aspx. Cuando IntelliTrace está habilitado, se indicará al visualizar mi servicio de host en el Explorador de servidores de Visual Studio:

 

 

A continuación, puedo hacer clic en una instancia de mi aplicación y seleccionar el elemento de menú de los registros de IntelliTrace logs. Eso descargará los registros desde Azure y los abrirá en Visual Studio, de esta manera:

 

 

Como puede ver en la imagen, se pueden ver los subprocesos que se utilizaron, las excepciones que se produjeron, la información del sistema, los módulos que se cargaron, etc. He simulado una excepción para probar esto estableciendo la asignación general de almacenamiento para la información diagnóstica en 5MB. Recordará que he mencionado antes que serían necesarios unos 5GB. He hecho el cambio y publicado la aplicación, y minutos después he descargado los registros IntelliTrace. Por supuesto, he encontrado el error, destacado aquí en la segunda página de registros:

 

 

Ahí está; una buena información general sobre los diagnósticos de Windows Azure 1.4. Podemos capturar eventos Trace, registros de eventos, contadores de rendimiento, registros de IIS, volcados de memoria y cualquier archivo de registro de diagnóstico personalizado. Puedo realizar protocolos de escritorio remotos para llevar a cabo más soluciones de problemas, si es necesario. Puedo descargar los registros IntelliTrace desde mi aplicación y dispongo de una experiencia de depuración limitada en mi instancia local de Visual Studio 2010.

Esta entrada de blog es una traducción. Puede consultar el artículo original en Windows Azure 1.4 Diagnostics All Up Overview