Debug snapshots on exceptions in .NET apps

When an exception occurs, you can automatically collect a debug snapshot from your live web application. The snapshot shows the state of source code and variables at the moment the exception was thrown. The Snapshot Debugger (preview) in Azure Application Insights monitors exception telemetry from your web app. It collects snapshots on your top-throwing exceptions so that you have the information you need to diagnose issues in production. Include the Snapshot collector NuGet package in your application, and optionally configure collection parameters in ApplicationInsights.config. Snapshots appear on exceptions in the Application Insights portal.

You can view debug snapshots in the portal to see the call stack and inspect variables at each call stack frame. To get a more powerful debugging experience with source code, open snapshots with Visual Studio 2017 Enterprise by downloading the Snapshot Debugger extension for Visual Studio. In Visual Studio you can also set Snappoints to interactively take snapshots without waiting for an exception.

Snapshot collection is available for:

  • .NET Framework and ASP.NET applications running .NET Framework 4.5 or later.
  • .NET Core 2.0 and ASP.NET Core 2.0 applications running on Windows.

Configure snapshot collection for ASP.NET applications

  1. Enable Application Insights in your web app, if you haven't done it yet.

  2. Include the Microsoft.ApplicationInsights.SnapshotCollector NuGet package in your app.

  3. Review the default options that the package added to ApplicationInsights.config:

    <TelemetryProcessors>
        <Add Type="Microsoft.ApplicationInsights.SnapshotCollector.SnapshotCollectorTelemetryProcessor, Microsoft.ApplicationInsights.SnapshotCollector">
        <!-- The default is true, but you can disable Snapshot Debugging by setting it to false -->
        <IsEnabled>true</IsEnabled>
        <!-- Snapshot Debugging is usually disabled in developer mode, but you can enable it by setting this to true. -->
        <!-- DeveloperMode is a property on the active TelemetryChannel. -->
        <IsEnabledInDeveloperMode>false</IsEnabledInDeveloperMode>
        <!-- How many times we need to see an exception before we ask for snapshots. -->
        <ThresholdForSnapshotting>5</ThresholdForSnapshotting>
        <!-- The maximum number of examples we create for a single problem. -->
        <MaximumSnapshotsRequired>3</MaximumSnapshotsRequired>
        <!-- The maximum number of problems that we can be tracking at any time. -->
        <MaximumCollectionPlanSize>50</MaximumCollectionPlanSize>
        <!-- How often to reset problem counters. -->
        <ProblemCounterResetInterval>06:00:00</ProblemCounterResetInterval>
        <!-- The maximum number of snapshots allowed in one minute. -->
        <SnapshotsPerMinuteLimit>2</SnapshotsPerMinuteLimit>
        <!-- The maximum number of snapshots allowed per day. -->
        <SnapshotsPerDayLimit>50</SnapshotsPerDayLimit>
        </Add>
    </TelemetryProcessors>
    
  4. Snapshots are collected only on exceptions that are reported to Application Insights. In some cases (for example, older versions of the .NET platform), you might need to configure exception collection to see exceptions with snapshots in the portal.

Configure snapshot collection for ASP.NET Core 2.0 applications

  1. Enable Application Insights in your ASP.NET Core web app, if you haven't done it yet.

Note

Be sure that your application references version 2.1.1, or newer, of the Microsoft.ApplicationInsights.AspNetCore package.

  1. Include the Microsoft.ApplicationInsights.SnapshotCollector NuGet package in your app.

  2. Modify your application's Startup class to add and configure the Snapshot Collector's telemetry processor.

    using Microsoft.ApplicationInsights.SnapshotCollector;
    using Microsoft.Extensions.Options;
    ...
    class Startup
    {
        private class SnapshotCollectorTelemetryProcessorFactory : ITelemetryProcessorFactory
        {
            private readonly IServiceProvider _serviceProvider;
    
            public SnapshotCollectorTelemetryProcessorFactory(IServiceProvider serviceProvider) =>
                _serviceProvider = serviceProvider;
    
            public ITelemetryProcessor Create(ITelemetryProcessor next)
            {
                var snapshotConfigurationOptions = _serviceProvider.GetService<IOptions<SnapshotCollectorConfiguration>>();
                return new SnapshotCollectorTelemetryProcessor(next, configuration: snapshotConfigurationOptions.Value);
            }
        }
    
        public Startup(IConfiguration configuration) => Configuration = configuration;
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Configure SnapshotCollector from application settings
            services.Configure<SnapshotCollectorConfiguration>(Configuration.GetSection(nameof(SnapshotCollectorConfiguration)));
    
            // Add SnapshotCollector telemetry processor.
            services.AddSingleton<ITelemetryProcessorFactory>(sp => new SnapshotCollectorTelemetryProcessorFactory(sp));
    
            // TODO: Add other services your application needs here.
        }
    }
    
  3. Configure the Snapshot Collector by adding a SnapshotCollectorConfiguration section to appsettings.json. For example:

    {
      "ApplicationInsights": {
        "InstrumentationKey": "<your instrumentation key>"
      },
      "SnapshotCollectorConfiguration": {
        "IsEnabledInDeveloperMode": true
      }
    }
    

