Troubleshoot an app in Azure App Service using Visual Studio

Overview

This tutorial shows how to use Visual Studio tools to help debug an app in App Service, by running in debug mode remotely or by viewing application logs and web server logs.

You'll learn:

  • Which app management functions are available in Visual Studio.
  • How to use Visual Studio remote view to make quick changes in a remote app.
  • How to run debug mode remotely while a project is running in Azure, both for an app and for a WebJob.
  • How to create application trace logs and view them while the application is creating them.
  • How to view web server logs, including detailed error messages and failed request tracing.
  • How to send diagnostic logs to an Azure Storage account and view them there.

If you have Visual Studio Ultimate, you can also use IntelliTrace for debugging. IntelliTrace is not covered in this tutorial.

Prerequisites

This tutorial works with the development environment, web project, and App Service app that you set up in Create an ASP.NET app in Azure App Service. For the WebJobs sections, you'll need the application that you create in Get Started with the Azure WebJobs SDK.

The code samples shown in this tutorial are for a C# MVC web application, but the troubleshooting procedures are the same for Visual Basic and Web Forms applications.

The tutorial assumes you're using Visual Studio 2019.

The streaming logs feature only works for applications that target .NET Framework 4 or later.

App configuration and management

Visual Studio provides access to a subset of the app management functions and configuration settings available in the Azure portal. In this section, you'll see what's available by using Server Explorer. To see the latest Azure integration features, try out Cloud Explorer also. You can open both windows from the View menu.

  1. If you aren't already signed in to Azure in Visual Studio, right-click Azure and select Connect to Microsoft Azure Subscription in Server Explorer.

    An alternative is to install a management certificate that enables access to your account. If you choose to install a certificate, right-click the Azure node in Server Explorer, and then select Manage and Filter Subscriptions in the context menu. In the Manage Microsoft Azure Subscriptions dialog box, click the Certificates tab, and then click Import. Follow the directions to download and then import a subscription file (also called a .publishsettings file) for your Azure account.

    Note

    If you download a subscription file, save it to a folder outside your source code directories (for example, in the Downloads folder), and then delete it once the import has completed. A malicious user who gains access to the subscription file can edit, create, and delete your Azure services.

    For more information about connecting to Azure resources from Visual Studio, see Assign Azure roles using the Azure portal.

  2. In Server Explorer, expand Azure and expand App Service.

  3. Expand the resource group that includes the app that you created in Create an ASP.NET app in Azure App Service, and then right-click the app node and click View Settings.

    View Settings in Server Explorer

    The Azure Web App tab appears, and you can see there the app management and configuration tasks that are available in Visual Studio.

    Azure Web App window

    In this tutorial, you'll use the logging and tracing drop-downs. You'll also use remote debugging but you'll use a different method to enable it.

    For information about the App Settings and Connection Strings boxes in this window, see Azure App Service: How Application Strings and Connection Strings Work.

    If you want to perform an app management task that can't be done in this window, click Open in Management Portal to open a browser window to the Azure portal.

Access app files in Server Explorer

You typically deploy a web project with the customErrors flag in the Web.config file set to On or RemoteOnly, which means you don't get a helpful error message when something goes wrong. For many errors, all you get is a page like one of the following ones:

Server Error in '/' Application:

Screenshot showing a Server Error in '/' Application error in a web browser.

An error occurred:

Screenshot showing an example of a generic error occurring in a web browser.

The website cannot display the page

Screenshot showing a message that reads **The website cannot display the page error in a web browser**.

Frequently the easiest way to find the cause of the error is to enable detailed error messages, which the first of the preceding screenshots explains how to do. That requires a change in the deployed Web.config file. You could edit the Web.config file in the project and redeploy the project, or create a Web.config transform and deploy a debug build, but there's a quicker way: in Solution Explorer, you can directly view and edit files in the remote app by using the remote view feature.

  1. In Server Explorer, expand Azure, expand App Service, expand the resource group that your app is located in, and then expand the node for your app.

    You see nodes that give you access to the app's content files and log files.

  2. Expand the Files node, and double-click the Web.config file.

    Open Web.config

    Visual Studio opens the Web.config file from the remote app and shows [Remote] next to the file name in the title bar.

  3. Add the following line to the system.web element:

    <customErrors mode="Off"></customErrors>

    Edit Web.config

  4. Refresh the browser that is showing the unhelpful error message, and now you get a detailed error message, such as the following example:

    Detailed error message

    (The error shown was created by adding the line shown in red to Views\Home\Index.cshtml.)

