65
Page | 1 Hands-On Lab Debugging Applications in Windows Azure Lab version: 1.0.0 Last updated: 11/16/2010

Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

  • Upload
    others

  • View
    4

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 1

Hands-On Lab

Debugging Applications in Windows Azure

Lab version: 1.0.0

Last updated: 11/16/2010

Page 2: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 2

CONTENTS

OVERVIEW ................................................................................................................................................... 3

EXERCISE 1: DEBUGGING AN APPLICATION IN THE CLOUD .............................................................. 5 Task 1 – Exploring the Fabrikam Insurance Application ....................................................................... 6

Task 2 – Running the Application as a Cloud Service ............................................................................ 8

Task 3 – Adding Tracing Support to the Application ........................................................................... 14

Task 4 – Creating a Log Viewer Tool ................................................................................................... 25

Verification .......................................................................................................................................... 33

EXERCISE 2: USING INTELLITRACE TO DIAGNOSE ROLE START-UP FAILURES .......................... 39 Task 1 – Preparing the Application for Deployment to the Cloud ...................................................... 40

Task 2 – Configuring Visual Studio for Deploying Applications to Windows Azure (Optional) .......... 41

Task 3 – Deploying the Application with IntelliTrace Enabled ............................................................ 49

Task 4 – Examining the IntelliTrace Logs to Determine the Cause of a Failure .................................. 52

Task 5 – Fixing the Application and Re-Deploying (Optional) ............................................................. 62

SUMMARY .................................................................................................................................................. 65

Page 3: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 3

Overview

Using Visual Studio, you can debug applications in your local machine by stepping through code, setting

breakpoints, and examining the value of program variables. For Windows Azure applications, the

Development Fabric allows you to run the code locally and debug it using these same features and

techniques, making this process relatively straightforward.

Ideally, you should take advantage of the Development Fabric and use Visual Studio to identify and fix

most bugs in your code, as this provides the most productive environment for debugging. Nevertheless,

some bugs might remain undetected and will only manifest themselves once you deploy the application

to the cloud. These are often the result of missing dependencies or caused by differences in the

execution environment. For addition information on environment issues, see Differences Between the

Development Fabric and Windows Azure.

Once you deploy an application to the cloud, you are no longer able to attach a debugger and instead,

need to rely on debugging information written to logs in order to diagnose and troubleshoot application

failures. Windows Azure provides comprehensive diagnostic facilities that allow capturing information

from different sources, including Windows Azure application logs, IIS logs, failed request traces,

Windows event logs, custom error logs, and crash dumps. The availability of this diagnostic information

relies on the Windows Azure Diagnostics Monitor to collect data from individual role instances and

transfer this information to Windows Azure Storage for aggregation. Once the information is in storage,

you can retrieve it and analyze it.

While the information gathered by Windows Azure Diagnostics can be a very valuable troubleshooting

resource, for quick debugging, you often need immediate access to the diagnostic data. The lab shows

how you can configure a custom trace listener and enable it at runtime to write diagnostics output

directly to a table in Windows Azure storage.

Sometimes an application may crash before it is able to produce logs that can help you determine the

cause of the failure. With IntelliTrace debugging, a feature available in the Visual Studio 2010 Ultimate

edition, you can log extensive debugging information for a role instance while it is running in Windows

Azure. The lab discusses how to enable IntelliTrace for an Azure deployment to debug role start up

failures.

Objectives

In this hands-on lab, you will:

Learn what features and techniques are available in Visual Studio and Windows Azure to debug

applications once deployed to Windows Azure.

Use a simple TraceListener to log directly to table storage and a viewer to retrieve these logs.

Understand how to enable and use IntelliTrace to trace and debug applications.

Page 4: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 4

Prerequisites

The following is required to complete this hands-on lab:

IIS 7 (with ASP.NET, WCF HTTP Activation)

Microsoft .NET Framework 4.0

Microsoft Visual Studio 2010

Windows Azure Tools for Microsoft Visual Studio 1.2 (June 2010)

Setup

For convenience, much of the code used in this hands-on lab is available as Visual Studio code snippets.

To check the prerequisites of the lab and install the code snippets:

1. Open a Windows Explorer window and browse to the lab’s Source\Setup folder.

2. Double-click the Dependencies.dep file in this folder to launch the Dependency Checker tool

and install any missing prerequisites and the Visual Studio code snippets.

3. If the User Account Control dialog is shown, confirm the action to proceed.

Note: This process may require elevation. The .dep extension is associated with the Dependency

Checker tool during its installation. For additional information about the setup procedure and how to

install the Dependency Checker tool, refer to the Setup.docx document in the Assets folder of the

training kit.

Using the Code Snippets

Throughout the lab document, you will be instructed to insert code blocks. For your convenience, most

of that code is provided as Visual Studio Code Snippets, which you can use from within Visual Studio

2010 to avoid having to add it manually.

If you are not familiar with the Visual Studio Code Snippets, and want to learn how to use them, you can

refer to the Setup.docx document in the Assets folder of the training kit, which contains a section

describing how to use them.

Page 5: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 5

Exercises

This hands-on lab includes the following exercises:

1. Debugging an Application in the Cloud

2. Using IntelliTrace to Diagnose Role Start-Up Failures

Estimated time to complete this lab: 60 minutes.

Note: When you first start Visual Studio, you must select one of the predefined settings collections.

Every predefined collection is designed to match a particular development style and determines

window layouts, editor behavior, IntelliSense code snippets, and dialog box options. The procedures in

this lab describe the actions necessary to accomplish a given task in Visual Studio when using the

General Development Settings collection. If you choose a different settings collection for your

development environment, there may be differences in these procedures that you need to take into

account.

Exercise 1: Debugging an Application in

the Cloud

Because Windows Azure Diagnostics is oriented towards operational monitoring and has to cater for

gathering information from multiple role instances, it requires that diagnostic data first be transferred

from local storage in each role to Windows Azure storage, where it is aggregated. This requires

programming scheduled transfers with the Diagnostic Monitor to copy logging data to Azure storage at

regular intervals, or else requesting a transfer of the logs on-demand. Moreover, information obtained

in this manner provides a snapshot of the diagnostics data available at the time of the transfer. To

retrieve updated data, a new transfer is necessary. When debugging a single role, and especially during

the development phase, these actions add unnecessary friction to the process. To simplify the retrieval

of diagnostics data from a deployed role, it is simpler to read information directly from Windows Azure

storage, without requiring additional steps.

In this exercise, you debug a simple application by configuring a special trace listener that can write its

output directly into a table in Windows Azure Storage. To produce diagnostic data, you instrument the

application to write its trace information using standard methods in the System.Diagnostics namespace.

Finally, you create a simple log viewer application that can retrieve and display the contents of the

diagnostics table.

Page 6: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 6

The application that you will use for this exercise simulates an online auto insurance policy calculator. It

has a single form where users can enter details about their vehicle and then submit the form to obtain

an estimate on their insurance premium. Behind the scenes, the controller action that processes the

form uses a separate assembly to calculate premiums based on the input from the user. The assembly

contains a bug that causes it to raise an exception for input values that fall outside the expected range.

Task 1 – Exploring the Fabrikam Insurance Application

In this task, you build and run the Fabrikam Insurance application in the Web Development Server to

become familiar with its operation.

1. Open Visual Studio in elevated administrator mode from Start | All Programs | Microsoft Visual

