Windows Azure Diagnostics enables you to collect diagnostic data from a service running in Windows Azure. The data collected is highly configurable and can include Windows Azure logs, IIS 7.0 logs, Windows Diagnostic infrastructure logs, Failed Request logs, Windows Event logs, Performance counters, Crash dumps, and customer error logs. The collection of the data is a two stage process with data initially collected on the compute node and then transferred to Azure storage for consumption. The data transfer can be either scheduled or initiated on demand. A number of developers new to Azure have experienced problems getting the scheduled transfers working, some of the common problems encountered include:

  • Not specifying the ScheduledTransferPeriod for the type of diagnostic data required in the OnStart method. Even the data collected by default is not automatically transferred to Azure table storage and a value must be specified.
  • Specifying a ScheduledTransferPeriod less than 1 minute. If a value below 1 minute is specified, the value reverts to the default value of zero (do not transfer).
  • Not specifying a storage account for the DiagnosticConnectionString in the cloud service configuration file or leaving the value as "UseDevelopmentStorage=true".
  • Setting a DefaultEndpointsProtocol to HTTP instead of HTTPS. The symptom of this condition is the Worker role stuck in Initializing, Stopping, Stopped, Busy cycle.
  • Accidently removing the “RoleEnvironment.Changing += RoleEnvironmentChanging;” line from the OnStart method and then attempting to configure DiagnosticConnectionString.

To validate that the ScheduledTransferPeriod values are correctly set to transfer the diagnostic data, check the wad-control-container blob for the role instance and check the values specified in ScheduledTransferPeriodInMinutes for the required diagnostic data are not set to zero.

<?xml version="1.0" ?>
<ConfigRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DataSources>
<OverallQuotaInMB>4080</OverallQuotaInMB>
<Logs>
<BufferQuotaInMB>0</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>1</ScheduledTransferPeriodInMinutes>
<ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
</Logs>
<DiagnosticInfrastructureLogs>
<BufferQuotaInMB>0</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>1</ScheduledTransferPeriodInMinutes>
<ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
</DiagnosticInfrastructureLogs>
<PerformanceCounters>
<BufferQuotaInMB>0</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
<Subscriptions />
</PerformanceCounters>
<WindowsEventLog>
<BufferQuotaInMB>0</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>1</ScheduledTransferPeriodInMinutes>
<Subscriptions>
<string>Application!*</string>
</Subscriptions>
<ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
</WindowsEventLog>
<Directories>
<BufferQuotaInMB>0</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>1</ScheduledTransferPeriodInMinutes>
<Subscriptions>
<DirectoryConfiguration>
<Path>C:\Resources\directory\b0d4296799c244e1b1c7940ce801f397.WebRole1.DiagnosticStore\FailedReqLogFiles</Path>
<Container>wad-iis-failedreqlogfiles</Container>
<DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
</DirectoryConfiguration>
<DirectoryConfiguration>
<Path>C:\Resources\directory\b0d4296799c244e1b1c7940ce801f397.WebRole1.DiagnosticStore\LogFiles</Path>
<Container>wad-iis-logfiles</Container>
<DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
</DirectoryConfiguration>
<DirectoryConfiguration>
<Path>C:\Resources\directory\b0d4296799c244e1b1c7940ce801f397.WebRole1.DiagnosticStore\CrashDumps</Path>
<Container>wad-crash-dumps</Container>
<DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
</DirectoryConfiguration>
</Subscriptions>
</Directories>
</DataSources>
</ConfigRequest>

The following code fragment illustrates the transfer of IIS logs, diagnostic logs, and windows application event log to blob storage every minute.

public override bool OnStart()
{
DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();

config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);

config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);

config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);

// Start the diagnostic monitor with the modified configuration.
DiagnosticMonitor.Start("DiagnosticsConnectionString", config);
System.Diagnostics.Trace.TraceInformation("On start completed");

// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
RoleEnvironment.Changing += RoleEnvironmentChanging;

return base.OnStart();
}

Associated Service Configuration File:

<?xml version="1.0" encoding="utf-16"?>
<ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
serviceName="" osVersion="*"
xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
<Role name="WebRole1">
<ConfigurationSettings>
<Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=account;AccountKey=key" />
</ConfigurationSettings>
<Instances count="1" />
<Certificates />
</Role>
</ServiceConfiguration>

For further information see

Written by Michael Royster