Troubleshoot an app in Azure App Service using Visual Studio
Note
This article is for Visual Studio 2019. For troubleshooting in Visual Studio 2022, see Remote Debug ASP.NET Core on Azure App Service.
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.
If you aren't already signed in to Azure in Visual Studio, right-click Azure and select Connect to 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 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.
In Server Explorer, expand Azure and expand App Service.
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.
The Azure Web App tab appears, and you can see there the app management and configuration tasks that are available in Visual Studio.
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:
An error occurred:
The website cannot display the page
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.
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.
Expand the Files node, and double-click the Web.config file.
Visual Studio opens the Web.config file from the remote app and shows [Remote] next to the file name in the title bar.
Add the following line to the
system.web
element:<customErrors mode="Off"></customErrors>
Refresh the browser that is showing the unhelpful error message, and now you get a detailed error message, such as the following example:
(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.
Open the web project that you created in Create an ASP.NET app in Azure App Service.
Open Controllers\HomeController.cs.
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(); }
Set a breakpoint on the
ViewBag.Message
line.In Solution Explorer, right-click the project, and click Publish.
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.
In the Publish dialog, click the Settings tab, and then change Configuration to Debug, and then click Save.
Click Publish. After deployment finishes and your browser opens to the Azure URL of your app, close the browser.
In Server Explorer, right-click your app, and then click 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.
Click About in the menu.
Visual Studio stops on the breakpoint, and the code is running in Azure, not on your local computer.
Hover over the
currentTime
variable to see the time value.The time you see is the Azure server time, which may be in a different time zone than your local computer.
Enter a new value for the
currentTime
variable, such as "Now running in Azure".Press F5 to continue running.
The About page running in Azure displays the new value that you entered into the currentTime variable.
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.
Open the web project that you created in Get Started with the Azure WebJobs SDK.
In the ContosoAdsWebJob project, open Functions.cs.
Set a breakpoint on the first statement in the
GenerateThumbnail
method.In Solution Explorer, right-click the web project (not the WebJob project), and click Publish.
In the Profile drop-down list, select the same profile that you used in Get Started with the Azure WebJobs SDK.
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.
In Server Explorer, expand Azure > App Service > your resource group > your app > WebJobs > Continuous, and then right-click ContosoAdsWebJob.
Click 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.
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.
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.Press F5 to continue running.
The
GenerateThumbnail
method finishes creating the thumbnail.In the browser, refresh the Index page and you see the thumbnail.
In Visual Studio, press SHIFT+F5 to stop debugging.
In Server Explorer, right-click the ContosoAdsWebJob node and click View Dashboard.
Sign in with your Azure credentials, and then click the WebJob name to go to the page for your WebJob.
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.)
Click the function name to see details about the function execution.
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 thecompilation
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
Open Controllers\HomeController.cs, and replace the
Index
,About
, andContact
methods with the following code in order to addTrace
statements and ausing
statement forSystem.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(); }
Add a
using System.Diagnostics;
statement to the top of the file.
View the tracing output locally
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.The following steps show how to view trace output in a web page, without compiling in debug mode.
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
.
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" />
Press CTRL+F5 to run the application.
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
).On the Application Trace page, click View Details on the first line (not the BrowserLink 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.By default,
trace.axd
is only available locally. If you wanted to make it available from a remote app, you could addlocalOnly="false"
to thetrace
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
In Solution Explorer, right-click the web project and click Publish.
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).
In Server Explorer, right-click your app and select View Streaming Logs.
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.
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.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:
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.
In Server Explorer, right-click the app, and then click View Settings as you did earlier.
Change Application Logging (File System) to Verbose, and then click Save.
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.
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 Azure Logs tab of the Output Window has several buttons and a text box:
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.
In the Azure Web App Configuration tab that you opened from Server Explorer, change Web Server Logging to On, and then click Save.
In the Output Window, click the Specify which Azure logs to monitor button.
In the Azure Logging Options dialog box, select Web server logs, and then click OK.
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.
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.
In the Azure Web App Configuration tab that you opened from Server Explorer, change Detailed Error Messages to On, and then click Save.
In the Output Window, click the Specify which Azure logs to monitor button.
In the Azure Logging Options dialog box, click All logs, and then click OK.
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.
Control+click the link to see the log output formatted in a browser:
Download file system logs
Any logs that you can monitor in the Output window can also be downloaded as a .zip file.
In the Output window, click Download Streaming Logs.
File Explorer opens to your Downloads folder with the downloaded file selected.
Extract the .zip file, and you see the following folder structure:
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.
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.
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.
In Visual Studio, in the Configuration tab of the Azure Web App window, click Open in Management Portal.
In the Azure portal Settings page for your app, click Deployment credentials, and then enter a new 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".
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.
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.
Open the LogFiles folder.
Open the folder that is named W3SVC plus a numeric value.
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.
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.
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:
- How to monitor apps
- Investigating Memory Leaks in Azure App Service with Visual Studio 2013. Azure ALM blog post about Visual Studio features for analyzing managed memory issues.
- Azure App Service online tools you should know about. Blog post by Amit Apple.
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:
- Introduction to Remote Debugging Azure App Service.
- Introduction to Remote Debugging Azure App Service part 2 - Inside Remote debugging
- Introduction to Remote Debugging on Azure App Service part 3 - Multi-Instance environment and GIT
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:
Monitoring and Telemetry (Building Real-World Cloud Apps with Azure).
E-book chapter with recommendations for tracing in Azure cloud applications.ASP.NET Tracing
Old but still a good resource for a basic introduction to the subject.Trace Listeners
Information about trace listeners but doesn't mention the WebPageTraceListener.Walkthrough: Integrating ASP.NET Tracing with System.Diagnostics Tracing
This article is also old, but includes some additional information that the introductory article doesn't cover.Tracing in ASP.NET MVC Razor Views
Besides tracing in Razor views, the post also explains how to create an error filter in order to log all unhandled exceptions in an MVC application. For information about how to log all unhandled exceptions in a Web Forms application, see the Global.asax example in Complete Example for Error Handlers on MSDN. In either MVC or Web Forms, if you want to log certain exceptions but let the default framework handling take effect for them, you can catch and rethrow as in the following example:try { // Your code that might cause an exception to be thrown. } catch (Exception ex) { Trace.TraceError("Exception: " + ex.ToString()); throw; }
Streaming Diagnostics Trace Logging from the Azure Command Line (plus Glimpse!)
How to use the command line to do what this tutorial shows how to do in Visual Studio. Glimpse is a tool for debugging ASP.NET applications.
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:
- LogParser
A tool for viewing data in web server logs (.log files). - Troubleshooting IIS Performance Issues or Application Errors using LogParser
An introduction to the Log Parser tool that you can use to analyze web server logs. - Blog posts by Robert McMurray on using LogParser
- The HTTP status code in IIS 7.0, IIS 7.5, and IIS 8.0
Analyzing failed request tracing logs
The Azure 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.