Editing the Web.config file is only one example of scenarios in which the ability to read and edit files on your App Service app make troubleshooting easier.

Remote debugging apps

If the detailed error message doesn't provide enough information, and you can't re-create the error locally, another way to troubleshoot is to run in debug mode remotely. You can set breakpoints, manipulate memory directly, step through code, and even change the code path.

Remote debugging does not work in Express editions of Visual Studio.

This section shows how to debug remotely using the project you create in Create an ASP.NET app in Azure App Service.

  1. Open the web project that you created in Create an ASP.NET app in Azure App Service.

  2. Open Controllers\HomeController.cs.

  3. Delete the About() method and insert the following code in its place.

    public ActionResult About()
    {
        string currentTime = DateTime.Now.ToLongTimeString();
        ViewBag.Message = "The current time is " + currentTime;
        return View();
    }
    
  4. Set a breakpoint on the ViewBag.Message line.

  5. In Solution Explorer, right-click the project, and click Publish.

  6. In the Profile drop-down list, select the same profile that you used in Create an ASP.NET app in Azure App Service. Then, click Settings.

  7. In the Publish dialog, click the Settings tab, and then change Configuration to Debug, and then click Save.

    Publish in debug mode

  8. Click Publish. After deployment finishes and your browser opens to the Azure URL of your app, close the browser.

  9. In Server Explorer, right-click your app, and then click Attach Debugger.

    Screenshot of the Server Explorer window showing an app selected and then clicking Attach Debugger.

    The browser automatically opens to your home page running in Azure. You might have to wait 20 seconds or so while Azure sets up the server for debugging. This delay only happens the first time you run in debug mode on an app in a 48-hour period. When you start debugging again in the same period, there isn't a delay.

    Note

    If you have any trouble starting the debugger, try to do it by using Cloud Explorer instead of Server Explorer.

  10. Click About in the menu.

    Visual Studio stops on the breakpoint, and the code is running in Azure, not on your local computer.

  11. Hover over the currentTime variable to see the time value.

    View variable in debug mode running in Azure

    The time you see is the Azure server time, which may be in a different time zone than your local computer.

  12. Enter a new value for the currentTime variable, such as "Now running in Azure".

  13. Press F5 to continue running.

    The About page running in Azure displays the new value that you entered into the currentTime variable.

    About page with new value

Remote debugging WebJobs

This section shows how to debug remotely using the project and app you create in Get Started with the Azure WebJobs SDK.

The features shown in this section are available only in Visual Studio 2013 with Update 4 or later.