Configure snapshot collection for other .NET applications

  1. If your application is not already instrumented with Application Insights, get started by enabling Application Insights and setting the instrumentation key.

  2. Add the Microsoft.ApplicationInsights.SnapshotCollector NuGet package in your app.

  3. Snapshots are collected only on exceptions that are reported to Application Insights. You may need to modify your code to report them. The exception handling code depends on the structure of your application, but an example is below:

    TelemetryClient _telemetryClient = new TelemetryClient();
    
    void ExampleRequest()
    {
        try
        {
            // TODO: Handle the request.
        }
        catch (Exception ex)
        {
            // Report the exception to Application Insights.
            _telemetryClient.TrackException(ex);
    
            // TODO: Rethrow the exception if desired.
        }
    }
    

Grant permissions

Owners of the Azure subscription can inspect snapshots. Other users must be granted permission by an owner.

To grant permission, assign the Application Insights Snapshot Debugger role to users who will inspect snapshots. This role can be assigned to individual users or groups by subscription owners for the target Application Insights resource or its resource group or subscription.

  1. Open the Access Control (IAM) blade.
  2. Click the +Add button.
  3. Select Application Insights Snapshot Debugger from the Roles drop-down list.
  4. Search for and enter a name for the user to add.
  5. Click the Save button to add the user to the role.

[!IMPORTANT] Snapshots can potentially contain personal and other sensitive information in variable and parameter values.

Debug snapshots in the Application Insights portal

If a snapshot is available for a given exception or a problem ID, an Open Debug Snapshot button appears on the exception in the Application Insights portal.

Open Debug Snapshot button on exception

In the Debug Snapshot view, you see a call stack and a variables pane. When you select frames of the call stack in the call stack pane, you can view local variables and parameters for that function call in the variables pane.

View Debug Snapshot in the portal

Snapshots might contain sensitive information, and by default they are not viewable. To view snapshots, you must have the Application Insights Snapshot Debugger role assigned to you.

Debug snapshots with Visual Studio 2017 Enterprise

  1. Click the Download Snapshot button to download a .diagsession file, which can be opened by Visual Studio 2017 Enterprise.

  2. To open the .diagsession file, you must first download and install the Snapshot Debugger extension for Visual Studio.

  3. After you open the snapshot file, the Minidump Debugging page in Visual Studio appears. Click Debug Managed Code to start debugging the snapshot. The snapshot opens to the line of code where the exception was thrown so that you can debug the current state of the process.

    View debug snapshot in Visual Studio

The downloaded snapshot contains any symbol files that were found on your web application server. These symbol files are required to associate snapshot data with source code. For App Service apps, make sure to enable symbol deployment when you publish your web apps.

How snapshots work

When your application starts, a separate snapshot uploader process is created that monitors your application for snapshot requests. When a snapshot is requested, a shadow copy of the running process is made in about 10 to 20 milliseconds. The shadow process is then analyzed, and a snapshot is created while the main process continues to run and serve traffic to users. The snapshot is then uploaded to Application Insights along with any relevant symbol (.pdb) files that are needed to view the snapshot.

Current limitations

Publish symbols

The Snapshot Debugger requires symbol files on the production server to decode variables and to provide a debugging experience in Visual Studio. The 15.2 release of Visual Studio 2017 publishes symbols for release builds by default when it publishes to App Service. In prior versions, you need to add the following line to your publish profile .pubxml file so that symbols are published in release mode:

    <ExcludeGeneratedDebugSymbol>False</ExcludeGeneratedDebugSymbol>

For Azure Compute and other types, ensure that the symbol files are in the same folder of the main application .dll (typically, wwwroot/bin) or are available on the current path.

Optimized builds

In some cases, local variables cannot be viewed in release builds because of optimizations that are applied during the build process.

Troubleshooting

These tips help you troubleshoot problems with the Snapshot Debugger.

Verify the instrumentation key

Make sure that you're using the correct instrumentation key in your published application. Usually, Application Insights reads the instrumentation key from the ApplicationInsights.config file. Verify that the value is the same as the instrumentation key for the Application Insights resource that you see in the portal.

Check the uploader logs

After a snapshot is created, a minidump file (.dmp) is created on disk. A separate uploader process takes that minidump file and uploads it, along with any associated PDBs, to Application Insights Snapshot Debugger storage. After the minidump has uploaded successfully, it is deleted from disk. The log files for the minidump uploader are retained on disk. In an App Service environment, you can find these logs in D:\Home\LogFiles\Uploader_*.log. Use the Kudu management site for App Service to find these log files.

  1. Open your App Service application in the Azure portal.

  2. Select the Advanced Tools blade, or search for Kudu.

  3. Click Go.
  4. In the Debug console drop-down list box, select CMD.
  5. Click LogFiles.

