Windows Azure Diagnostics allow you to collect rich diagnostic data to assist you in trouble shooting your service. It provides support for a variety of diagnostic features including Windows Azure logs, Windows Event logs, IIS logs, Failed Request Tracing (commonly known as FREB) logs, application crash dumps, and performance counters, in addition to Windows Azure Diagnostic Monitor logs with data about the diagnostic feature itself.
The diagnostics infrastructure collects data in local storage for every diagnostic type that you enable and can transfer the data it gathers to an Azure Storage account for permanent storage. You can schedule to push the collected data to storage at regular intervals or you can request an on-demand transfer whenever you require this information.
You can configure any given instance of a running service using a Diagnostics Management API provided in the Windows Azure SDK, including enabling individual diagnostic features and performing transfers of diagnostics data to Azure Storage. The API allows you to modify the configuration of a service remotely and without interrupting its execution.
During this exercise, you will instrument the MyTODO application and monitor its operation. This involves adding performance counters, scheduling tasks to transfer diagnostic data to an Azure Storage account and adding code to manage these operations from outside the cloud, more precisely, from a console application running in your desktop.
Task 1 – Configuring Azure Storage for Persisting Diagnostics Data
The myTODO application uses two separate storage settings. The first one, DataConnectionString, points to the storage account for the application's data. In addition, Windows Azure Diagnostics collects data locally for each instance of the application. To store this data permanently, the diagnostics monitor needs a second setting, DiagnosticsConnectionString, to point to the store for the information it gathers. It uses the configured storage account to persist performance counter data and event log information.
In this task, you configure the data and diagnostics storage settings for the application.
- Open Microsoft Visual Studio 2008 in elevated administrator mode, from Start | All Programs | Microsoft Visual Studio 2008 by right clicking the Microsoft Visual Studio 2008 shortcut and choosing Run as Administrator.
- In the File menu, choose Open and then Project/Solution. In the Open Project dialog, browse to Ex03-Monitoring\Begin choosing the language of your preference (C# or VB) in the Source folder of this lab, select MyTodo.sln and click Open.
- Now, configure the storage account connection strings for the application data and the diagnostics information it produces. To do this, expand the
Roles node in the MyTodo project and double-click the MyTodo.WebUX
role. In the role properties window, select the Settings tab, select the
DataConnectionString setting, ensure that the Type is set to ConnectionString, and then click the button labeled with an ellipsis. In the
Storage Connection String dialog, choose the Enter storage credentials option. Complete your storage
Account Name and storage Account Key and click OK.

Figure 1 Configuring the storage account name and account key
Note:This information is available in the Summary section of your storage account in the Windows Azure Developer Portal. You used the same settings in Exercise 1, when you deployed and configured the application. In that instance, because you were running the application in Windows Azure, you updated the configuration at the Developer Portal. - Repeat the previous steps to configure the DiagnosticsConnectionString setting using the same account information.
Task 2 – Enabling Failed Request Tracing
Failed Request Tracing produces detailed trace logs according to filters established within a web role’s configuration.
You can customize Failed Request Tracing in several ways. You can specify what content to trace, for example, all *.css files or a specific document such as “About”. You can also choose what conditions cause tracing to write a request to the log. This includes a particular response status code (e.g. 401) or a range of codes (e.g. 400-500), an event with a certain severity (e.g. critical), or the time taken to process a request (e.g. all requests that exceed 5 seconds).
For more information on Failed Request Tracing, see Troubleshooting Failed Requests Using Tracing in IIS 7.0.
In this task, you configure the web role to capture failed request information for all supported trace areas. To do so, you will modify the application to introduce an arbitrary delay into one of its responses and configure a failure condition that causes Failed Request Tracing to write the request to the log when the response time exceeds a specified limit.
Note: |
|---|
| The development environment supports the use of the Failed Request Tracing feature. To enable it, you must install the Tracing feature in IIS. |
- Open the Web.config file in the MyTodo.WebUx project. Locate the
system.webServer section and insert the following tracing section into it, as shown (highlighted) in the following configuration fragment.
<system.webServer> <validation ... /> <modules ... > ... </modules> <handlers> ... </handlers> <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> </system.webServer>
Note:The failureDefintions element shown above will result in logging for any requests that take longer than 15 seconds or that result in a response status code in the range 400 to 599. - Now, you will modify the application to introduce an arbitrary delay when it processes the response to the About page of the application. Open the HomeController.cs file in the Controllers folder of the MyTodo.WebUx project.
- Locate the About action and insert the following (highlighted) code to temporarily suspend the thread that processes the request for several seconds.
public ActionResult About() { System.Threading.Thread.Sleep(18000); return this.View(); } - Press F5 to launch the cloud project in the development fabric.
- Switch to the development fabric UI and ensure that the service has started successfully.
- Open the local store to examine the diagnostic files. To do this, in the Development Fabric, expand the
Service Deployments tree view to locate the node for the MyTodo.WebUx role, Expand this node to display its instances and right-click the single instance under it to select
Open local store.

Figure 2 Opening the local store in the development fabric
Note:Currently, opening the Local Store from the Development Fabric UI is not possible when you log in as regular user, even after launching Visual Studio in elevated mode. If you are unable to open the local store from the Development Fabric, execute this task logged in as an administrator or, as an alternative, carry out the following procedure to start the Development Fabric service manually, using a path to the local store that is accessible to the current user. 1. If necessary, press SHIFT + F5 to stop the running application. 2. Stop the Development Fabric service if it is currently running. To do this, right-click its icon in the task bar and select Shutdown Development Fabric service. 3. Open a Windows Azure SDK command prompt elevated as an administrator. In the Start menu, choose All Programs | Windows Azure SDK v1.0, right-click Windows Azure SDK Command Prompt and select Run as administrator. 4. At the command prompt, enter bin\devfabric\dfservice -sp "<LOCAL_STORE_PATH>". Replace the placeholder with the path to a folder where you have access, for example, bin\devfabric\dfservice -sp "C:\DevFabric". 5. To view the local store, open a Windows Explorer window pointing at the path chosen in the previous step. In this folder, select the subdirectory for the current deployment, which you can determine from the Service Deployments tree view in the Development Fabric, and navigate to the res\deployment(XXX).MyTodo.MyTodo.WebUx.0 folder. - In the folders tree view of the newly opened Windows Explorer window, expand directory | DiagnosticStore | FailedReqLogFiles.
- Now, you will make a request that will trigger a failure based on the tracing rules that you configured earlier and cause it to be written to the log. To bring this about, click the About link in the browser window to navigate to this page. Recall that you inserted a delay in the processing of the corresponding controller action that is greater than the timeTaken limit set in the tracing configuration.
- Switch to the Windows Explorer window and expand the FailedReqLogFiles folder where you will find a W3SVC1 folder that contains the log files.
- Inside this folder, locate the log file corresponding to the failed request to the
About page.
Note:The W3SVC1 directory contains Failed Request Tracing log files in XML format, one file for each failed request. It should contain at least one log file for the failed request that you induced. A second log file might be present in this folder if the response time for the initial page of the site was greater than the configured limit as the result of a slow start up time of the web role. In addition, the folder contains an XSL style sheet file that allows you to view each log file in an easily comprehensible format. 
Figure 3 Viewing Failed Request Tracing logs in the local store
- Double-click the xml log file in Windows Explorer to open the file in your browser. Notice that the
Request Summary tab shows the URL of the failed request as well as a reason for the failure, in this case TIME_TAKEN. The summary also shows the response status code and the time taken to process the request.

Figure 4 Summary view for the failed request
Each log file contains a wealth of information about a request that can prove invaluable when troubleshooting an application. It is beyond the scope of this lab to analyze this feature in detail but you might want to spend some time examining the various views available in the trace report.
- (Optional) The failureDefinitions element that you configured in the tracing section of the Web.config file not only specifies a timeTaken attribute to capture requests that exceeded a certain time to be processed, but also includes a statusCodes attribute to log requests that have response status code in the range 400 to 599. To see this in action, enter an invalid URL in the address bar of the browser, for example http://127.0.0.1:81/Home/BadURL, and press ENTER. Examine the failed request log file generated as a result of the 404 status code. Notice that this time the failure reason is STATUS_CODE.
- In addition to failed traced requests, Windows Azure Diagnostics collects Internet Information Server logs by default and stores them locally for each instance of the web role. To view the IIS logs, in Windows Explorer, locate the
LogFiles folder inside DiagnosticStore. Inside this folder, you will find a
W3SVC1 folder that contains the log files.

Figure 5 Viewing IIS logs in the local store
- Double-click any one of the log files in this folder to open it in Notepad. Notice that it is a standard IIS log file with details about every request made to the application, including its date and time, the request URL, and the response status.

Figure 6 Internet Information Server log file
In this task, you have examined several logging features by browsing the information captured locally by the Development Fabric. When you deploy your application to Windows Azure, you will no longer have direct access to these files in the local store. Instead, you will configure the diagnostics infrastructure to transfer the information to table and blob storage in your Azure Storage account. In the next task, you will see how you can achieve this.
Task 3 – Instrumenting a Web Role
Using the Diagnostics Management API, an application can define the information that it needs to collect at role start up time.
In this task, you add code to the myTODO application to enable Windows Azure logs and set up a transfer schedule that automatically copies the logs to an Azure Storage account at regular intervals. In addition, you enable logging and use the standard .NET tracing API to write messages to the log.
- Open the WebRole.cs file in the MyTodo.WebUx project. This file contains the role entry point of the web role.
- In the OnStart method of WebRole class, first delete the call to
DiagnosticsMonitor.Start at the start of the method and then insert the following (highlighted) code to replace it. This code schedules the transfer of the error logs produced in the web role to Azure Storage.
(Code Snippet – Deploying and Monitoring Application in Windows Azure - Ex 3 Web Role Diagnostic Monitor Configuration – C#)
public override bool OnStart() { // Get the factory configuration so that it can be edited DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration(); // Set scheduled transfer interval for infrastructure logs to 1 minute config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1); // Specify a logging level to filter records to transfer config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Error; // Set scheduled transfer interval for user's Windows Azure Logs to 1 minute config.Logs.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1); DiagnosticMonitor.Start("DiagnosticsConnectionString", config); RoleEnvironment.Changing += this.RoleEnvironmentChanging; ... return base.OnStart(); }
Note:For projects created in Visual Studio, the role template generates code to initialize the Diagnostic Monitor with default settings. Typically, you will not need to change these settings, as you would normally request an on-demand transfer of diagnostics information whenever you require it for troubleshooting purposes. In the code shown above, the role uses custom settings to set up a schedule that transfers the Windows Azure and Diagnostics Infrastructure logs to storage once every minute and creates a logging level filter to select only those records with an error level equal to or greater than Error. Setting up an automatic transfer schedule in this manner will allow you to examine the information contained in the Azure Storage diagnostic tables later in the exercise. - Next, update the application to write a warning to the log whenever a user fails authentication using the standard .NET tracing API in
System.Diagnostics. To do this, open the AccountMembershipService.cs file in the
Authentication folder of the MyTodo.WebUx project, locate the ValidateUser method and replace its body with the following (highlighted) code.
public bool ValidateUser(string userName, string password) { bool valid = this.provider.ValidateUser(userName, password); if (!valid) { System.Diagnostics.Trace.TraceWarning("Invalid login: {0}", userName); } return valid; }
Note:The updated method writes a warning event to the log whenever the authentication module detects a failed login attempt. - Finally, enable tracing in the configuration file by configuring a trace listener specific to Windows Azure Diagnostics. To configure the listener, open the
Web.config file in the MyTodo.WebUx project and insert the following (highlighted) configuration block.
<configuration> ... <system.diagnostics> <trace autoflush="false" indentsize="4"> <listeners> <add name="AzureDiagnostics" type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </listeners> </trace> </system.diagnostics> </configuration>
Note:The System.Diagnostic.Trace class provides a set of methods and properties that help you trace the execution of your code. To use the methods in this class to record information in the Windows Azure logs, you need to configure a trace listener specific to Windows Azure in the system.diagnostics section of the configuration file (Web.config file for a web role or App.config file for a worker role). This step is usually unnecessary for roles created in Visual Studio because they already include the necessary settings in their role templates. - Press F5 to build and run the application in the development fabric.
Note:In this task, for convenience, you run the application locally in the development fabric but you configure it to use Azure Storage. Instead, you may wish to deploy the application to Windows Azure. In that case, use the procedure that you learnt in Exercise 1 to deploy the application using the Windows Azure Developer Portal or, alternatively, take advantage of the PowerShell cmdlets from the Windows Azure Service Management tools that you saw in Exercise 2 to do the same thing. - In the browser window, click Sign In. In the Log On page, enter any username and password and attempt to sign in using invalid credentials. Recall that previously, you modified the application to log a warning for authentication failures.

Figure 7 Signing in to the application with invalid credentials
- Switch to the Development Fabric UI and display the log for the web role to verify that the failed login attempt resulted in a warning message in the log.

Figure 8 Web role log showing the failed login attempt
- Next, examine the logs that the Diagnostics Monitor pushes to Windows Azure table storage. To do this, you will take advantage of the Windows Azure TableBrowser, which is a publicly available Web application that allows you to browse your Azure Storage tables and create, edit, delete, and copy entities. To use it, open your browser and navigate to http://myazurestorage.com.
- In the home page for the TableBrowser, enter the Account Name and Primary Access Key of your Azure Storage account and click
Log In. Specify the same settings that you used previously, when you configured the
DiagnosticConnectionString setting for the web role.

Figure 9 Signing in to the Windows Azure TableBrowser tool
- After you sign in, the tool presents you with a list of tables in your account. There should be at least five tables. The first three contain information for the ASP.NET providers used by the application. The remaining two tables hold the log information
that the Diagnostics Manager transferred based on the schedule configured in the
OnStart method of the web role.
Membership
Contains membership information for the Azure TableStorageMembershipProvider.
Roles
Contains role information for the Azure TableStorageRoleProvider.
Sessions
Contains session information for the TableStorageSessionStateProvider.
WADInfrastructureLogsTable
Contains logs from the diagnostic infrastructure, which help the user troubleshoot issues with the diagnostic monitoring system itself.
WADLogsTable
Contains the logs generated by the application using the standard .NET tracing API.
Figure 10 Table storage showing the application and diagnostics tables
- Click the link for the WADLogsTable to examine its content. This table contains the application logs. It should contain at least one row corresponding to the failed login attempt. To expand or collapse the contents of the row, click the green / red
icon to its left. Notice the Message column showing the information logged by the
TraceInformation call that you added to the ValidateUser method earlier in the task.

Figure 11 Log message showing the failed login attempt
Task 4 – Monitoring Azure Services Remotely
The Diagnostics Management API allows you to change the diagnostics configuration of any role instance in a running service from outside the cloud, without stopping the service. This includes adding performance counters, collecting Windows Event and other custom logs, and triggering the transfer of diagnostics information to Azure Storage.
In this task, you execute a console application in your desktop to update the role diagnostic configuration and add a performance counter. Then, you use the same tool to trigger an on-demand transfer of the collected performance data to Azure Storage. You can find the source code for the diagnostics tool in the MyTodo.Diagnostics.Client project of the solution.
Figure 12 Console application to configure diagnostics for an Azure Service remotely
- Open the AzureDiagnosticConfiguration.cs file in the MyTodo.Diagnostics.Client project.
- Implement the AddPerformanceCounter method by inserting code that uses the Diagnostics Management API to add a performance counter to the configuration of an Azure Service.
(Code Snippet – Deploying and Monitoring Application in Windows Azure - Ex3 Add Performance Counter – C#)
public void AddPerformanceCounter(PerformanceCounterConfiguration performanceCounter) { // Create a new DeploymentDiagnosticManager for the given deployment id var diagnosticManager = new DeploymentDiagnosticManager(this.storageAccount, this.deploymentId); // Get the role instance diagnostics manager for all instance of the role var roleInstanceManagers = diagnosticManager.GetRoleInstanceDiagnosticManagersForRole(this.roleName); // Set the new configuration for each instance of the role foreach (var roleInstanceManager in roleInstanceManagers) { DiagnosticMonitorConfiguration diagnosticConfiguration = roleInstanceManager.GetCurrentConfiguration(); // Add the new performance counter to the configuration diagnosticConfiguration.PerformanceCounters.DataSources.Add(performanceCounter); // Update the configuration roleInstanceManager.SetCurrentConfiguration(diagnosticConfiguration); } }
Note:The code obtains a reference to the Diagnostics Manager for all instances of a role, then loops through each instance adding a new performance counter to the role instance configuration, and then saves the changes. When you execute the diagnostics tool specifying the AddPerformanceCounter operation in its command line, it invokes this method to add the new performance counter and update the diagnostics configuration of the service. - Next, in the AzureDiagnosticConfiguration class, implement the PerformOnDemandTransfer method to transfer all diagnostic data from the local storage of the role instance to Azure Storage.
(Code Snippet – Deploying and Monitoring Application in Windows Azure - Ex3 PerformOnDemandTransfer – C#)
public void PerformOnDemandTransfer(DataBufferName dataBufferName) { // Create a new DeploymentDiagnosticManager for the given deployment id var diagnosticManager = new DeploymentDiagnosticManager(this.storageAccount, this.deploymentId); // Get the role instance diagnostics manager for all instance of the a role var roleInstanceManagers = diagnosticManager.GetRoleInstanceDiagnosticManagersForRole(this.roleName); var transferOptions = new OnDemandTransferOptions(); transferOptions.From = DateTime.UtcNow - TimeSpan.FromMinutes(5); transferOptions.To = DateTime.UtcNow; transferOptions.NotificationQueueName = this.transferQueueName.ToLowerInvariant(); var queueClient = this.storageAccount.CreateCloudQueueClient(); queueClient.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1)); var queue = queueClient.GetQueueReference(transferOptions.NotificationQueueName); queue.CreateIfNotExist(); foreach (var roleInstanceManager in roleInstanceManagers) { CancelAllPreviousTransfers(roleInstanceManager); // Start the transfer for each instance of the role roleInstanceManager.BeginOnDemandTransfer(dataBufferName, transferOptions); // Poll the feedback queue every 15 sec for 10 min to see if the transfer is complete. PollAndConfirmTransfer(roleInstanceManager, queue); } } - Save the AzureDiagnosticConfiguration.cs file.
- Next, update the application to display the deployment ID of the service in its page title. You will need to supply this information to the diagnostics tool later, when you use it to configure your deployment. To add the deployment ID to the title, open
the Site.Master file in the Views\Shared folder of the MyTodo.WebUx project. Locate the
title tag inside the head of the page and insert the following code to append the DeploymentId property to the page title.
Note that this step is not strictly necessary when you run the application in the Development Fabric, because you can obtain the deployment ID from corresponding node in the Service Deployments tree view.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=8" /> <title> <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> | DeploymentId: <%= Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.DeploymentId %> </title> <link href="<%=Url.Content("~/Content/styles/site.css")%>" rel="stylesheet" type="text/css" /> <asp:ContentPlaceHolder ID="StylesContent" runat="server"></asp:ContentPlaceHolder> </head> <body> <div id="container"> ...
Note:The Diagnostics Management API requires the storage account used to store diagnostics information and the deployment ID of your service.
Verification
Now, you will test the remote diagnostic monitoring capabilities of Windows Azure. First, you will configure a new performance monitor counter to measure “% Processor Time” and then you will trigger an on-demand transfer of performance counter data to Azure Storage. Finally, you will inspect the table that received the performance records collected by the counter.
- Press F5 to build and run the application.
- Obtain the deployment ID of the running service. To retrieve the ID, switch to the browser window showing the start page of the application and record the
DeploymentId value shown in the title bar. Alternatively, if you are running the application in the Development Fabric, you can obtain the Deployment ID from the corresponding label in the Service Deployments tree view.

Figure 13 Obtaining the deployment ID of the service
- Open a command prompt and change the current directory to %WindowsAzurePlatformKit%\Labs\WindowsAzureDeployment\Source\Ex03-Monitoring\{begin|end}\{CS|VB}\MyTodo.Diagnostics.Client\bin\debug.
- At the command prompt, execute myTodoMonitorClient indicating the AddPerformanceCounter operation. Use the following command line arguments ensuring that you replace the parameter placeholders with the settings that apply to your service account.
[code
lang="other"]
myTodoMonitorClient.exe AddPerformanceCounter /accountName:<YOUR_STORAGE_NAME> /accountKey:<YOUR_STORAGE_KEY> /roleName:MyTodo.WebUx /deploymentId:<YOUR_DEPLOYMENT_ID> /counter:"\Processor(_Total)\% Processor Time" /sampleRate:5
[/code]
Note:The command receives your Azure Storage account credentials, the name of the role to configure, the deployment ID of the service, the name of the counter to add, and a sampling rate (in seconds), and updates the configuration of the role instances to add a new performance counter. If you are using the tool to configure an application that uses Development Storage, omit the accountName and accountKey parameters from the command line above. 
Figure 14 Remotely adding performance counters to a running service
- Now, you will transfer the diagnostics data saved in the preview exercise to your Azure Storage account.
At the command prompt, once again execute the myTodoMonitorClient command, this time specifying the
OnDemandTransfer operation. Remember to replace the parameter placeholders with your service account information.
myTodoMonitorClient.exe OnDemandTransfer /accountName:<YOUR_STORAGE_NAME> /accountKey:<YOUR_STORAGE_KEY> /roleName:MyTodo.WebUx /deploymentId:<YOUR_DEPLOYMENT_ID> /bufferName:PerformanceCounters

Figure 15 Pushing diagnostics data to Azure Storage
Note:The bufferName parameter specifies which information you are transferring to Azure Storage. You can specify the following values: DiagnosticInfrastructureLogs, Directories, Logs, PerformanceCounters, and WindowsEventLogs. - Now that you have triggered the transfer of performance data to your Azure Storage account, it is time to verify that the operation succeeded. Again, open your browser and navigate to http://myazurestorage.com.
- In the home page for the TableBrowser, enter the Account Name and Primary Access Key of your Azure Storage account and click Log In.
- If you recall the tables that existed in your account after completing the previous task, you will notice that there is now an additional table named
WADPerformanceCountersTable. This table contains the performance data that was collected by the counter that you added earlier in this task.

Figure 16 Azure Table Storage showing the new performance counters table
- Click the WADPerformanceCountersTable link to view the contents of this table. In the table, you will find the performance data collected during the interval prior to the on-demand transfer. Expand any one of the rows to view the information it contains.
To do this, click the green icon next to the row.

Figure 17 Performance counter data table containing records for “% Processor Time”
Note:You are examining the information in the TableBrowser to review its format and see how it is stored in an Azure Storage table. In a more common scenario, you would use an application to process the information in these tables and generate reports and statistics.