Remote debugging only works with continuous WebJobs. Scheduled and on-demand WebJobs don't support debugging.

  1. Open the web project that you created in Get Started with the Azure WebJobs SDK.

  2. In the ContosoAdsWebJob project, open Functions.cs.

  3. Set a breakpoint on the first statement in the GenerateThumbnail method.

    Set breakpoint

  4. In Solution Explorer, right-click the web project (not the WebJob project), and click Publish.

  5. In the Profile drop-down list, select the same profile that you used in Get Started with the Azure WebJobs SDK.

  6. Click the Settings tab, and change Configuration to Debug, and then click Publish.

    Visual Studio deploys the web and WebJob projects, and your browser opens to the Azure URL of your app.

  7. In Server Explorer, expand Azure > App Service > your resource group > your app > WebJobs > Continuous, and then right-click ContosoAdsWebJob.

  8. Click Attach Debugger.

    Screenshot of Server Explorer showing ContosoAdsWebJob selected in the drop-down menu and Attach Debugger selected.

    The browser automatically opens to your home page running in Azure. You might have to wait 20 seconds or so while Azure sets up the server for debugging. This delay only happens the first time you run in debug mode on an app in a 48-hour period. When you start debugging again in the same period, there isn't a delay.

  9. In the web browser that is opened to the Contoso Ads home page, create a new ad.

    Creating an ad causes a queue message to be created, which is picked up by the WebJob and processed. When the WebJobs SDK calls the function to process the queue message, the code hits your breakpoint.

  10. When the debugger breaks at your breakpoint, you can examine and change variable values while the program is running the cloud. In the following illustration, the debugger shows the contents of the blobInfo object that was passed to the GenerateThumbnail method.

    blobInfo object in debugger

  11. Press F5 to continue running.

    The GenerateThumbnail method finishes creating the thumbnail.

  12. In the browser, refresh the Index page and you see the thumbnail.

  13. In Visual Studio, press SHIFT+F5 to stop debugging.

  14. In Server Explorer, right-click the ContosoAdsWebJob node and click View Dashboard.

  15. Sign in with your Azure credentials, and then click the WebJob name to go to the page for your WebJob.

    Click ContosoAdsWebJob

    The Dashboard shows that the GenerateThumbnail function executed recently.

    (The next time you click View Dashboard, you don't have to sign in, and the browser goes directly to the page for your WebJob.)

  16. Click the function name to see details about the function execution.

    Function details

If your function wrote logs, you could click ToggleOutput to see them.

Notes about remote debugging

  • Running in debug mode in production is not recommended. If your production app is not scaled out to multiple server instances, debugging prevents the web server from responding to other requests. If you do have multiple web server instances, when you attach to the debugger, you get a random instance, and you have no way to ensure that subsequent browser requests go to the same instance. Also, you typically don't deploy a debug build to production, and compiler optimizations for release builds might make it impossible to show what is happening line by line in your source code. For troubleshooting production problems, your best resource is application tracing and web server logs.

  • Avoid long stops at breakpoints when remote debugging. Azure treats a process that is stopped for longer than a few minutes as an unresponsive process, and shuts it down.

  • While you're debugging, the server is sending data to Visual Studio, which could affect bandwidth charges. For information about bandwidth rates, see Azure Pricing.

  • Make sure that the debug attribute of the compilation element in the Web.config file is set to true. It is set to true by default when you publish a debug build configuration.

    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
    
  • If you find that the debugger doesn't step into the code that you want to debug, you might have to change the Just My Code setting. For more information, see Specify whether to debug only user code using Just My Code in Visual Studio.

  • A timer starts on the server when you enable the remote debugging feature, and after 48 hours the feature is automatically turned off. This 48-hour limit is done for security and performance reasons. You can easily turn the feature back on as many times as you like. We recommend leaving it disabled when you are not actively debugging.

  • You can manually attach the debugger to any process, not only the app process (w3wp.exe). For more information about how to use debug mode in Visual Studio, see Debugging in Visual Studio.

Diagnostic logs overview

An ASP.NET application that runs in an App Service app can create the following kinds of logs:

  • Application tracing logs
    The application creates these logs by calling methods of the System.Diagnostics.Trace class.
  • Web server logs
    The web server creates a log entry for every HTTP request to the app.
  • Detailed error message logs
    The web server creates an HTML page with some additional information for failed HTTP requests (requests that result in status code 400 or greater).
  • Failed request tracing logs
    The web server creates an XML file with detailed tracing information for failed HTTP requests. The web server also provides an XSL file to format the XML in a browser.

Logging affects app performance, so Azure gives you the ability to enable or disable each type of log as needed. For application logs, you can specify that only logs above a certain severity level should be written. When you create a new app, by default all logging is disabled.

Logs are written to files in a LogFiles folder in the file system of your app and are accessible via FTP. Web server logs and application logs can also be written to an Azure Storage account. You can retain a greater volume of logs in a storage account than is possible in the file system. You're limited to a maximum of 100 megabytes of logs when you use the file system. (File system logs are only for short-term retention. Azure deletes old log files to make room for new ones after the limit is reached.)

Create and view application trace logs

In this section, you do the following tasks:

  • Add tracing statements to the web project that you created in Get started with Azure and ASP.NET.
  • View the logs when you run the project locally.
  • View the logs as they are generated by the application running in Azure.

For information about how to create application logs in WebJobs, see How to work with Azure queue storage using the WebJobs SDK - How to write logs. The following instructions for viewing logs and controlling how they're stored in Azure apply also to application logs created by WebJobs.

Add tracing statements to the application

  1. Open Controllers\HomeController.cs, and replace the Index, About, and Contact methods with the following code in order to add Trace statements and a using statement for System.Diagnostics:

    public ActionResult Index()
    {
        Trace.WriteLine("Entering Index method");
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
        Trace.TraceInformation("Displaying the Index page at " + DateTime.Now.ToLongTimeString());
        Trace.WriteLine("Leaving Index method");
        return View();
    }
    
    public ActionResult About()
    {
        Trace.WriteLine("Entering About method");
        ViewBag.Message = "Your app description page.";
        Trace.TraceWarning("Transient error on the About page at " + DateTime.Now.ToShortTimeString());
        Trace.WriteLine("Leaving About method");
        return View();
    }
    
    public ActionResult Contact()
    {
        Trace.WriteLine("Entering Contact method");
        ViewBag.Message = "Your contact page.";
        Trace.TraceError("Fatal error on the Contact page at " + DateTime.Now.ToLongTimeString());
        Trace.WriteLine("Leaving Contact method");
        return View();
    }        
    
  2. Add a using System.Diagnostics; statement to the top of the file.

View the tracing output locally

  1. Press F5 to run the application in debug mode.

    The default trace listener writes all trace output to the Output window, along with other Debug output. The following illustration shows the output from the trace statements that you added to the Index method.

    Tracing in Debug window

    The following steps show how to view trace output in a web page, without compiling in debug mode.

  2. Open the application Web.config file (the one located in the project folder) and add a <system.diagnostics> element at the end of the file just before the closing </configuration> element:

    <system.diagnostics>
    <trace>
      <listeners>
        <add name="WebPageTraceListener"
            type="System.Web.WebPageTraceListener,
            System.Web,
            Version=4.0.0.0,
            Culture=neutral,
            PublicKeyToken=b03f5f7f11d50a3a" />
      </listeners>
    </trace>
    </system.diagnostics>
    

The WebPageTraceListener lets you view trace output by browsing to /trace.axd.

  1. Add a trace element under <system.web> in the Web.config file, such as the following example:

    <trace enabled="true" writeToDiagnosticsTrace="true" mostRecent="true" pageOutput="false" />
    
  2. Press CTRL+F5 to run the application.

  3. In the address bar of the browser window, add trace.axd to the URL, and then press Enter (the URL is similar to http://localhost:53370/trace.axd).

  4. On the Application Trace page, click View Details on the first line (not the BrowserLink line).

    Screenshot of the Application Trace page in a web browser showing View Details selected on the first line.

    The Request Details page appears, and in the Trace Information section you see the output from the trace statements that you added to the Index method.

    Screenshot of the Request Details page in a web browser showing a message highlighted in the Trace Information section.

    By default, trace.axd is only available locally. If you wanted to make it available from a remote app, you could add localOnly="false" to the trace element in the Web.config file, as shown in the following example:

    <trace enabled="true" writeToDiagnosticsTrace="true" localOnly="false" mostRecent="true" pageOutput="false" />
    

    However, enabling trace.axd in a production app is not recommended for security reasons. In the following sections, you'll see an easier way to read tracing logs in an App Service app.

View the tracing output in Azure

  1. In Solution Explorer, right-click the web project and click Publish.

  2. In the Publish Web dialog box, click Publish.

    After Visual Studio publishes your update, it opens a browser window to your home page (assuming you didn't clear Destination URL on the Connection tab).

  3. In Server Explorer, right-click your app and select View Streaming Logs.

    Screenshot of Server Explorer after right-clicking your app, with View Streaming Logs selected in a new window.

    The Output window shows that you are connected to the log-streaming service, and adds a notification line each minute that goes by without a log to display.

    Screenshot of the Output window showing an example of a connection to a log-streaming service with notification lines.

  4. In the browser window that shows your application home page, click Contact.

    Within a few seconds, the output from the error-level trace you added to the Contact method appears in the Output window.

    Error trace in Output window

    Visual Studio is only showing error-level traces because that is the default setting when you enable the log monitoring service. When you create a new App Service app, all logging is disabled by default, as you saw when you opened the settings page earlier:

    Application Logging off

    However, when you selected View Streaming Logs, Visual Studio automatically changed Application Logging(File System) to Error, which means error-level logs get reported. In order to see all of your tracing logs, you can change this setting to Verbose. When you select a severity level lower than error, all logs for higher severity levels are also reported. So when you select verbose, you also see information, warning, and error logs.

  5. In Server Explorer, right-click the app, and then click View Settings as you did earlier.

  6. Change Application Logging (File System) to Verbose, and then click Save.

    Setting trace level to Verbose

  7. In the browser window that is now showing your Contact page, click Home, then click About, and then click Contact.

    Within a few seconds, the Output window shows all of your tracing output.

    Verbose trace output

    In this section, you enabled and disabled logging by using app settings. You can also enable and disable trace listeners by modifying the Web.config file. However, modifying the Web.config file causes the app domain to recycle, while enabling logging via the app configuration doesn't do that. If the problem takes a long time to reproduce, or is intermittent, recycling the app domain might "fix" it and force you to wait until it happens again. Enabling diagnostics in Azure lets you start capturing error information immediately without recycling the app domain.

Output window features

The Microsoft Azure Logs tab of the Output Window has several buttons and a text box:

Screenshot showing the buttons and text box of the Microsoft Azure Logs tab in the Output window.

These perform the following functions:

  • Clear the Output window.
  • Enable or disable word wrap.
  • Start or stop monitoring logs.
  • Specify which logs to monitor.
  • Download logs.
  • Filter logs based on a search string or a regular expression.
  • Close the Output window.

If you enter a search string or regular expression, Visual Studio filters logging information at the client. That means you can enter the criteria after the logs are displayed in the Output window and you can change filtering criteria without having to regenerate the logs.

View web server logs

Web server logs record all HTTP activity for the app. In order to see them in the Output window, you must enable them for the app and tell Visual Studio that you want to monitor them.

  1. In the Azure Web App Configuration tab that you opened from Server Explorer, change Web Server Logging to On, and then click Save.

    Enable web server logging

  2. In the Output Window, click the Specify which Microsoft Azure logs to monitor button.

    Specify which Azure logs to monitor

  3. In the Microsoft Azure Logging Options dialog box, select Web server logs, and then click OK.

    Monitor web server logs

  4. In the browser window that shows the app, click Home, then click About, and then click Contact.

    The application logs generally appear first, followed by the web server logs. You might have to wait a while for the logs to appear.

    Web server logs in Output window

By default, when you first enable web server logs by using Visual Studio, Azure writes the logs to the file system. As an alternative, you can use the Azure portal to specify that web server logs should be written to a blob container in a storage account.

If you use the portal to enable web server logging to an Azure storage account, and then disable logging in Visual Studio, when you re-enable logging in Visual Studio your storage account settings are restored.

View detailed error message logs

Detailed error logs provide some additional information about HTTP requests that result in error response codes (400 or above). In order to see them in the Output window, you have to enable them for the app and tell Visual Studio that you want to monitor them.

  1. In the Azure Web App Configuration tab that you opened from Server Explorer, change Detailed Error Messages to On, and then click Save.

    Enable detailed error messages

  2. In the Output Window, click the Specify which Microsoft Azure logs to monitor button.

  3. In the Microsoft Azure Logging Options dialog box, click All logs, and then click OK.

    Monitor all logs

  4. In the address bar of the browser window, add an extra character to the URL to cause a 404 error (for example, http://localhost:53370/Home/Contactx), and press Enter.

    After several seconds, the detailed error log appears in the Visual Studio Output window.

    Detailed error log - Output window

    Control+click the link to see the log output formatted in a browser:

    Detailed error log - browser window

Download file system logs

Any logs that you can monitor in the Output window can also be downloaded as a .zip file.

  1. In the Output window, click Download Streaming Logs.

    Screenshot of the Output window showing the Download Streaming Logs button highlighted.

    File Explorer opens to your Downloads folder with the downloaded file selected.

    Screenshot of the Downloads folder in File Explorer with a downloaded file selected.

  2. Extract the .zip file, and you see the following folder structure:

    Screenshot of the .zip file folder structure after the file has been extracted.

    • Application tracing logs are in .txt files in the LogFiles\Application folder.

    • Web server logs are in .log files in the LogFiles\http\RawLogs folder. You can use a tool such as Log Parser to view and manipulate these files.

    • Detailed error message logs are in .html files in the LogFiles\DetailedErrors folder.

      (The deployments folder is for files created by source control publishing; it doesn't have anything related to Visual Studio publishing. The Git folder is for traces related to source control publishing and the log file streaming service.)

View failed request tracing logs

Failed request tracing logs are useful when you need to understand the details of how IIS is handling an HTTP request, in scenarios such as URL rewriting or authentication problems.

App Service apps use the same failed request tracing functionality that has been available with IIS 7.0 and later. You don't have access to the IIS settings that configure which errors get logged, however. When you enable failed request tracing, all errors are captured.

You can enable failed request tracing by using Visual Studio, but you can't view them in Visual Studio. These logs are XML files. The streaming log service only monitors files that are deemed readable in plain text mode: .txt, .html, and .log files.

You can view failed request tracing logs in a browser directly via FTP or locally after using an FTP tool to download them to your local computer. In this section, you'll view them in a browser directly.

  1. In the Configuration tab of the Azure Web App window that you opened from Server Explorer, change Failed Request Tracing to On, and then click Save.

    Enable failed request tracing

  2. In the address bar of the browser window that shows the app, add an extra character to the URL and click Enter to cause a 404 error.

    This causes a failed request tracing log to be created, and the following steps show how to view or download the log.

  3. In Visual Studio, in the Configuration tab of the Azure Web App window, click Open in Management Portal.

  4. In the Azure portal Settings page for your app, click Deployment credentials, and then enter a new user name and password.

    New FTP user name and password

    Note

    When you log in, you have to use the full user name with the app name prefixed to it. For example, if you enter "myid" as a user name and the site is "myexample", you log in as "myexample\myid".

  5. In a new browser window, go to the URL that is shown under FTP hostname or FTPS hostname in the Overview page for your app.

  6. Sign in using the FTP credentials that you created earlier (including the app name prefix for the user name).

    The browser shows the root folder of the app.

  7. Open the LogFiles folder.

    Open LogFiles folder

  8. Open the folder that is named W3SVC plus a numeric value.

    Open W3SVC folder

    The folder contains XML files for any errors that have been logged after you enabled failed request tracing, and an XSL file that a browser can use to format the XML.

    W3SVC folder

  9. Click the XML file for the failed request that you want to see tracing information for.

    The following illustration shows part of the tracing information for a sample error.

    Failed request tracing in browser

Next Steps

You've seen how Visual Studio makes it easy to view logs created by an App Service app. The following sections provide links to more resources on related topics:

  • App Service troubleshooting
  • Debugging in Visual Studio
  • Remote debugging in Azure
  • Tracing in ASP.NET applications
  • Analyzing web server logs
  • Analyzing failed request tracing logs
  • Debugging Cloud Services

App Service troubleshooting

For more information about troubleshooting apps in Azure App Service, see the following resources:

For help with a specific troubleshooting question, start a thread in one of the following forums:

Debugging in Visual Studio

For more information about how to use debug mode in Visual Studio, see Debugging in Visual Studio and Debugging Tips with Visual Studio 2010.

Remote debugging in Azure

For more information about remote debugging for App Service apps and WebJobs, see the following resources:

If your app uses an Azure Web API or Mobile Services back-end and you need to debug that, see Debugging .NET Backend in Visual Studio.

Tracing in ASP.NET applications

There are no thorough and up-to-date introductions to ASP.NET tracing available on the Internet. The best you can do is get started with old introductory materials written for Web Forms because MVC didn't exist yet, and supplement that with newer blog posts that focus on specific issues. Some good places to start are the following resources:

For error logging, an alternative to writing your own tracing code is to use an open-source logging framework such as ELMAH. For more information, see Scott Hanselman's blog posts about ELMAH.

Also, you don't need to use ASP.NET or System.Diagnostics tracing to get streaming logs from Azure. The App Service app streaming log service streams any .txt, .html, or .log file that it finds in the LogFiles folder. Therefore, you could create your own logging system that writes to the file system of the app, and your file is automatically streamed and downloaded. All you have to do is write application code that creates files in the d:\home\logfiles folder.

Analyzing web server logs

For more information about analyzing web server logs, see the following resources:

Analyzing failed request tracing logs

The Microsoft TechNet website includes a Using Failed Request Tracing section, which may be helpful for understanding how to use these logs. However, this documentation focuses mainly on configuring failed request tracing in IIS, which you can't do in Azure App Service.