Studio 2010 by right clicking the Microsoft Visual Studio 2010 shortcut and choosing Run as

administrator.

2. If the User Account Control dialog appears, click Continue.

3. In the File menu, choose Open and then Project/Solution. In the Open Project dialog, browse

to Ex1-LoggingToAzureStorage in the Source folder of the lab and choose the folder for the

language of your preference (Visual C# or Visual Basic). Select Begin.sln in the Begin folder and

then click Open.

4. Set the start action of the project. To do this, in Solution Explorer, right-click the

FabrikamInsurance project and then select Properties. In the properties window, switch to the

Web tab and then, under Start Action, select the Specific Page option. Leave the page value

blank.

Figure 1

Configuring the start action of the project

Page 7: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 7

5. Press F5 to build and run the solution. The application should launch in the Web Development

Server and open its Auto Insurance Quotes page in your browser.

6. To explore its operation, complete the form by choosing any combination of values from the

Vehicle Details drop down lists and then click Calculate to obtain a quote for the insurance

premium. Notice that after you submit the form, the page refreshes and shows the calculated

amount.

Figure 2

Exploring the Fabrikam Insurance application

7. Press SHIFT + F5 to stop debugging and shut down the application.

Page 8: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 8

Task 2 – Running the Application as a Cloud Service

In this task, you create a new Cloud Service project to prepare the application for deployment to

Windows Azure.

1. Add a new Cloud Service project to the solution. To do this, in the File menu, point to Add and

then select New Project. In the Add New Project dialog, expand the language of your

preference (Visual C# or Visual Basic) in the Installed Templates list and then select Cloud.

Choose the Windows Azure Cloud Service template, set the Name of the project to

FabrikamInsuranceService and accept the proposed location in the folder of the solution. Click

OK to create the project.

Figure 3

Creating a new cloud service project (C#)

Page 9: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 9

Figure 4

Creating a new cloud service project (Visual Basic)

2. In the New Cloud Service Project dialog, click OK without adding any new roles to the solution.

3. Now, in Solution Explorer, right-click the Roles node in the new FabrikamInsuranceService

project, point to Add, and then select Web Role Project in solution. Then, in the Associate with

Role Project dialog, select the FabrikamInsurance project, and click OK.

Page 10: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 10

Figure 5

Associating the MVC application with the cloud service

4. Add references to the Windows Azure support assemblies. To do this, in Solution Explorer,

right-click the FabrikamInsurance project, and then select Add Reference. In the Add Reference

dialog, switch to the .NET tab, select the Microsoft.WindowsAzure.Diagnostics,

Microsoft.WindowsAzure.ServiceRuntime, and Microsoft.WindowsAzure.StorageClient

components, and then click OK.

Page 11: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 11

Figure 6

Adding references to the Windows Azure support assemblies to the project

5. Now, add a role entry point to the MVC application. To do this, in Solution Explorer, right-click

the FabrikamInsurance project, point to Add, and then select Existing Item. In the Add Existing

Item dialog, browse to Assets in the Source folder of the lab. Inside this folder, choose the

folder for the language of your project (Visual C# or Visual Basic), select WebRole.cs or

WebRole.vb, and then click Add.

Note: The WebRole class is a RoleEntryPoint derived class that contains methods that

Windows Azure calls when it starts, runs, or stops the role. The provided code is the same that

Visual Studio generates when you create a new Cloud Service project.

6. You are now ready to test the cloud service application. To launch the application in the

development fabric, press F5. Wait until the deployment completes and the browser opens to

show its main page.

7. Again, complete the entry form by choosing a combination of values from the drop down lists

and then click Calculate. Ensure that you receive a valid response with the calculated premium

as a result.

Page 12: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 12

8. Once you have verified that everything works in the development fabric just as it did when

hosted by the Web Development Server, you will now cause an exception by making the

application process bad data that it does not handle correctly. To do this, change the values

used for the calculation by setting the Make to “PORSCHE” and the Model to “BOXTER (BAD

DATA)”.

Figure 7

Choosing make and model for the insurance premium calculation

9. Click Calculate to re-submit the form with new values. Notice that an unhandled exception

occurs and execution halts in the Visual Studio debugger at the line that caused the error.

Figure 8

Unhandled exception in the application caused by bad data

Page 13: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 13

Note: Within the Visual Studio debugger, you are able to step through code, set breakpoints,

and examine the value of program variables. Debugging applications hosted in the

development fabric provides the same experience that you typically have when debugging

other programs to which you can attach the Visual Studio debugger. Using the debugger under

these conditions is covered extensively and will not be explored here. For more information,

see Debugging in Visual Studio.

10. Press F5 to continue execution and let ASP.NET handle the exception. Notice that the

unhandled exception handler provides details about the exception, including the line in the

source code that raised the exception.

Figure 9

ASP.NET default unhandled exception handler

Note: Unhandled exceptions are typically handled by ASP.NET, which can report the error in its

response including details about an error and the location in the source code where the

exception was raised. However, for applications that are available publicly, exposing such

information is not recommended to prevent unnecessary disclosure of internal details about

the application that may compromise its security. Instead, errors and other diagnostics output

should be written to a log that can only be retrieved after proper authorization.

Page 14: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 14

You can configure how information is displayed by ASP.NET when an unhandled error occurs

during the execution of a Web request. For more information, see customErrors Element

(ASP.NET Settings Schema).

In this case, the unhandled exception error page includes full details for the error because the

default mode for the customErrors element is remoteOnly and you are accessing the page

locally. When you deploy the application to the cloud and access it remotely, the page shows a

generic error message instead.

11. Press SHIFT + F5 to stop debugging and shut down the application.

Task 3 – Adding Tracing Support to the Application

In the previous task, you briefly saw how to debug your application with Visual Studio when it executes

locally in the development fabric. To debug the application once you deploy it to the cloud, you need to

write debugging information to the logs in order to diagnose an application failure.

In this task, you add a TraceListener to the project capable of logging diagnostics data directly into table

storage, where you can easily retrieve it with a simple query. The source code for this project is already

provided for you in the Assets folder of the lab.

1. In Solution Explorer, right-click the Begin solution, point to Add and then select Existing

Project. In the Add Existing Project dialog, browse to Assets in the Source folder of the lab,

select the folder for the language of your choice (Visual C# or Visual Basic), then navigate to

AzureDiagnostics inside this folder, select the AzureDiagnostics project file and click Open.

2. Add a reference to the AzureDiagnostics library in the Web role project. To do this, in Solution

Explorer, right-click the FabrikamInsurance project, and select Add Reference. In the Add

Reference dialog, switch to the Projects tab, select AzureDiagnostics in the list of projects, and

then click OK.

3. Open WebRole.cs (for Visual C# projects) or WebRole.vb (for Visual Basic projects) in the

FabrikamInsurance project and insert the following (highlighted) method into the WebRole

class.

(Code Snippet – WindowsAzureDebugging-Ex1-ConfigureTraceListener-CS)

C#

public class WebRole : RoleEntryPoint

{

...

private static void ConfigureTraceListener()

{

bool enableTraceListener = false;

Page 15: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 15

string enableTraceListenerSetting =

RoleEnvironment.GetConfigurationSettingValue("EnableTableStorageTraceListener"

);

if (bool.TryParse(enableTraceListenerSetting, out enableTraceListener))

{

if (enableTraceListener)

{

AzureDiagnostics.TableStorageTraceListener listener =

new

AzureDiagnostics.TableStorageTraceListener("DiagnosticsConnectionString")

{

Name = "TableStorageTraceListener"

};

System.Diagnostics.Trace.Listeners.Add(listener);

System.Diagnostics.Trace.AutoFlush = true;

}

else

{

System.Diagnostics.Trace.Listeners.Remove("TableStorageTraceListener");

}

}

}

}

(Code Snippet – WindowsAzureDebugging-Ex1-ConfigureTraceListener-VB)

Visual Basic

Public Class WebRole

Inherits RoleEntryPoint

...

Private Shared Sub ConfigureTraceListener()

Dim enableTraceListener As Boolean = False

Dim enableTraceListenerSetting As String =

RoleEnvironment.GetConfigurationSettingValue("EnableTableStorageTraceListener"

)

If Boolean.TryParse(enableTraceListenerSetting, enableTraceListener) Then

If enableTraceListener Then

Dim listener As New

AzureDiagnostics.TableStorageTraceListener("DiagnosticsConnectionString") With

{.Name = "TableStorageTraceListener"}

System.Diagnostics.Trace.Listeners.Add(listener)

System.Diagnostics.Trace.AutoFlush = True

Else

System.Diagnostics.Trace.Listeners.Remove("TableStorageTraceListener")

End If

End If

Page 16: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 16

End Sub

End Class

Note: The ConfigureTraceListener method retrieves the EnableTableStorageTraceListener

configuration setting and, if its value is true, it creates a new instance of the

TableStorageTraceListener class, defined in the project that you added to the solution earlier,

and then adds it to the collection of available trace listeners. Note that the method also

enables the AutoFlush property of the Trace object to ensure that trace messages are written

immediately to table storage, allowing you to retrieve them as they occur.

4. Now, insert the following (highlighted) code in the OnStart method of the WebRole class to set

up the Azure Storage configuration settings publisher and to enable the

TableStorageTraceListener.

(Code Snippet – WindowsAzureDebugging-Ex1-WebRole OnStart-CS)

C#

public class WebRole : RoleEntryPoint

{

public override bool OnStart()

{

DiagnosticMonitor.Start("DiagnosticsConnectionString");

CloudStorageAccount.SetConfigurationSettingPublisher((configName,

configSetter) =>

{

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

});

ConfigureTraceListener();

// For information on handling configuration changes

// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

RoleEnvironment.Changing += RoleEnvironmentChanging;

return base.OnStart();

}

...

}

(Code Snippet – WindowsAzureDebugging-Ex1-OnStart-VB)

Visual Basic

Page 17: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 17

Public Class WebRole

Inherits RoleEntryPoint

Public Overrides Function OnStart() As Boolean

DiagnosticMonitor.Start("DiagnosticsConnectionString")

CloudStorageAccount.SetConfigurationSettingPublisher(Sub(configName,

configSetter)

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))

ConfigureTraceListener()

' For information on handling configuration changes

' see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironmentChanging

Return MyBase.OnStart()

End Function

...

End Class

Note: TraceListeners can be added by configuring them in the system.diagnostics section of

the configuration file. However, in this case, the role creates the listener programmatically

allowing you to enable the listener only when you need it and while the service is running.

Figure 10

Enabling the TableStorageTraceListener in the configuration file

5. Next, define a configuration setting to control the diagnostics logging with the

TableStorageTraceListener. To create the setting, expand the Roles node in the

FabrikamInsuranceService project and then double-click the FabrikamInsurance role. In the

role properties window, switch to the Settings page, click Add Setting, and then set the name of

the new setting to EnableTableStorageTraceListener, the type as String, and the value as false.

Page 18: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 18

Figure 11

Creating a configuration setting to enable the trace listener

6. Locate the RoleEnvironmentChanging event handler inside the WebRole class and replace its

body with the following (highlighted) code.

(Code Snippet – WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanging event

handler-CS)

C#

public class WebRole : RoleEntryPoint

{

...

private void RoleEnvironmentChanging(object sender,

RoleEnvironmentChangingEventArgs e)

{

// for any configuration setting change except

EnableTableStorageTraceListener

if

(e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any(change =>

change.ConfigurationSettingName != "EnableTableStorageTraceListener"))

{

// Set e.Cancel to true to restart this role instance

e.Cancel = true;

}

}

...

}

(Code Snippet – WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanging event

handler-VB)

Visual Basic

Page 19: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 19

Public Class WebRole

Inherits RoleEntryPoint

...

Private Sub RoleEnvironmentChanging(ByVal sender As Object, ByVal e As

RoleEnvironmentChangingEventArgs)

' for any configuration setting change except

EnableTableStorageTraceListener

If e.Changes.OfType(Of

RoleEnvironmentConfigurationSettingChange)().Any(Function(change)

change.ConfigurationSettingName <> "EnableTableStorageTraceListener") Then

' Set e.Cancel to true to restart this role instance

e.Cancel = True

End If

End Sub

...

End Class

Note: The RoleEnvironmentChanging event occurs before a change to the service

configuration is applied to the running instances of the role. The updated handler scans the

collection of changes and restarts the role instance for any configuration setting change,

unless the change only involves the value of the EnableTableStorageTraceListener setting. If

this particular setting changes, the role instance is allowed to apply the change without

restarting it.

7. Now, add the following (highlighted) code to define a handler for the RoleEnvironmentChanged

event.

(Code Snippet – WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanged event

handler-CS)

C#

public class WebRole : RoleEntryPoint

{

...

private void RoleEnvironmentChanged(object sender,

RoleEnvironmentChangedEventArgs e)

{

// configure trace listener for any changes to

EnableTableStorageTraceListener

if

(e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any(change =>

change.ConfigurationSettingName == "EnableTableStorageTraceListener"))

{

ConfigureTraceListener();

}

Page 20: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 20

}

...

}

(Code Snippet – WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanged event

handler-VB)

Visual Basic

Public Class WebRole

Inherits RoleEntryPoint

...

Private Sub RoleEnvironmentChanged(ByVal sender As Object, ByVal e As

RoleEnvironmentChangedEventArgs)

' configure trace listener for any changes to

EnableTableStorageTraceListener

If e.Changes.OfType(Of

RoleEnvironmentConfigurationSettingChange)().Any(Function(change)

change.ConfigurationSettingName = "EnableTableStorageTraceListener") Then

ConfigureTraceListener()

End If

End Sub

...

End Class

Note: The RoleEnvironmentChanged event handler occurs after a change to the service

configuration has been applied to the running instances of the role. If this change involves the

EnableTableStorageTraceListener configuration setting, the handler calls the

ConfigureTraceListener method to enable or disable the trace listener.

8. Finally, insert the following (highlighted) line into the OnStart method, immediately before to

the call to the base class method, to subscribe to the Changed event of the RoleEnvironment.

C#

public class WebRole : RoleEntryPoint

{

public override bool OnStart()

{

DiagnosticMonitor.Start("DiagnosticsConnectionString");

CloudStorageAccount.SetConfigurationSettingPublisher((configName,

configSetter) =>

{

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

});

Page 21: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 21

ConfigureTraceListener();

// For information on handling configuration changes

// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

RoleEnvironment.Changing += RoleEnvironmentChanging;

RoleEnvironment.Changed += RoleEnvironmentChanged;

return base.OnStart();

}

...

}

Visual Basic

Public Class WebRole

Inherits RoleEntryPoint

Public Overrides Function OnStart() As Boolean

DiagnosticMonitor.Start("DiagnosticsConnectionString")

CloudStorageAccount.SetConfigurationSettingPublisher(Sub(configName,

configSetter)

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))

ConfigureTraceListener()

' For information on handling configuration changes

' see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironmentChanging

AddHandler RoleEnvironment.Changed, AddressOf RoleEnvironmentChanged

Return MyBase.OnStart()

End Function

...

End Class

9. To instrument the application and write diagnostics information to the error log, add a global

error handler to the application. To do this, in Solution Explorer, double-click Global.asax in the

FabrikamInsurance project to open this file and insert the following method into the

MVCApplication class.

(Code Snippet – WindowsAzureDebugging-Ex1-Application_Error-CS)

C#

public class MvcApplication : System.Web.HttpApplication

{

...

Page 22: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 22

protected void Application_Error()

{

var lastError = Server.GetLastError();

System.Diagnostics.Trace.TraceError(lastError.Message);

}

}

(Code Snippet – WindowsAzureDebugging-Ex1-Application_Error-VB)

Visual Basic

Public Class MvcApplication

Inherits System.Web.HttpApplication

...

Protected Sub Application_Error()

Dim lastError = Server.GetLastError()

System.Diagnostics.Trace.TraceError(lastError.Message)

End Sub

End Class

Note: The Application_Error event is raised to catch any unhandled ASP.NET errors while

processing a request. The event handler shown above retrieves a reference to the unhandled

exception object using Server.GetLastError and then uses the TraceError method of the

System.Diagnostics.Trace class to log the error message.

Note that the Trace object outputs the message to each listener in its Listeners collection,

including the TableStorageTraceListener, provided you enable it in the configuration settings.

Typically, the collection also contains instances of the DefaultTraceListener class and, when

executing the solution in the development fabric, the DevelopmentFabricTraceListener. The

latter writes its output to a log that you can view from the development fabric UI.

To write to the Windows Azure diagnostics log, a DiagnosticMonitorTraceListener can also be

added to the Web.config or App.config file of the role. When using this type of trace listener,

the logs are gathered locally in each role. To retrieve them, you first need to instruct the

Diagnostic Monitor to copy the information to Azure Storage. The role project templates

included with the Windows Azure Tools for Microsoft Visual Studio already include the settings

required to use the DiagnosticMonitorTraceListener in the configuration files it generates.

Page 23: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 23

Figure 12

Trace object Listeners collection showing configured trace listeners

10. Open the QuoteController.cs (for Visual C# projects) or QuoteController.vb (for Visual Basic

projects) file in the Controllers folder of the FabrikamInsurance project and add the following

method.

(Code Snippet – WindowsAzureDebugging-Ex1-Controller OnException method-CS)

C#

[HandleError]

public class QuoteController : Controller

{

...

protected override void OnException(ExceptionContext filterContext)

{

System.Diagnostics.Trace.TraceError(filterContext.Exception.Message);

}

}

(Code Snippet – WindowsAzureDebugging-Ex1-Controller OnException method-VB)

Visual Basic

<HandleError()>

Public Class QuoteController

Inherits Controller

...

Protected Overrides Sub OnException(ByVal filterContext As ExceptionContext)

System.Diagnostics.Trace.TraceError(filterContext.Exception.Message)

End Sub

End Class

Page 24: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 24

Note: The OnException method is called when an unhandled exception occurs during the

processing of an action in a controller. For MVC applications, unhandled errors are typically

caught at the controller level, provided they occur during the execution of a controller action

and that the action (or controller) has been decorated with a HandleErrorAttribute. To log

exceptions in controller actions, you need to override the OnException method of the

controller because the Application_Error is bypassed when the error-handling filter catches

the exceptions.

By default, when an action method with the HandleErrorAttribute attribute throws any

exception, MVC displays the Error view that is located in the ~/Views/Shared folder.

11. In addition to error logging, tracing can also be useful for recording other significant events

during the execution of the application. For example, for registering whenever a given

controller action is invoked. To show this feature, insert the following (highlighted) tracing

statement at the start of the Calculator method to log a message whenever this action is called.

C#

public class QuoteController : Controller

{

...

public ActionResult Calculator()

{

System.Diagnostics.Trace.TraceInformation("Calculator called...");

QuoteViewModel model = new QuoteViewModel();

PopulateViewModel(model, null);

return View(model);

}

...

}

Visual Basic

Public Class QuoteController

Inherits Controller

...

Public Function Calculator() As ActionResult

System.Diagnostics.Trace.TraceInformation("Calculator called...")

Dim model As New QuoteViewModel()

PopulateViewModel(model, Nothing)

Return View(model)

End Function

...

End Class

Page 25: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 25

12. Similarly, add a tracing statement to the About action, as shown (highlighted) below.

C#

public class QuoteController : Controller

{

...

public ActionResult About()

{

System.Diagnostics.Trace.TraceInformation("About called...");

return View();

}

...

}

Visual Basic

Public Class QuoteController

Inherits Controller

...

Public Function About() As ActionResult

System.Diagnostics.Trace.TraceInformation("About called...")

Return View()

End Function

...

End Class

Task 4 – Creating a Log Viewer Tool

At this point, the application is ready for tracing and can send all its diagnostics output to a table in

Azure Storage. To view the trace logs, you now create a simple log viewer application that will

periodically query the table and retrieve all entries added since it was last queried.

1. Add a new console application project to the solution. To create the project, in the File menu,

point to Add, and then select New Project. In the Add New Project dialog, expand node for the

language of your choice (Visual C# or Visual Basic) in the Installed Templates tree view, select

the Windows category, and then the Console Application template. Set the name of the project

to LogViewer, accept the proposed location inside the solution folder, and then click OK.

2. Right-click the new LogViewer project in Solution Explorer and select Properties.

For Visual C# projects:

In the properties window, switch to the Application page, and then change the Target

framework to .NET Framework 4.

Page 26: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 26

Figure 13

Configuring the target framework for the project (Visual C#)

For Visual Basic projects:

In the properties window, switch to the Compile page and then click Advanced Compile

Options. In the Advanced Compiler Settings dialog, select .NET Framework 4 in the Target

framework drop down list, and then click OK.

Page 27: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 27

Figure 14

Configuring the target framework for the project (Visual Basic)

Note: The client profile is not suitable in this case because the application will use the

StorageClient API to retrieve log data from table storage. This API relies on functionality

available only in the full .NET Framework 4 distribution.

3. If the Target Framework Change dialog appears, click Yes.

Page 28: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 28

Figure 15

Target Framework Change

4. Add references to the assemblies required by this project. To do this, in Solution Explorer, right-

click the LogViewer project and select Add Reference. In the Add Reference dialog, switch to

the .NET tab and, while holding down the CTRL key to select multiple items, select

System.Configuration, Microsoft.WindowsAzure.StorageClient, and

System.Data.Services.Client, and then click OK.

5. Next, add a reference to the diagnostics project in the solution. Repeat the previous step to

open the Add Reference dialog, only this time select the Projects tab, select the

AzureDiagnostics project and click OK.

6. Add a class to display a simple progress indicator in the console window to the project. To do

this, in Solution Explorer, right-click LogViewer, point to Add, and select Existing Item. In the

Add Existing Item dialog, browse to Assets in the Source folder of the lab, select the folder for

the language of the project (Visual C# or Visual Basic), select the ProgressIndicator.[cs|.vb] file,

and then click Add.

7. In Solution Explorer, double-click Program.cs or Module1.vb to open this file and insert the

following namespace declarations at the top of the file.

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer namespaces-CS)

C#

using System.Configuration;

using System.Data.Services.Client;

using System.Threading;

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.StorageClient;

using AzureDiagnostics;

Page 29: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 29

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer namespaces-VB)

Visual Basic

Imports System.Configuration

Imports System.Data.Services.Client

Imports System.Threading

Imports Microsoft.WindowsAzure

Imports Microsoft.WindowsAzure.StorageClient

Imports AzureDiagnostics

8. For Visual Basic projects only, reformulate the Sub Main making it Public and adding a string

array parameter named args.

(Code Snippet – WindowsAzureDebugging-Ex1-Reformulate Sub Main -VB)

Visual Basic

Module Module1

Public Sub Main(ByVal args() As String)

End Sub

End Module

9. Define the following (highlighted) members in the Program class (for Visual C# projects) or the

Module1 module (for Visual Basic projects).

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer static members-CS)

C#

class Program

{

private static string lastPartitionKey = String.Empty;

private static string lastRowKey = String.Empty;

static void Main(string[] args)

{

}

}

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer static members-VB)

Visual Basic

Module Module1

Page 30: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 30

Private lastPartitionKey As String = String.Empty

Private lastRowKey As String = String.Empty

Public Sub Main(ByVal args() As String)

End Sub

End Module

10. Next, insert the QueryLogTable method into the class or module.

(Code Snippet – WindowsAzureDebugging-Ex1-QueryLogTable method-CS)

C#

class Program

{

...

private static void QueryLogTable(CloudTableClient tableStorage)

{

TableServiceContext context = tableStorage.GetDataServiceContext();

DataServiceQuery query =

context.CreateQuery<LogEntry>(TableStorageTraceListener.DIAGNOSTICS_TABLE)

.Where(entry =>

entry.PartitionKey.CompareTo(lastPartitionKey) > 0

|| (entry.PartitionKey ==

lastPartitionKey && entry.RowKey.CompareTo(lastRowKey) > 0))

as DataServiceQuery;

foreach (AzureDiagnostics.LogEntry entry in query.Execute())

{

Console.WriteLine("{0} - {1}", entry.Timestamp, entry.Message);

lastPartitionKey = entry.PartitionKey;

lastRowKey = entry.RowKey;

}

}

...

}

(Code Snippet – WindowsAzureDebugging-Ex1-QueryLogTable method-VB)

Visual Basic

Module Module1

...

Private Sub QueryLogTable(ByVal tableStorage As CloudTableClient)

Dim context As TableServiceContext = tableStorage.GetDataServiceContext()

Dim query As DataServiceQuery = TryCast(context.CreateQuery(Of

LogEntry)(TableStorageTraceListener.DIAGNOSTICS_TABLE).Where(Function(entry)

Page 31: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 31

entry.PartitionKey.CompareTo(lastPartitionKey) > 0 OrElse (entry.PartitionKey

= lastPartitionKey AndAlso entry.RowKey.CompareTo(lastRowKey) > 0)),

DataServiceQuery)

For Each entry As AzureDiagnostics.LogEntry In query.Execute()

Console.WriteLine("{0} - {1}", entry.Timestamp, entry.Message)

lastPartitionKey = entry.PartitionKey

lastRowKey = entry.RowKey

Next

End Sub

...

End Module

Note: The rows in the diagnostic log table are stored with a primary key composed by the

partition and row key properties, where both are based on the event tick count of the

corresponding log entry and are thus ordered chronologically. The QueryLogTable method

queries the table to retrieve all rows whose primary key value is greater than the last value

obtained during the previous invocation of this method. This ensures that each time it is

called, the method only retrieves new entries added to the log.

11. Finally, to complete the changes, insert the following (highlighted) code into the body of

method Main.

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer Main method-CS)

C#

class Program

{

...

static void Main(string[] args)

{

string connectionString = (args.Length == 0) ?

"DiagnosticsConnectionString" : args[0];

CloudStorageAccount account =

CloudStorageAccount.Parse(ConfigurationManager.AppSettings[connectionString]);

CloudTableClient tableStorage = account.CreateCloudTableClient();

tableStorage.CreateTableIfNotExist(TableStorageTraceListener.DIAGNOSTICS_TABLE

);

Utils.ProgressIndicator progress = new Utils.ProgressIndicator();

Timer timer = new Timer((state) =>

{

progress.Disable();

Page 32: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 32

QueryLogTable(tableStorage);

progress.Enable();

}, null, 0, 10000);

Console.ReadKey(true);

}

}

(Code Snippet – WindowsAzureDebugging-Ex1-LogViewer Main method-VB)

Visual Basic

Module Module1

...

Public Sub Main(ByVal args() As String)

Dim connectionString As String = If((args.Length = 0),

"DiagnosticsConnectionString", args(0))

Dim account As CloudStorageAccount =

CloudStorageAccount.Parse(ConfigurationManager.AppSettings(connectionString))

Dim tableStorage As CloudTableClient = account.CreateCloudTableClient()

tableStorage.CreateTableIfNotExist(TableStorageTraceListener.DIAGNOSTICS_TABLE

)

Dim progress As New ProgressIndicator()

Dim timer As New Timer(Sub(state)

progress.Disable()

QueryLogTable(tableStorage)

progress.Enable()

End Sub, Nothing, 0, 10000)

Console.ReadKey(True)

End Sub

End Module

Note: The inserted code initializes the Azure Storage account information, creates the

diagnostics table if necessary, and then starts a timer that periodically calls the

QueryLogMethod defined in the previous step to display new entries in the diagnostics log.

12. To complete the viewer application, open the App.config file in the LogViewer project and

insert the following (highlighted) appSettings section to define the DiagnosticsConnectionString

setting required to initialize the Windows Azure storage account information.

Page 33: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 33

(Code Snippet – WindowsAzureDebugging-LogViewer DiagnosticConnectionString)

XML

<configuration>

...

<appSettings>

<add key="DiagnosticsConnectionString"

value="UseDevelopmentStorage=true"/>

</appSettings>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />

</startup>

</configuration>

Verification

You are now ready to execute the solution in the development fabric. To enable the Table Storage trace

listener dynamically without stopping the running service, you initially deploy the service with the

EnableTraceStorageTraceListener setting disabled and then, you change the setting in the configuration

file to enable the listener and then upload it to re-configure the running service. Using the log viewer

application, you examine the trace messages produced by the application.

1. Open the Web.config file of the FabrikamInsurance project and insert the following

(highlighted) customErrors section as a direct child of the system.web element.

XML

<configuration>

...

<system.web>

...

<customErrors mode="On" />

</system.web>

...

</configuration>

Note: When you set the customErrors mode to On, ASP.NET displays generic error messages

for both local and remote clients. With customErrors set to its default setting of RemoteOnly,

once the application is deployed to Windows Azure and you access it remotely, you will also

see the generic errors, so this step is not strictly necessary. However, it allows you to

reproduce locally the behavior that you would observe once you deploy the application to the

cloud.

Page 34: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 34

2. To test the solution, you need to configure the cloud service and the log viewer application so

that they both start simultaneously. To define the start up projects, right-click the solution node

in Solution Explorer and select Set StartUp Projects. In the Solution ‘Begin’ Property Pages

window, make sure to select Startup Project under Common Properties, and then select the

option labeled Multiple startup projects. Next, set the Action for both the LogViewer and

FabrikamInsuranceService projects to Start, leaving the remaining projects as None. Click OK to

save the changes to the start-up configuration.

Figure 16

Configuring the start-up projects for the solution

3. Press CTRL + F5 to launch the application without attaching a debugger. Again, this reproduces

the conditions that you would have once you deploy the application to the cloud. Wait until the

deployment completes and the browser opens to show its main page.

4. In the browser window, complete the form making sure that you choose “PORSCHE” for the

Make of the vehicle and “BOXSTER (BAD DATA)” for the Model. Notice that this time, because

you enabled the customErrors setting in the Web.config file, the application shows a generic

error page instead of the exception details that you saw earlier. This is what you would also see

had the application been deployed to Azure.

Page 35: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 35

Figure 17

Application error with customErrors enabled

5. Examine the output from the log viewer application. Notice that, despite the error, the console

window is still empty because the table storage trace listener is currently disabled.

6. Switch back to Visual Studio and, in Solution Explorer, expand the Roles node of the

FabrikamInsuranceService project, and then double-click the FabrikamInsurance role to open

its properties window. Select the Settings page, and then change the value of the

EnableTableStorageTraceListener setting to true.

7. Press CTRL + S to save the changes to the configuration.

8. Open the development fabric console by right-clicking its icon located in the system tray and

selecting Show Development Fabric UI. Record the ID for the current deployment. This is the

numeric value shown enclosed in parenthesis, next to the deployment label.

Page 36: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 36

Figure 18

Development fabric UI showing the current deployment ID

9. Now, open a Windows Azure SDK command prompt from Start | All Programs | Windows

Azure SDK v1.X | Windows Azure SDK Command Prompt. To launch the command prompt as

an administrator, right-click its shortcut in the Start menu and choose Run as administrator.

10. Change the current directory to the location of the FabrikamInsuranceService cloud project

inside the current solution’s folder. This folder contains the service configuration file,

ServiceConfiguration.cscfg.

11. At the command prompt, execute the following command to update the configuration of the

running deployment. Replace the [DEPLOYMENTID] placeholder with the value that you

recorded earlier.

Windows Azure Command Prompt

csrun /update:[DEPLOYMENTID];ServiceConfiguration.cscfg

Page 37: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 37

Figure 19

Updating the configuration of the running service

12. Examine the diagnostics output in the development fabric UI to make sure that the role applied

the configuration changes successfully.

Page 38: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 38

Figure 20

Diagnostics log showing the configuration settings change

Note: For applications deployed to the cloud, you would normally update the configuration of

your running application through the Windows Azure Developer Portal or by using the

Windows Azure Management API to upload a new configuration file.

13. Once you have updated the configuration and enabled the trace listener, return to the browser

window, browse to the Quotes page, and re-enter the same parameters that caused the error

previously (make “PORSCHE”, model “BOXSTER (BAD DATA)”). Then, click Calculate to submit

the form again. The response should still show the error page.

14. Switch to the log viewer window and wait a few seconds until it refreshes. Notice that the

console now shows an entry with the error message for the unhandled exception, showing that

the trace output generated by the running application is written directly to table storage.

Figure 21

Viewer showing the error logged to table storage

15. To view the output from other informational trace messages, return to the browser window

and click About followed by Quotes to execute both actions in the controller. Recall that you

inserted trace messages at the start of each method. Notice that the viewer console now

displays a message for each of these actions.

Page 39: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 39

Figure 22

Viewer showing informational trace messages for the controller actions

16. In the log viewer window, press any key to exit the program.

17. Finally, delete the running deployment in the development fabric. To do this, right-click the

deployment in the Service Deployments tree view and select Remove.

Exercise 2: Using IntelliTrace to Diagnose

Role Start-Up Failures

Trace logs are a useful resource when diagnosing problems in your application. Upon start up, each role

instance is responsible for starting the Diagnostics Monitor for that role, typically during its OnStart

method. However, if a role cannot start successfully and enable the Diagnostics Monitor, this prevents it

from producing logging data that may allow you to determine the cause of the crash. Troubleshooting

this type of problem when an application is running in the cloud and in the absence of any logging

information can be very challenging. Even when logs are available, debugging is considerably easier if

you can browse stack traces, local variables, and exception data.

IntelliTrace (previously known as Historical Debugger) is a new feature available in Visual Studio 2010

Ultimate edition that provides the ability to collect data about an application while it is executing. When

you enable IntelliTrace, it records key code execution and environment data and then allows you to

replay this data from within Visual Studio, stepping through the same code that executes in the cloud.

Page 40: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 40

When you deploy a service to Windows Azure from within Visual Studio, you can enable IntelliTrace

debugging to package the necessary IntelliTrace files along with an agent that Visual Studio will

communicate with to retrieve the IntelliTrace data. Once enabled, IntelliTrace operates in the

background, collecting information about the running service.

You can customize the basic IntelliTrace configuration specifying, which events to log, whether to collect

call information, which modules and processes to collect logs for, and how much space to allocate to the

recording (the default size is 250 MB).

The collected information is saved to an IntelliTrace file, which you can open later to start

troubleshooting the problem. This information lets you step back in time to see what happened in the

application and which events led to a crash.

In this exercise, you explore the use of IntelliTrace to diagnose a role start-up failure while deploying the

Fabrikam Insurance application to Windows Azure.

Important: IntelliTrace debugging is intended for debug scenarios only, and should not be used for a

production deployment.

Note: To complete this exercise, you require a Windows Azure Hosted Service and a Windows Azure

Storage Account. For more information on how to purchase a Windows Azure subscription, visit

http://www.microsoft.com/windowsazure/offers/.

Important: If you are using a 32-bit environment to execute this lab, you need to install a hotfix

identified as KB983301. This hotfix installs the 64-bit IntelliTrace components on your machine

necessary to collect tracing information from the 64-bit Azure instances, allowing the Windows Azure

Tools to deploy an application to Windows Azure with IntelliTrace enabled.

Task 1 – Preparing the Application for Deployment to the Cloud

When you deploy your service using Visual Studio, the Windows Azure Tools upload the service package

and then automatically start it. You will not have a chance to update the configuration settings before

the service starts, so you need to configure the necessary settings before you publish the service.

In this task, you update the storage connection string to point to your Windows Azure storage account.

1. If not already open, launch Microsoft Visual Studio 2010 in elevated administrator mode. To do

this, in Start | All Programs | Microsoft Visual Studio 2010, right-click the Microsoft Visual

Studio 2010 shortcut and choose Run as administrator.

Page 41: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 41

2. In the File menu, choose Open and then Project/Solution. In the Open Project dialog, browse

to Ex2-DebuggingWithIntelliTrace\Begin in the Source folder of the lab, select Begin.sln in the

folder for the language of your preference (Visual C# or Visual Basic) and click Open.

3. In Solution Explorer, expand the Roles node inside the FabrikamInsuranceService cloud project

and then double-click the FabrikamInsurance role.

4. In the FabrikamInsurance [Role] window, switch to the Settings tab, locate the

DiagnosticsConnectionString setting, change its Type to Connection String, and then click the

button labeled with ellipsis on the right. In the Storage Connection String dialog, select the

option labeled Enter storage credentials, type the name and shared key for your Windows

Azure storage account, and then click OK.

Figure 23

Configuring the application for deployment

5. Press CTRL + S to save your changes.

Task 2 – Configuring Visual Studio for Deploying Applications to Windows Azure (Optional)

In this task, you create a management certificate using Visual Studio and then upload it to the Windows

Azure Portal. The procedure described here is necessary to be able to deploy services to Windows Azure

directly from Visual Studio and you only need to complete it once. If you have already configured the

credentials, you may skip this task and continue with Task 3.

1. In Solution Explorer, right-click the FabrikamInsuranceService cloud project and select Publish.

2. In the Publish Cloud Service dialog, you first need to create the necessary credentials to access

your Windows Azure account. First, select the option labeled Deploy your Cloud Service to

Windows Azure. Next, to add a new set of credentials to your configuration, in the Credentials

drop down list, select Add.

Page 42: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 42

Figure 24

Adding Windows Azure account credentials in Visual Studio

3. To create the credentials, you require a certificate. If Visual Studio cannot find a suitable

certificate in your personal certificate store, it will prompt you to create a new one; otherwise,

in the Cloud Service Management Authentication dialog, expand the drop down list labeled

Create or select an existing certificate for authentication and then select Create.

Figure 25

Page 43: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 43

Creating a new certificate for authentication

Note: The drop down list contains all the certificates that are suitable for authentication with

the Azure Management API.

4. In the Create Certificate dialog, enter a suitable name for the certificate, for example,

AzureMgmtVS, and then click OK.

Figure 26

Creating a new management certificate

5. Back in the Cloud Service Management Authentication dialog; ensure that the newly created

certificate is selected. Notice that the issuer for this certificate is the Windows Azure Tools.

Figure 27

Selecting a certificate for the credentials

Page 44: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 44

6. Now, click the link labeled Copy the full path. This copies the path of the certificate public key

file to the clipboard.

Figure 28

Copying the path of the certificate public key file to the clipboard

Note: Visual Studio stores the public key file for the certificate it generates in a temporary

folder inside your local data directory.

7. Click OK to dismiss the confirmation message box and then save the path in the clipboard to a

safe location. You will need this value shortly, when you upload the certificate to the portal.

Figure 29

Page 45: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 45

Confirmation that the file path was copied to the clipboard successfully

8. Next, click the link labeled Developer Portal to open a browser window and navigate to the

Windows Azure Developer portal.

Figure 30

Opening the Developer Portal in your browser

9. At the Windows Azure Developer Portal, sign in using your Windows Live ID.

10. Select the Account tab and then click Manage My API Certificates.

Page 46: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 46

Figure 31

Managing API certificates in the Windows Azure Developer Portal

11. In the API Certificates page, click Browse and make sure to change the file name to the path

that you copied earlier to your clipboard for the public key (.cer) file generated by Visual Studio,

and then click Open to upload the new certificate from your local storage.

Figure 32

Uploading a certificate to the Windows Azure Developer Portal

Page 47: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 47

12. Select the Account tab in the Developer Portal UI and record the value shown for Subscription

ID under Support Information.

Figure 33

Determining the subscription ID for a Windows Azure account

13. To complete the setup of your credentials, switch back to the Cloud Service Management

Authentication dialog, enter your subscription ID and a name to identify the credentials and

then click OK.

Page 48: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 48

Figure 34

Completing the credential setup procedure

14. After you confirm the creation of the new credentials, Visual Studio uses them to access the

management service to verify that the information that you provided is valid and notifies you if

authentication fails. If this occurs, verify the information that you entered and then re-attempt

the operation once again.

Figure 35

Page 49: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 49

Authentication failure while accessing the management service

15. In the Publish Cloud Service dialog, click Cancel. You will restart the publishing process in the

next task.

Task 3 – Deploying the Application with IntelliTrace Enabled

In the previous task, you created a self-signed certificate using Visual Studio and uploaded it to the

Windows Azure Portal. Now, you are ready to deploy the application to the cloud and enable

IntelliTrace.

1. In Solution Explorer, right-click the FabrikamInsuranceService cloud project and select Publish.

2. In the Publish Cloud Service dialog, select the credentials that you created in the previous task.

Figure 36

Deploying a service package to Windows Azure from Visual Studio

3. After you select the credentials, notice that the dialog populates the drop down list labeled

Hosted Service Slot to deploy to with the information for all the services configured in your

Page 50: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 50

Windows Azure account, including production and staging slots for each service. Select the slot

in this list where you wish to deploy the service.

4. Similarly, the dialog populates the drop down list labeled Storage Account to deploy through

with all the storage services that you have configured in your Windows Azure account. To

deploy a service, Visual Studio first uploads the service package to Azure storage, and then

deploys the service from there. Select the storage service that you wish to use for this purpose.

5. Leave the check box labeled Prompt before deleting an existing deployment checked.

6. If you wish, update the Deployment Label to identify the deployment in the Developer Portal

UI.

7. Make sure the check box labeled Enable IntelliTrace for .NET 4 roles is checked. This enables

you to capture detailed trace logs of your running service in the cloud that you can download to

your desktop to perform historical debugging.

Figure 37

Publishing a cloud service package with IntelliTrace enabled

8. Click OK to start the deployment process.

Note: The deployment process is asynchronous so that you can continue to work while you

wait for deployment to complete. You can monitor the progress of the deployment from the

Page 51: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 51

Windows Azure Activity log and the status of the Hosted Service from the Windows Azure

Compute node in the Server Explorer window.

9. After you start the deployment, open the Windows Azure Activity Log window to determine

the status of the operation.

Note: If this window is not visible, in the View menu, point to Other Windows, and then select

Windows Azure Activity Log.

10. To view detailed information about the deployment operation in progress, click the green arrow

on the left of the activity log entry.

Notice that the additional information provided includes the deployment slot, Production or

Staging, the Website URL, the Deployment ID, and a History log that shows state changes,

including the time when each change occurred.

11. Wait for the deployment operation to complete, which may take several minutes. While this is

happening, you can examine the History panel on the right of the Windows Azure Activity Log

window to determine the status of the deployment. Notice that the status of the role instance

shows first as initializing, then busy, and finally as unresponsive, and that the role never starts.

Note: Normally, when a role process exits, the Azure Fabric automatically restarts it, which

causes the cycling role state behavior typically observed when a role crashes during start up.

This is no longer true once you enable IntelliTrace. Instead, when a role process exits, it is put

into an “Unresponsive” state and halted to allow you to retrieve the IntelliTrace logs for the

failing role.

Figure 38

Viewing detailed information about a deployment operation

Page 52: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 52

Task 4 – Examining the IntelliTrace Logs to Determine the Cause of a Failure

In the previous task, the role failed to start due to an unknown reason. In this task, you will use

IntelliTrace to determine what caused the failure.

1. In the Windows Azure Activity Log window, click Open in Server Explorer.

Note: If this window is not currently visible, in the View menu, point to Other Windows, and

then select Windows Azure Activity Log.

Figure 39

Viewing the Windows Azure hosted service in Server Explorer

2. In the Windows Azure Compute node, examine the role instance status of the hosted service

where you deployed the FabrikamInsurance application. Notice that the label for the

deployment slot indicates that IntelliTrace is enabled for this deployment and that the status is

shown as “Unresponsive” here too.

3. Now, right-click the slot node, labeled as Instance 0 (Unresponsive) in Server Explorer, and

then select View IntelliTrace Logs to download the information to your workstation. After you

do this, notice that Visual Studio creates a new IntelliTrace entry in the Windows Azure Activity

Log window to display the progress of the download operation.

Page 53: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 53

Figure 40

Downloading the IntelliTrace logs for a hosted service

4. Wait for the download to complete, which may take several minutes. While this is happening,

you can expand the corresponding entry in the Windows Azure Activity Log window and

examine the History panel on the right to monitor the progress of the operation.

Figure 41

IntelliTrace operation history log

Note: When you request the IntelliTrace logs, a snapshot of the information collected so far is

uploaded from the VM instance where the role is running to Windows Azure storage and then

downloaded to a disk file on your local computer. Once the log is transferred successfully, it is

deleted from Windows Azure storage.

5. After the download completes, Visual Studio automatically opens the IntelliTrace log file and

displays it in a window. The IntelliTrace Summary window is divided into several sections that

contain diagnostics information collected for the deployment.

Page 54: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 54

Figure 42

IntelliTrace summary window

The report in this windows starts with a graphical view that shows a timeline that contains every

thread active during the diagnostics collection period, with each thread showing its ID, a name,

if available, and the starting and ending times of the thread.

Below the graphical thread view, the Threads List shows the same information in textual format.

Page 55: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 55

Figure 43

Threads List section in the IntelliTrace summary window

Other sections available in the IntelliTrace summary window are:

Exceptions – lists unhandled exceptions that occur during the data collection period with details

about the exception type, the exception message, the thread where the exception was raised,

an HResult, if applicable, and the time of the exception. Selecting an entry in the list displays the

corresponding call stack for the exception.

If an exception occurs in your code, you can select the exception in the list and then click Start

Debugging to open the appropriate source file in Visual Studio with the cursor placed on the line

of code that raised the exception.

Page 56: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 56

Figure 44

Exception Data section in the IntelliTrace summary window

System Info – shows information about the virtual machine environment where the diagnostics

data was collected, including the computer name, operating system and CLR versions, physical

memory and virtual memory available, number of processors, time zone, among other details.

Page 57: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 57

Figure 45

System Info section in the IntelliTrace summary window

Modules – lists every module loaded in memory, including the name of the module and the

path from where it was loaded. This information can be useful to debug assembly-loading

issues.

Page 58: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 58

Figure 46

Module section in the IntelliTrace summary window

Note: There is a search box above each section in the IntelliTrace summary window. If you are

looking for a specific module or exception, just start typing into the Search box to narrow

down the results shown in the list.

6. Pick an exception under Exception Data or a thread under Threads List and then click Start

Debugging.

7. In the Debug menu, point to IntelliTrace, and then select IntelliTrace Events. The events

window lists the events captured while the application was running in Windows Azure. Note

that you can filter the events in this list by category and/or thread to focus in any particular

combination that may interest you.

Page 59: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 59

Figure 47

Viewing IntelliTrace event data

For the current deployment, you used default settings to define the events captured by

IntelliTrace. During a deployment operation, click Settings in the Publish Cloud Service dialog to

open the IntelliTrace Settings window to configure which events should be included in the

IntelliTrace log.

Page 60: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 60

Figure 48

Configuring IntelliTrace settings before deploying a service package

8. To determine what caused the role to fail during start up in the previous task, expand the

Exception Data section on the summary page and examine the list of exceptions.

Page 61: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 61

Figure 49

Viewing exception data in the IntelliTrace summary window

In general, this list contains multiple exceptions, some of which may be ignored as they are

handled by the runtime environment and do not cause the role to crash. There is no precise rule

regarding which exceptions are normal and can be ignored, so you will typically review the list to

identify potentially fatal exceptions. You will find that examining IntelliTrace logs for successful

deployments will enhance your ability to discriminate significant entries in this list.

Notice that the list includes a FileNotFoundException with the message “Could not load file or

assembly System.Web.Mvc…”. This exception indicates that the role was unable to locate the

System.Web.Mvc assembly required by the application and is, in fact, the reason why the role

could not start successfully earlier. These types of error are common and very difficult to

diagnose in the cloud, especially when you cannot reproduce them locally because all the

required dependencies are already present in your development environment.

Page 62: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 62

In the following task, you will fix the problem and re-deploy the service package.

Note: In general, you need to set Copy Local = True for any assembly that is not installed by

default in the Windows Azure VMs to ensure that it is deployed with your application.

Task 5 – Fixing the Application and Re-Deploying (Optional)

Now that you identified the cause of the role start up failure as a missing assembly, you can correct the

problem and re-deploy the application.

In this task, you add the missing assembly to the service package and re-deploy it to Windows Azure.

1. Ensure that the System.Web.Mvc assembly is included in the service package that you deploy

to Windows Azure. To do this, for a Visual C# project, expand the References node for the

FabrikamInsurance project in Solution Explorer, right-click the System.Web.Mvc assembly and

select Properties.

For a Visual Basic project, right-click the FabrikamInsurance project and select Properties. In the

Project Properties window, switch to the References tab, select the System.Web.Mvc assembly,

and press F4.

Figure 50

Opening the properties window for the System.Web.Mvc assembly reference (C#)

2. To add the assembly to the service package, in the Properties window for the System.Web.Mvc

assembly, change the value of the Copy Local setting to True.

Page 63: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 63

Figure 51

Including an assembly in the service package deployed to Windows Azure

3. In Solution Explorer, right-click the FabrikamInsuranceService cloud project and select Publish.

4. In the Publish Cloud Service dialog, leave the IntelliTrace option enabled and then click OK to

start the deployment process one more time. You may wish to change the Deployment Label to

identify the deployment as the one that contains the bug fix.

Page 64: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 64

Figure 52

Deploying the updated cloud service

Note: if a deployment operation is already in progress, go to the Windows Azure Activity Log,

right-click the corresponding entry, and then select Cancel and remove before publishing a

new deployment.

5. Because the slot that you chose is already occupied by the previous deployment, Visual Studio

warns you and asks for confirmation before it deletes it. Click Delete and Continue to overwrite

the current deployment.

6. Wait for the deployment operation to complete, which may take several minutes.

Figure 53

Viewing detailed information about a deployment operation

Page 65: Hands-On Labaz12722.vo.msecnd.net/.../Labs/WindowsAzureDebugging/Lab.pdfPage | 5 Exercises This hands-on lab includes the following exercises: 1. Debugging an Application in the Cloud

Page | 65

7. Once the deployment is ready, in the Windows Azure Activity Log window, click the Website

URL link for the deployment operation to open the application in your browser.

8. Test the application and ensure that it is working properly.

9. You may download the IntelliTrace log for the running application and compare it with the log

that you obtained earlier, when the application failed to start. This will increase your ability to

recognize which exceptions are normal.

Summary

By completing this hands-on lab, you learnt how to apply simple debugging techniques to troubleshoot

your Windows Azure application once you deploy it to the cloud. You saw how to use standard .NET

diagnostics to write diagnostics output directly into table storage with a custom trace listener. Using

IntelliTrace, you quickly diagnosed a role that failed to start due to a missing dependency; an error that

would otherwise have been very difficult to diagnose in the cloud.