You should see at least one file with a name that begins with Uploader_ and a .log extension. Click the appropriate icon to download any log files or open them in a browser. The file name includes the machine name. If your App Service instance is hosted on more than one machine, there are separate log files for each machine. When the uploader detects a new minidump file, it is recorded in the log file. Here's an example of a successful upload:

MinidumpUploader.exe Information: 0 : Dump available 139e411a23934dc0b9ea08a626db16c5.dmp
    DateTime=2017-05-25T14:25:08.0349846Z
MinidumpUploader.exe Information: 0 : Uploading D:\local\Temp\Dumps\c12a605e73c44346a984e00000000000\139e411a23934dc0b9ea08a626db16c5.dmp, 329.12 MB
    DateTime=2017-05-25T14:25:16.0145444Z
MinidumpUploader.exe Information: 0 : Upload successful.
    DateTime=2017-05-25T14:25:42.9164120Z
MinidumpUploader.exe Information: 0 : Extracting PDB info from D:\local\Temp\Dumps\c12a605e73c44346a984e00000000000\139e411a23934dc0b9ea08a626db16c5.dmp.
    DateTime=2017-05-25T14:25:42.9164120Z
MinidumpUploader.exe Information: 0 : Matched 2 PDB(s) with local files.
    DateTime=2017-05-25T14:25:44.2310982Z
MinidumpUploader.exe Information: 0 : Stamp does not want any of our matched PDBs.
    DateTime=2017-05-25T14:25:44.5435948Z
MinidumpUploader.exe Information: 0 : Deleted D:\local\Temp\Dumps\c12a605e73c44346a984e00000000000\139e411a23934dc0b9ea08a626db16c5.dmp
    DateTime=2017-05-25T14:25:44.6095821Z

In the previous example, the instrumentation key is c12a605e73c44346a984e00000000000. This value should match the instrumentation key for your application. The minidump is associated with a snapshot with the ID 139e411a23934dc0b9ea08a626db16c5. You can use this ID later to locate the associated exception telemetry in Application Insights Analytics.

The uploader scans for new PDBs about once every 15 minutes. Here's an example:

MinidumpUploader.exe Information: 0 : PDB rescan requested.
    DateTime=2017-05-25T15:11:38.8003886Z
MinidumpUploader.exe Information: 0 : Scanning D:\home\site\wwwroot\ for local PDBs.
    DateTime=2017-05-25T15:11:38.8003886Z
MinidumpUploader.exe Information: 0 : Scanning D:\local\Temporary ASP.NET Files\root\a6554c94\e3ad6f22\assembly\dl3\81d5008b\00b93cc8_dec5d201 for local PDBs.
    DateTime=2017-05-25T15:11:38.8160276Z
MinidumpUploader.exe Information: 0 : Local PDB scan complete. Found 2 PDB(s).
    DateTime=2017-05-25T15:11:38.8316450Z
MinidumpUploader.exe Information: 0 : Deleted PDB scan marker D:\local\Temp\Dumps\c12a605e73c44346a984e00000000000\.pdbscan.
    DateTime=2017-05-25T15:11:38.8316450Z

For applications that are not hosted in App Service, the uploader logs are in the same folder as the minidumps: %TEMP%\Dumps\<ikey> (where <ikey> is your instrumentation key).

Use Application Insights search to find exceptions with snapshots

When a snapshot is created, the throwing exception is tagged with a snapshot ID. When the exception telemetry is reported to Application Insights, that snapshot ID is included as a custom property. Using the Search blade in Application Insights, you can find all telemetry with the ai.snapshot.id custom property.

  1. Browse to your Application Insights resource in the Azure portal.
  2. Click Search.
  3. Type ai.snapshot.id in the Search text box and press Enter.

Search for telemetry with a snapshot ID in the portal

If this search returns no results, then no snapshots were reported to Application Insights for your application in the selected time range.

To search for a specific snapshot ID from the Uploader logs, type that ID in the Search box. If you can't find telemetry for a snapshot that you know was uploaded, follow these steps:

  1. Double-check that you're looking at the right Application Insights resource by verifying the instrumentation key.

  2. Using the timestamp from the Uploader log, adjust the Time Range filter of the search to cover that time range.

If you still don't see an exception with that snapshot ID, then the exception telemetry wasn't reported to Application Insights. This situation can happen if your application crashed after it took the snapshot but before it reported the exception telemetry. In this case, check the App Service logs under Diagnose and solve problems to see if there were unexpected restarts or unhandled exceptions.

Next steps