Edit

Share via


Application Insights for ASP.NET and ASP.NET Core applications

Caution

We recommend the Azure Monitor OpenTelemetry Distro for new applications or customers to power Azure Monitor Application Insights. The Azure Monitor OpenTelemetry Distro delivers a similar functionality and experience as the Application Insights SDK. It's possible to migrate from the Application Insights SDK using the migration guides for .NET, Node.js, and Python, but we are still working to add a few more features for backwards compatibility.

This article explains how to enable and configure Application Insights for ASP.NET and ASP.NET Core applications to send telemetry. Application Insights can collect the following telemetry from your apps:

  • Requests
  • Dependencies
  • Exceptions
  • Performance counters
  • Traces (Logs)
  • Heartbeats
  • Custom events & metrics (requires manual instrumentation)
  • Page views (requires JavaScript SDK for webpages)
  • Availability tests (requires manually setting up availability tests)

Supported scenarios

Note

The Application Insights SDK for ASP.NET Core can monitor your applications no matter where or how they run. If your application is running and has network connectivity to Azure, telemetry can be collected. Application Insights monitoring is supported everywhere .NET Core is supported.

Supported ASP.NET ASP.NET Core
Operating system Windows Windows, Linux, or macOS
Hosting method In-process (IIS or IIS Express) In process or out of process
Deployment method Web Deploy, MSI, or manual file copy Framework dependent or self-contained
Web server Internet Information Services (IIS) Internet Information Server (IIS) or Kestrel
Hosting platform Azure App Service (Windows), Azure Virtual Machines, or on-premises servers The Web Apps feature of Azure App Service, Azure Virtual Machines, Docker, and Azure Kubernetes Service (AKS)
.NET version .NET Framework 4.6.1 and later All officially supported .NET versions that aren't in preview
IDE Visual Studio Visual Studio, Visual Studio Code, or command line

Add Application Insights

Prerequisites

Create a basic web app

If you don't have a functioning web application yet, you can use the following guidance to create one.

Note

We use an MVC application example. If you're using the Worker Service, use the instructions in Application Insights for Worker Service applications.

  1. Open Visual Studio.
  2. Select Create a new project.
  3. Choose ASP.NET Web Application (.NET Framework) with C# and select Next.
  4. Enter a Project name, then select Create.
  5. Choose MVC, then select Create.

Add Application Insights automatically (Visual Studio)

This section guides you through automatically adding Application Insights to a template-based web app.

From within your ASP.NET web app project in Visual Studio:

  1. Select Project > Add Application Insights Telemetry > Application Insights Sdk (local) > Next > Finish > Close.

  2. Open the ApplicationInsights.config file.

  3. Before the closing </ApplicationInsights> tag, add a line that contains the connection string for your Application Insights resource. Find your connection string on the overview pane of the newly created Application Insights resource.

    <ConnectionString>Copy connection string from Application Insights Resource Overview</ConnectionString>
    
  4. Select Project > Manage NuGet Packages > Updates. Then update each Microsoft.ApplicationInsights NuGet package to the latest stable release.

  5. Run your application by selecting IIS Express. A basic ASP.NET app opens. As you browse through the pages on the site, telemetry is sent to Application Insights.

Add Application Insights manually (no Visual Studio)

This section guides you through manually adding Application Insights to a template-based web app.

  1. Add the following NuGet packages and their dependencies to your project:

  2. In some cases, the ApplicationInsights.config file is created for you automatically. If the file is already present, skip to step 4.

    Create it yourself if it's missing. In the root directory of an ASP.NET application, create a new file called ApplicationInsights.config.

  3. Copy the following XML configuration into your newly created file:

    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
      <TelemetryInitializers>
        <Add Type="Microsoft.ApplicationInsights.DependencyCollector.HttpDependenciesParsingTelemetryInitializer, Microsoft.AI.DependencyCollector" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.BuildInfoConfigComponentVersionTelemetryInitializer, Microsoft.AI.WindowsServer" />
        <Add Type="Microsoft.ApplicationInsights.Web.WebTestTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.SyntheticUserAgentTelemetryInitializer, Microsoft.AI.Web">
          <!-- Extended list of bots:
                search|spider|crawl|Bot|Monitor|BrowserMob|BingPreview|PagePeeker|WebThumb|URL2PNG|ZooShot|GomezA|Google SketchUp|Read Later|KTXN|KHTE|Keynote|Pingdom|AlwaysOn|zao|borg|oegp|silk|Xenu|zeal|NING|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|Java|JNLP|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|vortex|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|voyager|archiver|Icarus6j|mogimogi|Netvibes|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|wsr-agent|http client|Python-urllib|AppEngine-Google|semanticdiscovery|facebookexternalhit|web/snippet|Google-HTTP-Java-Client-->
          <Filters>search|spider|crawl|Bot|Monitor|AlwaysOn</Filters>
        </Add>
        <Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.AzureAppServiceRoleNameFromHostNameHeaderInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.OperationCorrelationTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.UserTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.AuthenticatedUserIdTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.AccountIdTelemetryInitializer, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.SessionTelemetryInitializer, Microsoft.AI.Web" />
      </TelemetryInitializers>
      <TelemetryModules>
        <Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
          <ExcludeComponentCorrelationHttpHeadersOnDomains>
            <!-- 
            Requests to the following hostnames will not be modified by adding correlation headers.
            Add entries here to exclude additional hostnames.
            NOTE: this configuration will be lost upon NuGet upgrade.
            -->
            <Add>core.windows.net</Add>
            <Add>core.chinacloudapi.cn</Add>
            <Add>core.cloudapi.de</Add>
            <Add>core.usgovcloudapi.net</Add>
          </ExcludeComponentCorrelationHttpHeadersOnDomains>
          <IncludeDiagnosticSourceActivities>
            <Add>Microsoft.Azure.EventHubs</Add>
            <Add>Azure.Messaging.ServiceBus</Add>
          </IncludeDiagnosticSourceActivities>
        </Add>
        <Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
          <!--
          Use the following syntax here to collect additional performance counters:
    
          <Counters>
            <Add PerformanceCounter="\Process(??APP_WIN32_PROC??)\Handle Count" ReportAs="Process handle count" />
            ...
          </Counters>
    
          PerformanceCounter must be either \CategoryName(InstanceName)\CounterName or \CategoryName\CounterName
    
          NOTE: performance counters configuration will be lost upon NuGet upgrade.
    
          The following placeholders are supported as InstanceName:
            ??APP_WIN32_PROC?? - instance name of the application process for Win32 counters.
            ??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters.
            ??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters.
          -->
        </Add>
        <Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryModule, Microsoft.AI.PerfCounterCollector" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.AppServicesHeartbeatTelemetryModule, Microsoft.AI.WindowsServer" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureInstanceMetadataTelemetryModule, Microsoft.AI.WindowsServer">
          <!--
          Remove individual fields collected here by adding them to the ApplicationInsighs.HeartbeatProvider
          with the following syntax:
    
          <Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights">
            <ExcludedHeartbeatProperties>
              <Add>osType</Add>
              <Add>___location</Add>
              <Add>name</Add>
              <Add>offer</Add>
              <Add>platformFaultDomain</Add>
              <Add>platformUpdateDomain</Add>
              <Add>publisher</Add>
              <Add>sku</Add>
              <Add>version</Add>
              <Add>vmId</Add>
              <Add>vmSize</Add>
              <Add>subscriptionId</Add>
              <Add>resourceGroupName</Add>
              <Add>placementGroupId</Add>
              <Add>tags</Add>
              <Add>vmScaleSetName</Add>
            </ExcludedHeartbeatProperties>
          </Add>
    
          NOTE: exclusions will be lost upon upgrade.
          -->
        </Add>
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule, Microsoft.AI.WindowsServer" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.UnhandledExceptionTelemetryModule, Microsoft.AI.WindowsServer" />
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.UnobservedExceptionTelemetryModule, Microsoft.AI.WindowsServer">
          <!--</Add>
        <Add Type="Microsoft.ApplicationInsights.WindowsServer.FirstChanceExceptionStatisticsTelemetryModule, Microsoft.AI.WindowsServer">-->
        </Add>
        <Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web">
          <Handlers>
            <!-- 
            Add entries here to filter out additional handlers:
    
            NOTE: handler configuration will be lost upon NuGet upgrade.
            -->
            <Add>Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler</Add>
            <Add>System.Web.StaticFileHandler</Add>
            <Add>System.Web.Handlers.AssemblyResourceLoader</Add>
            <Add>System.Web.Optimization.BundleHandler</Add>
            <Add>System.Web.Script.Services.ScriptHandlerFactory</Add>
            <Add>System.Web.Handlers.TraceHandler</Add>
            <Add>System.Web.Services.Discovery.DiscoveryRequestHandler</Add>
            <Add>System.Web.HttpDebugHandler</Add>
          </Handlers>
        </Add>
        <Add Type="Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule, Microsoft.AI.Web" />
        <Add Type="Microsoft.ApplicationInsights.Web.AspNetDiagnosticTelemetryModule, Microsoft.AI.Web" />
      </TelemetryModules>
      <ApplicationIdProvider Type="Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId.ApplicationInsightsApplicationIdProvider, Microsoft.ApplicationInsights" />
      <TelemetrySinks>
        <Add Name="default">
          <TelemetryProcessors>
            <Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryProcessor, Microsoft.AI.PerfCounterCollector" />
            <Add Type="Microsoft.ApplicationInsights.Extensibility.AutocollectedMetricsExtractor, Microsoft.ApplicationInsights" />
            <Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
              <MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
              <ExcludedTypes>Event</ExcludedTypes>
            </Add>
            <Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
              <MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
              <IncludedTypes>Event</IncludedTypes>
            </Add>
            <!--
              Adjust the include and exclude examples to specify the desired semicolon-delimited types. (Dependency, Event, Exception, PageView, Request, Trace)
            -->
          </TelemetryProcessors>
          <TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel" />
        </Add>
      </TelemetrySinks>
      <!-- 
        Learn more about Application Insights configuration with ApplicationInsights.config here:
        http://go.microsoft.com/fwlink/?LinkID=513840
      -->
      <ConnectionString>Copy the connection string from your Application Insights resource</ConnectionString>
    </ApplicationInsights>
    
  4. Add the connection string, which can be done in two ways:

    • (Recommended) Set the connection string in configuration.

      Before the closing </ApplicationInsights> tag in ApplicationInsights.config, add the connection string for your Application Insights resource. You can find your connection string on the overview pane of the newly created Application Insights resource.

      <ConnectionString>Copy the connection string from your Application Insights resource</ConnectionString>
      
    • Set the connection string in code.

      Provide a connection string in your program.cs class.

      var configuration = new TelemetryConfiguration
      {
          ConnectionString = "Copy the connection string from your Application Insights resource"
      };
      
  5. At the same level of your project as the ApplicationInsights.config file, create a folder called ErrorHandler with a new C# file called AiHandleErrorAttribute.cs. The contents of the file look like this:

    using System;
    using System.Web.Mvc;
    using Microsoft.ApplicationInsights;
    
    namespace WebApplication10.ErrorHandler //namespace will vary based on your project name
    {
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
        public class AiHandleErrorAttribute : HandleErrorAttribute
        {
            public override void OnException(ExceptionContext filterContext)
            {
                if (filterContext != null && filterContext.HttpContext != null && filterContext.Exception != null)
                {
                    //If customError is Off, then AI HTTPModule will report the exception
                    if (filterContext.HttpContext.IsCustomErrorEnabled)
                    {   
                        var ai = new TelemetryClient();
                        ai.TrackException(filterContext.Exception);
                    } 
                }
                base.OnException(filterContext);
            }
        }
    }
    
  6. In the App_Start folder, open the FilterConfig.cs file and change it to match the sample:

    using System.Web;
    using System.Web.Mvc;
    
    namespace WebApplication10 //Namespace will vary based on project name
    {
        public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new ErrorHandler.AiHandleErrorAttribute());
            }
        }
    }
    
  7. If Web.config is already updated, skip this step. Otherwise, update the file as follows:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      https://go.microsoft.com/fwlink/?LinkId=301880
      -->
    <configuration>
      <appSettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2" />
        <!-- Code added for Application Insights start -->
        <httpModules>
          <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" />
          <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
        </httpModules>
        <!-- Code added for Application Insights end -->
      </system.web>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
            <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
            <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
          </dependentAssembly>
          <!-- Code added for Application Insights start -->
          <dependentAssembly>
            <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
          </dependentAssembly>
          <!-- Code added for Application Insights end -->
        </assemblyBinding>
      </runtime>
      <system.codedom>
        <compilers>
          <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
          <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
        </compilers>
      </system.codedom>
      <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <!-- Code added for Application Insights start -->
        <modules>
          <remove name="TelemetryCorrelationHttpModule" />
          <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="managedHandler" />
          <remove name="ApplicationInsightsWebTracking" />
          <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
        </modules>
        <!-- Code added for Application Insights end -->
      </system.webServer>
    </configuration>
    

At this point, you successfully configured server-side application monitoring. If you run your web app, you see telemetry begin to appear in Application Insights.

Verify Application Insights receives telemetry

Run your application and make requests to it. Telemetry should now flow to Application Insights. The Application Insights SDK automatically collects incoming web requests to your application, along with the following telemetry.

Explore your telemetry

In this section

Live metrics

Live metrics can be used to quickly verify if application monitoring with Application Insights is configured correctly. Telemetry can take a few minutes to appear in the Azure portal, but the live metrics pane shows CPU usage of the running process in near real time. It can also show other telemetry like requests, dependencies, and traces.

Note

Live metrics are enabled by default when you onboard it by using the recommended instructions for .NET applications.

Enable live metrics by using code for any .NET application

To manually configure live metrics:

  1. Install the NuGet package Microsoft.ApplicationInsights.PerfCounterCollector.

  2. The following sample console app code shows setting up live metrics:

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using System;
using System.Threading.Tasks;

namespace LiveMetricsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a TelemetryConfiguration instance.
            TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
            config.InstrumentationKey = "INSTRUMENTATION-KEY-HERE";
            QuickPulseTelemetryProcessor quickPulseProcessor = null;
            config.DefaultTelemetrySink.TelemetryProcessorChainBuilder
                .Use((next) =>
                {
                    quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
                    return quickPulseProcessor;
                })
                .Build();

            var quickPulseModule = new QuickPulseTelemetryModule();

            // Secure the control channel.
            // This is optional, but recommended.
            quickPulseModule.AuthenticationApiKey = "YOUR-API-KEY-HERE";
            quickPulseModule.Initialize(config);
            quickPulseModule.RegisterTelemetryProcessor(quickPulseProcessor);

            // Create a TelemetryClient instance. It is important
            // to use the same TelemetryConfiguration here as the one
            // used to set up live metrics.
            TelemetryClient client = new TelemetryClient(config);

            // This sample runs indefinitely. Replace with actual application logic.
            while (true)
            {
                // Send dependency and request telemetry.
                // These will be shown in live metrics.
                // CPU/Memory Performance counter is also shown
                // automatically without any additional steps.
                client.TrackDependency("My dependency", "target", "http://sample",
                    DateTimeOffset.Now, TimeSpan.FromMilliseconds(300), true);
                client.TrackRequest("My Request", DateTimeOffset.Now,
                    TimeSpan.FromMilliseconds(230), "200", true);
                Task.Delay(1000).Wait();
            }
        }
    }
}

Traces (logs)

Application Insights captures logs from ASP.NET Core and other .NET apps through ILogger, and from classic ASP.NET (.NET Framework) through the classic SDK and adapters.

Tip

Note

To review frequently asked questions (FAQ), see Logging with .NET FAQ.

ILogger guidance doesn’t apply to ASP.NET. To send trace logs from classic ASP.NET apps to Application Insights, use supported adapters such as:

  • System.Diagnostics.Trace with Application Insights TraceListener
  • log4net or NLog with official Application Insights targets

For detailed steps and configuration examples, see Send trace logs to Application Insights.

Console application

To add Application Insights logging to console applications, first install the following NuGet packages:

The following example uses the Microsoft.Extensions.Logging.ApplicationInsights package and demonstrates the default behavior for a console application. The Microsoft.Extensions.Logging.ApplicationInsights package should be used in a console application or whenever you want a bare minimum implementation of Application Insights without the full feature set such as metrics, distributed tracing, sampling, and telemetry initializers.

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using var channel = new InMemoryChannel();

try
{
    IServiceCollection services = new ServiceCollection();
    services.Configure<TelemetryConfiguration>(config => config.TelemetryChannel = channel);
    services.AddLogging(builder =>
    {
        // Only Application Insights is registered as a logger provider
        builder.AddApplicationInsights(
            configureTelemetryConfiguration: (config) => config.ConnectionString = "<YourConnectionString>",
            configureApplicationInsightsLoggerOptions: (options) => { }
        );
    });

    IServiceProvider serviceProvider = services.BuildServiceProvider();
    ILogger<Program> logger = serviceProvider.GetRequiredService<ILogger<Program>>();

    logger.LogInformation("Logger is working...");
}
finally
{
    // Explicitly call Flush() followed by Delay, as required in console apps.
    // This ensures that even if the application terminates, telemetry is sent to the back end.
    channel.Flush();

    await Task.Delay(TimeSpan.FromMilliseconds(1000));
}

For more information, see What Application Insights telemetry type is produced from ILogger logs? Where can I see ILogger logs in Application Insights?.

Logging scopes

Note

The following guidance applies to ILogger scenarios (ASP.NET Core and console only). It doesn’t apply to classic ASP.NET.

ApplicationInsightsLoggingProvider supports log scopes, which are enabled by default.

If the scope is of type IReadOnlyCollection<KeyValuePair<string,object>>, then each key/value pair in the collection is added to the Application Insights telemetry as custom properties. In the following example, logs are captured as TraceTelemetry and have ("MyKey", "MyValue") in properties.

using (_logger.BeginScope(new Dictionary<string, object> { ["MyKey"] = "MyValue" }))
{
    _logger.LogError("An example of an Error level message");
}

If any other type is used as a scope, it gets stored under the property Scope in Application Insights telemetry. In the following example, TraceTelemetry has a property called Scope that contains the scope.

using (_logger.BeginScope("hello scope"))
{
    _logger.LogError("An example of an Error level message");
}

Find your logs

ILogger logs appear as trace telemetry (table traces in Application Insights and AppTraces in Log Analytics).

Example

In the Azure portal, go to Application Insights and run:

traces
| where severityLevel >= 2 // 2=Warning, 1=Information, 0=Verbose
| take 50

Dependencies

Automatically tracked dependencies

Application Insights SDKs for .NET and .NET Core ship with DependencyTrackingTelemetryModule, which is a telemetry module that automatically collects dependencies. The module DependencyTrackingTelemetryModule is shipped as the Microsoft.ApplicationInsights.DependencyCollector NuGet package and brought automatically when you use either the Microsoft.ApplicationInsights.Web NuGet package or the Microsoft.ApplicationInsights.AspNetCore NuGet package.

Currently, DependencyTrackingTelemetryModule tracks the following dependencies automatically:

Dependencies Details
HTTP/HTTPS Local or remote HTTP/HTTPS calls.
WCF calls Only tracked automatically if HTTP-based bindings are used.
SQL Calls made with SqlClient. See the section Advanced SQL tracking to get full SQL query for capturing SQL queries.
Azure Blob Storage, Table Storage, or Queue Storage Calls made with the Azure Storage client.
Azure Event Hubs client SDK Use the latest package: https://nuget.org/packages/Azure.Messaging.EventHubs.
Azure Service Bus client SDK Use the latest package: https://nuget.org/packages/Azure.Messaging.ServiceBus.
Azure Cosmos DB Tracked automatically if HTTP/HTTPS is used. Tracing for operations in direct mode with TCP are captured automatically using preview package >= 3.33.0-preview. For more details, visit the documentation.

If the dependency isn't autocollected, you can track it manually with a track dependency call.

For more information about how dependency tracking works, see Dependency tracking in Application Insights.

Set up automatic dependency tracking in console apps

To automatically track dependencies from .NET console apps, install the NuGet package Microsoft.ApplicationInsights.DependencyCollector and initialize DependencyTrackingTelemetryModule:

    DependencyTrackingTelemetryModule depModule = new DependencyTrackingTelemetryModule();
    depModule.Initialize(TelemetryConfiguration.Active);

Manually tracking dependencies

The following examples of dependencies, which aren't automatically collected, require manual tracking:

  • Azure Cosmos DB is tracked automatically only if HTTP/HTTPS is used. TCP mode isn't automatically captured by Application Insights for SDK versions older than 2.22.0-Beta1.
  • Redis

For those dependencies not automatically collected by SDK, you can track them manually by using the TrackDependency API that's used by the standard autocollection modules.

Example

If you build your code with an assembly that you didn't write yourself, you could time all the calls to it. This scenario would allow you to find out what contribution it makes to your response times.

To have this data displayed in the dependency charts in Application Insights, send it by using TrackDependency:


    var startTime = DateTime.UtcNow;
    var timer = System.Diagnostics.Stopwatch.StartNew();
    try
    {
        // making dependency call
        success = dependency.Call();
    }
    finally
    {
        timer.Stop();
        telemetryClient.TrackDependency("myDependencyType", "myDependencyCall", "myDependencyData", startTime, timer.Elapsed, success);
    }

Alternatively, TelemetryClient provides the extension methods StartOperation and StopOperation, which can be used to manually track dependencies as shown in Outgoing dependencies tracking.

Disabling the standard dependency tracking module

If you want to switch off the standard dependency tracking module, remove the reference to DependencyTrackingTelemetryModule in ApplicationInsights.config for ASP.NET applications.

Advanced SQL tracking to get full SQL query

For SQL calls, the name of the server and database is always collected and stored as the name of the collected DependencyTelemetry. Another field, called data, can contain the full SQL query text.

Note

Azure Functions requires separate settings to enable SQL text collection. For more information, see Enable SQL query collection.

For ASP.NET applications, the full SQL query text is collected with the help of byte code instrumentation, which requires using the instrumentation engine or by using the Microsoft.Data.SqlClient NuGet package instead of the System.Data.SqlClient library. Platform-specific steps to enable full SQL Query collection are described in the following table.

Platform Steps needed to get full SQL query
Web Apps in Azure App Service In your web app control panel, open the Application Insights pane and enable SQL Commands under .NET.
IIS Server (Azure Virtual Machines, on-premises, and so on) Either use the Microsoft.Data.SqlClient NuGet package or use the Application Insights Agent PowerShell Module to install the instrumentation engine and restart IIS.
Azure Cloud Services Add a startup task to install StatusMonitor.
Your app should be onboarded to the ApplicationInsights SDK at build time by installing NuGet packages for ASP.NET or ASP.NET Core applications.
IIS Express Use the Microsoft.Data.SqlClient NuGet package.
WebJobs in Azure App Service Use the Microsoft.Data.SqlClient NuGet package.

In addition to the preceding platform-specific steps, you must also explicitly opt in to enable SQL command collection by modifying the applicationInsights.config file with the following code:

<TelemetryModules>
  <Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
    <EnableSqlCommandTextInstrumentation>true</EnableSqlCommandTextInstrumentation>
  </Add>

In the preceding cases, the proper way of validating that the instrumentation engine is correctly installed is by validating that the SDK version of collected DependencyTelemetry is rddp. Use of rdddsd or rddf indicates dependencies are collected via DiagnosticSource or EventSource callbacks, so the full SQL query isn't captured.

Exceptions

Exceptions in web applications can be reported with Application Insights. You can correlate failed requests with exceptions and other events on both the client and server so that you can quickly diagnose the causes. In this section, you learn how to set up exception reporting, report exceptions explicitly, diagnose failures, and more.

Set up exception reporting

You can set up Application Insights to report exceptions that occur in either the server or the client. Depending on the platform your application is dependent on, you need the appropriate extension or SDK.

To have exceptions reported from your server-side application, consider the following scenarios:

Important

This section is focused on .NET Framework apps from a code example perspective. Some of the methods that work for .NET Framework are obsolete in the .NET Core SDK.

Diagnose failures and exceptions

Application Insights comes with a curated Application Performance Management experience to help you diagnose failures in your monitored applications.

For detailed instructions, see Investigate failures, performance, and transactions with Application Insights.

Custom tracing and log data

To get diagnostic data specific to your app, you can insert code to send your own telemetry data. Your custom telemetry or log data is displayed in diagnostic search alongside the request, page view, and other automatically collected data.

Using the Microsoft.VisualStudio.ApplicationInsights.TelemetryClient, you have several APIs available:

To see these events, on the left menu, open Search. Select the dropdown menu Event types, and then choose Custom Event, Trace, or Exception.

Screenshot that shows the Search screen.

Note

If your app generates large amounts of telemetry, the adaptive sampling module automatically reduces the volume sent to the portal by sending only a representative fraction of events. Events that are part of the same operation are selected or deselected as a group so that you can navigate between related events. For more information, see Sampling in Application Insights.

See request POST data

Request details don't include the data sent to your app in a POST call. To have this data reported:

By default, not all exceptions that cause failures in your app appear in the portal. If you use the JavaScript SDK in your webpages, you see browser exceptions. However, most server-side exceptions are intercepted by IIS, so you need to add some code to capture and report them.

You can:

  • Log exceptions explicitly by inserting code in exception handlers to report the exceptions.
  • Capture exceptions automatically by configuring your ASP.NET framework. The necessary additions are different for different types of framework.
Report exceptions explicitly

The simplest way to report is to insert a call to trackException() in an exception handler.

var telemetry = new TelemetryClient();

try
{
    // ...
}
catch (Exception ex)
{
    var properties = new Dictionary<string, string>
    {
        ["Game"] = currentGame.Name
    };

    var measurements = new Dictionary<string, double>
    {
        ["Users"] = currentGame.Users.Count
    };

    // Send the exception telemetry:
    telemetry.TrackException(ex, properties, measurements);
}

The properties and measurements parameters are optional, but they're useful for filtering and adding extra information. For example, if you have an app that can run several games, you could find all the exception reports related to a particular game. You can add as many items as you want to each dictionary.

Browser exceptions

Most browser exceptions are reported.

If your webpage includes script files from content delivery networks or other domains, ensure your script tag has the attribute crossorigin="anonymous" and that the server sends CORS headers. This behavior allows you to get a stack trace and detail for unhandled JavaScript exceptions from these resources.

Reuse your telemetry client

Note

We recommend that you instantiate the TelemetryClient once and reuse it throughout the life of an application.

With Dependency Injection (DI) in .NET, the appropriate .NET SDK, and correctly configuring Application Insights for DI, you can require the TelemetryClient as a constructor parameter.

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

    public ExampleController(TelemetryClient telemetryClient)
    {
        _telemetryClient = telemetryClient;
    }
}

In the preceding example, the TelemetryClient is injected into the ExampleController class.

Web forms

For web forms, the HTTP Module is able to collect the exceptions when there are no redirects configured with CustomErrors. However, when you have active redirects, add the following lines to the Application_Error function in Global.asax.cs.

void Application_Error(object sender, EventArgs e)
{
    if (HttpContext.Current.IsCustomErrorEnabled &&
        Server.GetLastError () != null)
    {
        _telemetryClient.TrackException(Server.GetLastError());
    }
}

In the preceding example, the _telemetryClient is a class-scoped variable of type TelemetryClient.

MVC

Starting with Application Insights Web SDK version 2.6 (beta 3 and later), Application Insights collects unhandled exceptions thrown in the MVC 5+ controllers methods automatically. If you previously added a custom handler to track such exceptions, you can remove it to prevent double tracking of exceptions.

There are several scenarios when an exception filter can't correctly handle errors when exceptions are thrown:

  • From controller constructors
  • From message handlers
  • During routing
  • During response content serialization
  • During application start-up
  • In background tasks

All exceptions handled by application still need to be tracked manually. Unhandled exceptions originating from controllers typically result in a 500 "Internal Server Error" response. If such response is manually constructed as a result of a handled exception, or no exception at all, it's tracked in corresponding request telemetry with ResultCode 500. However, the Application Insights SDK is unable to track a corresponding exception.

Prior versions support

If you use MVC 4 (and prior) of Application Insights Web SDK 2.5 (and prior), refer to the following examples to track exceptions.


Expand to view instructions for prior versions

If the CustomErrors configuration is Off, exceptions are available for the HTTP Module to collect. However, if it's set to RemoteOnly (default) or On, the exception is cleared and not available for Application Insights to automatically collect. You can fix that behavior by overriding the System.Web.Mvc.HandleErrorAttribute class and applying the overridden class as shown for the different MVC versions here (see the GitHub source):

using System;
using System.Web.Mvc;
using Microsoft.ApplicationInsights;

namespace MVC2App.Controllers
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AiHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext != null && filterContext.HttpContext != null && filterContext.Exception != null)
            {
                //The attribute should track exceptions only when CustomErrors setting is On
                //if CustomErrors is Off, exceptions will be caught by AI HTTP Module
                if (filterContext.HttpContext.IsCustomErrorEnabled)
                {   //Or reuse instance (recommended!). See note above.
                    var ai = new TelemetryClient();
                    ai.TrackException(filterContext.Exception);
                }
            }
            base.OnException(filterContext);
        }
    }
}

MVC 2

Replace the HandleError attribute with your new attribute in your controllers:

    namespace MVC2App.Controllers
    {
        [AiHandleError]
        public class HomeController : Controller
        {
            // Omitted for brevity
        }
    }

Sample

MVC 3

Register AiHandleErrorAttribute as a global filter in Global.asax.cs:

public class MyMvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AiHandleErrorAttribute());
    }
}

Sample

MVC 4, MVC 5

Register AiHandleErrorAttribute as a global filter in FilterConfig.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // Default replaced with the override to track unhandled exceptions
        filters.Add(new AiHandleErrorAttribute());
    }
}

Sample

Web API

Starting with Application Insights Web SDK version 2.6 (beta 3 and later), Application Insights collects unhandled exceptions thrown in the controller methods automatically for Web API 2+. If you previously added a custom handler to track such exceptions, as described in the following examples, you can remove it to prevent double tracking of exceptions.

There are several cases that the exception filters can't handle. For example:

  • Exceptions thrown from controller constructors.
  • Exceptions thrown from message handlers.
  • Exceptions thrown during routing.
  • Exceptions thrown during response content serialization.
  • Exception thrown during application startup.
  • Exception thrown in background tasks.

All exceptions handled by application still need to be tracked manually. Unhandled exceptions originating from controllers typically result in a 500 "Internal Server Error" response. If such a response is manually constructed as a result of a handled exception, or no exception at all, it's tracked in a corresponding request telemetry with ResultCode 500. However, the Application Insights SDK can't track a corresponding exception.

Prior versions support

If you use Web API 1 (and earlier) of Application Insights Web SDK 2.5 (and earlier), refer to the following examples to track exceptions.


Expand to view instructions for prior versions

Web API 1.x

Override System.Web.Http.Filters.ExceptionFilterAttribute:

using System.Web.Http.Filters;
using Microsoft.ApplicationInsights;

namespace WebAPI.App_Start
{
    public class AiExceptionFilterAttribute : ExceptionFilterAttribute
    {
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext != null && actionExecutedContext.Exception != null)
        {  //Or reuse instance (recommended!). See note above.
            var ai = new TelemetryClient();
            ai.TrackException(actionExecutedContext.Exception);
        }
        base.OnException(actionExecutedContext);
    }
    }
}

You could add this overridden attribute to specific controllers, or add it to the global filter configuration in the WebApiConfig class:

using System.Web.Http;
using WebApi1.x.App_Start;

namespace WebApi1.x
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });
    
            // ...
            config.EnableSystemDiagnosticsTracing();
    
            // Capture exceptions for Application Insights:
            config.Filters.Add(new AiExceptionFilterAttribute());
        }
    }
}

Sample

Web API 2.x

Add an implementation of IExceptionLogger:

using System.Web.Http.ExceptionHandling;
using Microsoft.ApplicationInsights;

namespace ProductsAppPureWebAPI.App_Start
{
    public class AiExceptionLogger : ExceptionLogger
    {
        public override void Log(ExceptionLoggerContext context)
        {
            if (context != null && context.Exception != null)
            {
                //or reuse instance (recommended!). see note above
                var ai = new TelemetryClient();
                ai.TrackException(context.Exception);
            }
            base.Log(context);
        }
    }
}

Add this snippet to the services in WebApiConfig:

using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using ProductsAppPureWebAPI.App_Start;

namespace WebApi2WithMVC
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
    
            // Web API routes
            config.MapHttpAttributeRoutes();
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });

            config.Services.Add(typeof(IExceptionLogger), new AiExceptionLogger());
        }
    }
}

Sample

As alternatives, you could:

  • Replace the only ExceptionHandler instance with a custom implementation of IExceptionHandler. This exception handler is only called when the framework is still able to choose which response message to send, not when the connection is aborted, for instance.
  • Use exception filters, as described in the preceding section on Web API 1.x controllers, which aren't called in all cases.

WCF

Add a class that extends Attribute and implements IErrorHandler and IServiceBehavior.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    using System.Web;
    using Microsoft.ApplicationInsights;

    namespace WcfService4.ErrorHandling
    {
      public class AiLogExceptionAttribute : Attribute, IErrorHandler, IServiceBehavior
      {
        public void AddBindingParameters(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase,
            System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
            System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher disp in serviceHostBase.ChannelDispatchers)
            {
                disp.ErrorHandlers.Add(this);
            }
        }

        public void Validate(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase)
        {
        }

        bool IErrorHandler.HandleError(Exception error)
        {//or reuse instance (recommended!). see note above
            var ai = new TelemetryClient();

            ai.TrackException(error);
            return false;
        }

        void IErrorHandler.ProvideFault(Exception error,
            System.ServiceModel.Channels.MessageVersion version,
            ref System.ServiceModel.Channels.Message fault)
        {
        }
      }
    }

Add the attribute to the service implementations:

namespace WcfService4
{
    [AiLogException]
    public class Service1 : IService1
    {
        // Omitted for brevity
    }
}

Sample

Exception performance counters

If you installed the Azure Monitor Application Insights Agent on your server, you can get a chart of the exceptions rate measured by .NET. Both handled and unhandled .NET exceptions are included.

Open a metrics explorer tab and add a new chart. Under Performance Counters, select Exception rate.

The .NET Framework calculates the rate by counting the number of exceptions in an interval and dividing by the length of the interval.

This count is different from the Exceptions count calculated by the Application Insights portal counting TrackException reports. The sampling intervals are different, and the SDK doesn't send TrackException reports for all handled and unhandled exceptions.

Custom metric collection

The Azure Monitor Application Insights .NET and .NET Core SDKs have two different methods of collecting custom metrics:

  • The TrackMetric() method, which lacks preaggregation.
  • The GetMetric() method, which has preaggregation.

We recommend to use aggregation, so TrackMetric() is no longer the preferred method of collecting custom metrics. This article walks you through using the GetMetric() method and some of the rationale behind how it works.


Expand to learn more about preaggregating vs. non-preaggregating API

The TrackMetric() method sends raw telemetry denoting a metric. It's inefficient to send a single telemetry item for each value. The TrackMetric() method is also inefficient in terms of performance because every TrackMetric(item) goes through the full SDK pipeline of telemetry initializers and processors.

Unlike TrackMetric(), GetMetric() handles local preaggregation for you and then only submits an aggregated summary metric at a fixed interval of one minute. If you need to closely monitor some custom metric at the second or even millisecond level, you can do so while only incurring the storage and network traffic cost of only monitoring every minute. This behavior also greatly reduces the risk of throttling occurring because the total number of telemetry items that need to be sent for an aggregated metric are greatly reduced.

In Application Insights, custom metrics collected via TrackMetric() and GetMetric() aren't subject to sampling. Sampling important metrics can lead to scenarios where alerting you might have built around those metrics could become unreliable. By never sampling your custom metrics, you can generally be confident that when your alert thresholds are breached, an alert fires. Because custom metrics aren't sampled, there are some potential concerns.

Trend tracking in a metric every second, or at an even more granular interval, can result in:

  • Increased data storage costs. There's a cost associated with how much data you send to Azure Monitor. The more data you send, the greater the overall cost of monitoring.
  • Increased network traffic or performance overhead. In some scenarios, this overhead could have both a monetary and application performance cost.
  • Risk of ingestion throttling. Azure Monitor drops ("throttles") data points when your app sends a high rate of telemetry in a short time interval.

Throttling is a concern because it can lead to missed alerts. The condition to trigger an alert could occur locally and then be dropped at the ingestion endpoint because of too much data being sent. We don't recommend using TrackMetric() for .NET and .NET Core unless you've implemented your own local aggregation logic. If you're trying to track every instance an event occurs over a given time period, you might find that TrackEvent() is a better fit. Keep in mind that unlike custom metrics, custom events are subject to sampling. You can still use TrackMetric() even without writing your own local preaggregation. But if you do so, be aware of the pitfalls.

In summary, we recommend GetMetric() because it does preaggregation, it accumulates values from all the Track() calls, and sends a summary/aggregate once every minute. The GetMetric() method can significantly reduce the cost and performance overhead by sending fewer data points while still collecting all relevant information.

Get started with GetMetric

For our examples, we're going to use a basic .NET Core 3.1 worker service application. If you want to replicate the test environment used with these examples, follow steps 1-6 in the Monitoring worker service article. These steps add Application Insights to a basic worker service project template. The concepts apply to any general application where the SDK can be used, including web apps and console apps.

Send metrics

Replace the contents of your worker.cs file with the following code:

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights;

namespace WorkerService3
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private TelemetryClient _telemetryClient;

        public Worker(ILogger<Worker> logger, TelemetryClient tc)
        {
            _logger = logger;
            _telemetryClient = tc;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {   // The following line demonstrates usages of GetMetric API.
            // Here "computersSold", a custom metric name, is being tracked with a value of 42 every second.
            while (!stoppingToken.IsCancellationRequested)
            {
                _telemetryClient.GetMetric("ComputersSold").TrackValue(42);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}

When you run the sample code, you see the while loop repeatedly executing with no telemetry being sent in the Visual Studio output window. A single telemetry item is sent by around the 60-second mark, which in our test looks like:

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.00000000-0000-0000-0000-000000000000.Metric", "time":"2019-12-28T00:54:19.0000000Z",
"ikey":"00000000-0000-0000-0000-000000000000",
"tags":{"ai.application.ver":"1.0.0.0",
"ai.cloud.roleInstance":"Test-Computer-Name",
"ai.internal.sdkVersion":"m-agg2c:2.12.0-21496",
"ai.internal.nodeName":"Test-Computer-Name"},
"data":{"baseType":"MetricData",
"baseData":{"ver":2,"metrics":[{"name":"ComputersSold",
"kind":"Aggregation",
"value":1722,
"count":41,
"min":42,
"max":42,
"stdDev":0}],
"properties":{"_MS.AggregationIntervalMs":"42000",
"DeveloperMode":"true"}}}}

This single telemetry item represents an aggregate of 41 distinct metric measurements. Because we were sending the same value over and over again, we have a standard deviation (stDev) of 0 with identical maximum (max) and minimum (min) values. The value property represents a sum of all the individual values that were aggregated.

Note

The GetMetric method doesn't support tracking the last value (for example, gauge) or tracking histograms or distributions.

If we examine our Application Insights resource in the Logs (Analytics) experience, the individual telemetry item would look like the following screenshot.

Screenshot that shows the Log Analytics query view.

Note

While the raw telemetry item didn't contain an explicit sum property/field once ingested, we create one for you. In this case, both the value and valueSum property represent the same thing.

You can also access your custom metric telemetry in the Metrics section of the portal as both a log-based and custom metric. The following screenshot is an example of a log-based metric.

Screenshot that shows the Metrics explorer view.

Cache metric reference for high-throughput usage

Metric values might be observed frequently in some cases. For example, a high-throughput service that processes 500 requests per second might want to emit 20 telemetry metrics for each request. The result means tracking 10,000 values per second. In such high-throughput scenarios, users might need to help the SDK by avoiding some lookups.

For example, the preceding example performed a lookup for a handle for the metric ComputersSold and then tracked an observed value of 42. Instead, the handle might be cached for multiple track invocations:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is where the cache is stored to handle faster lookup
            Metric computersSold = _telemetryClient.GetMetric("ComputersSold");
            while (!stoppingToken.IsCancellationRequested)
            {

                computersSold.TrackValue(42);

                computersSold.TrackValue(142);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

In addition to caching the metric handle, the preceding example also reduced Task.Delay to 50 milliseconds so that the loop would execute more frequently. The result is 772 TrackValue() invocations.

Multidimensional metrics

The examples in the previous section show zero-dimensional metrics. Metrics can also be multidimensional. We currently support up to 10 dimensions.

Here's an example of how to create a one-dimensional metric:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is an example of a metric with a single dimension.
            // FormFactor is the name of the dimension.
            Metric computersSold= _telemetryClient.GetMetric("ComputersSold", "FormFactor");

            while (!stoppingToken.IsCancellationRequested)
            {
                // The number of arguments (dimension values)
                // must match the number of dimensions specified while GetMetric.
                // Laptop, Tablet, etc are values for the dimension "FormFactor"
                computersSold.TrackValue(42, "Laptop");
                computersSold.TrackValue(20, "Tablet");
                computersSold.TrackValue(126, "Desktop");


                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

Running the sample code for at least 60 seconds results in three distinct telemetry items being sent to Azure. Each item represents the aggregation of one of the three form factors. As before, you can further examine in the Logs (Analytics) view.

Screenshot that shows the Log Analytics view of multidimensional metric.

In the metrics explorer:

Screenshot that shows Custom metrics.

Notice that you can't split the metric by your new custom dimension or view your custom dimension with the metrics view.

Screenshot that shows splitting support.

By default, multidimensional metrics within the metric explorer aren't turned on in Application Insights resources.

Enable multidimensional metrics

To enable multidimensional metrics for an Application Insights resource, select Usage and estimated costs > Custom Metrics > Enable alerting on custom metric dimensions > OK. For more information, see Custom metrics dimensions and preaggregation.

After you've made that change and sent new multidimensional telemetry, you can select Apply splitting.

Note

Only newly sent metrics after the feature was turned on in the portal will have dimensions stored.

Screenshot that shows applying splitting.

View your metric aggregations for each FormFactor dimension.

Screenshot that shows form factors.

Use MetricIdentifier when there are more than three dimensions

Currently, 10 dimensions are supported. More than three dimensions requires the use of MetricIdentifier:

// Add "using Microsoft.ApplicationInsights.Metrics;" to use MetricIdentifier
// MetricIdentifier id = new MetricIdentifier("[metricNamespace]","[metricId],"[dim1]","[dim2]","[dim3]","[dim4]","[dim5]");
MetricIdentifier id = new MetricIdentifier("CustomMetricNamespace","ComputerSold", "FormFactor", "GraphicsCard", "MemorySpeed", "BatteryCapacity", "StorageCapacity");
Metric computersSold  = _telemetryClient.GetMetric(id);
computersSold.TrackValue(110,"Laptop", "Nvidia", "DDR4", "39Wh", "1TB");

Custom metric configuration

If you want to alter the metric configuration, you must make alterations in the place where the metric is initialized.

Special dimension names

Metrics don't use the telemetry context of the TelemetryClient used to access them. Using special dimension names available as constants in the MetricDimensionNames class is the best workaround for this limitation.

Metric aggregates sent by the following Special Operation Request Size metric won't have Context.Operation.Name set to Special Operation. The TrackMetric() method or any other TrackXXX() method will have OperationName set correctly to Special Operation.

        //...
        TelemetryClient specialClient;
        private static int GetCurrentRequestSize()
        {
            // Do stuff
            return 1100;
        }
        int requestSize = GetCurrentRequestSize()

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                //...
                specialClient.Context.Operation.Name = "Special Operation";
                specialClient.GetMetric("Special Operation Request Size").TrackValue(requestSize);
                //...
            }
                   
        }

In this circumstance, use the special dimension names listed in the MetricDimensionNames class to specify the TelemetryContext values.

For example, when the metric aggregate resulting from the next statement is sent to the Application Insights cloud endpoint, its Context.Operation.Name data field will be set to Special Operation:

_telemetryClient.GetMetric("Request Size", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation");

The values of this special dimension will be copied into TelemetryContext and won't be used as a normal dimension. If you want to also keep an operation dimension for normal metric exploration, you need to create a separate dimension for that purpose:

_telemetryClient.GetMetric("Request Size", "Operation Name", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation", "Special Operation");
Dimension and time-series capping

To prevent the telemetry subsystem from accidentally using up your resources, you can control the maximum number of data series per metric. The default limits are no more than 1,000 total data series per metric, and no more than 100 different values per dimension.

Important

Use low cardinal values for dimensions to avoid throttling.

In the context of dimension and time series capping, we use Metric.TrackValue(..) to make sure that the limits are observed. If the limits are already reached, Metric.TrackValue(..) returns False and the value won't be tracked. Otherwise, it returns True. This behavior is useful if the data for a metric originates from user input.

The MetricConfiguration constructor takes some options on how to manage different series within the respective metric and an object of a class implementing IMetricSeriesConfiguration that specifies aggregation behavior for each individual series of the metric:

var metConfig = new MetricConfiguration(seriesCountLimit: 100, valuesPerDimensionLimit:2,
                new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false));

Metric computersSold = _telemetryClient.GetMetric("ComputersSold", "Dimension1", "Dimension2", metConfig);

// Start tracking.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value1");
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value2");

// The following call gives 3rd unique value for dimension2, which is above the limit of 2.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3");
// The above call does not track the metric, and returns false.
  • seriesCountLimit is the maximum number of data time series a metric can contain. When this limit is reached, calls to TrackValue() that would normally result in a new series return false.
  • valuesPerDimensionLimit limits the number of distinct values per dimension in a similar manner.
  • restrictToUInt32Values determines whether or not only non-negative integer values should be tracked.

Here's an example of how to send a message to know if cap limits are exceeded:

if (! computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3"))
{
// Add "using Microsoft.ApplicationInsights.DataContract;" to use SeverityLevel.Error
_telemetryClient.TrackTrace("Metric value not tracked as value of one of the dimension exceeded the cap. Revisit the dimensions to ensure they are within the limits",
SeverityLevel.Error);
}

Performance counters

ASP.NET fully supports performance counters, while ASP.NET Core offers limited support depending on the SDK version and hosting environment. For more information, see Counters for .NET in Application Insights.

Event counters

Application Insights supports collecting EventCounters with its EventCounterCollectionModule, which is enabled by default for ASP.NET Core. To learn how to configure the list of counters to be collected, see Counters for .NET in Application Insights.

Configure and tune the SDK

In this section

Configure the Application Insights SDK

You can customize the Application Insights SDK for ASP.NET and ASP.NET Core to change the default configuration.

The Application Insights .NET SDK consists of many NuGet packages. The core package provides the API for sending telemetry to the Application Insights. More packages provide telemetry modules and initializers for automatically tracking telemetry from your application and its context. By adjusting the configuration file, you can enable or disable telemetry modules and initializers. You can also set parameters for some of them.

The configuration file is named ApplicationInsights.config or ApplicationInsights.xml. The name depends on the type of your application. It's automatically added to your project when you install most versions of the SDK. By default, when you use the automated experience from the Visual Studio template projects that support Add > Application Insights Telemetry, the ApplicationInsights.config file is created in the project root folder. When it's compiled, it's copied to the bin folder. It's also added to a web app by Application Insights Agent on an IIS server. The configuration file is ignored if the extension for Azure websites or the extension for Azure VMs and virtual machine scale sets is used.

There isn't an equivalent file to control the SDK in a webpage.

This article describes the sections you see in the configuration file, how they control the components of the SDK, and which NuGet packages load those components.

Telemetry modules

Each telemetry module collects a specific type of data and uses the core API to send the data. The modules are installed by different NuGet packages, which also add the required lines to the .config file.

There's a node in the configuration file for each module. To disable a module, delete the node or comment it out.

Module Description
Dependency tracking:
DependencyCollector
Collects telemetry about calls your app makes to databases and external services and databases. To allow this module to work in an IIS server, you need to install Application Insights Agent. You can also write your own dependency tracking code by using the TrackDependency API.

Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule
Microsoft.ApplicationInsights.DependencyCollector NuGet package

Dependencies can be autocollected without modifying your code by using agent-based (codeless) attach. To use it in Azure web apps, enable the Application Insights extension. To use it in an Azure VM or an Azure virtual machine scale set, enable the Application Monitoring extension for VMs and virtual machine scale sets.
Performance collector:
PerformanceCollectorModule
Collects system performance counters, such as CPU, memory, and network load from IIS installations. You can specify which counters to collect, including performance counters you've set up yourself.

Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule
Microsoft.ApplicationInsights.PerfCounterCollector NuGet package
Diagnostic telemetry:
DiagnosticsTelemetryModule
Reports errors in the Application Insights instrumentation code itself. Examples are if the code can't access performance counters or if ITelemetryInitializer throws an exception. Trace telemetry tracked by this module appears in the Diagnostic Search.

Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule
Microsoft.ApplicationInsights NuGet package. If you only install this package, the ApplicationInsights.config file isn't automatically created.
Developer mode:
DeveloperModeWithDebuggerAttachedTelemetryModule
Forces the Application Insights TelemetryChannel to send data immediately, one telemetry item at a time, when a debugger is attached to the application process. This design reduces the amount of time between the moment when your application tracks telemetry and when it appears in the Application Insights portal. It causes significant overhead in CPU and network bandwidth.

Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule
Application Insights Windows Server NuGet package
Web request tracking:
Web.RequestTrackingTelemetryModule
Reports the response time and result code of HTTP requests.

Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule
Microsoft.ApplicationInsights.Web NuGet package
Exception tracking:
ExceptionTrackingTelemetryModule
Tracks unhandled exceptions in your web app. For more information, see Failures and exceptions.

Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule.
Microsoft.ApplicationInsights.Web NuGet package.
Microsoft.ApplicationInsights.WindowsServer.UnobservedExceptionTelemetryModule: Tracks unobserved task. exceptions.
Microsoft.ApplicationInsights.WindowsServer.UnhandledExceptionTelemetryModule: Tracks unhandled exceptions for worker roles, Windows services, and console applications.
Application Insights Windows Server NuGet package.
EventSource tracking:
EventSourceTelemetryModule
Allows you to configure EventSource events to be sent to Application Insights as traces. For information on tracking EventSource events, see Using EventSource events.

Microsoft.ApplicationInsights.EventSourceListener.EventSourceTelemetryModule
Microsoft.ApplicationInsights.EventSourceListener
ETW event tracking:
EtwCollectorTelemetryModule
Allows you to configure events from ETW providers to be sent to Application Insights as traces. For information on tracking ETW events, see Using ETW events.

Microsoft.ApplicationInsights.EtwCollector.EtwCollectorTelemetryModule
Microsoft.ApplicationInsights.EtwCollector
Application Insights package:
Microsoft.ApplicationInsights
Provides the core API of the SDK. The other telemetry modules use this API. You can also use it to define your own telemetry.

• No entry in ApplicationInsights.config.
Microsoft.ApplicationInsights NuGet package. If you just install this NuGet, no .config file is generated.

Telemetry channel

The telemetry channel manages buffering and transmission of telemetry to the Application Insights service.

  • Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel is the default channel for web applications. It buffers data in memory and employs retry mechanisms and local disk storage for more reliable telemetry delivery.
  • Microsoft.ApplicationInsights.InMemoryChannel is a lightweight telemetry channel. It's used if no other channel is configured.

Telemetry initializers

Telemetry initializers set context properties that are sent along with every item of telemetry.

You can write your own initializers to set context properties.

The standard initializers are all set either by the web or WindowsServer NuGet packages:

Initializer Description
AccountIdTelemetryInitializer Sets the AccountId property.
AuthenticatedUserIdTelemetryInitializer Sets the AuthenticatedUserId property as set by the JavaScript SDK.
AzureRoleEnvironmentTelemetryInitializer Updates the RoleName and RoleInstance properties of the Device context for all telemetry items with information extracted from the Azure runtime environment.
BuildInfoConfigComponentVersionTelemetryInitializer Updates the Version property of the Component context for all telemetry items with the value extracted from the BuildInfo.config file produced by MS Build.
ClientIpHeaderTelemetryInitializer Updates the Ip property of the Location context of all telemetry items based on the X-Forwarded-For HTTP header of the request.
DeviceTelemetryInitializer Updates the following properties of the Device context for all telemetry items:

Type is set to PC.
Id is set to the ___domain name of the computer where the web application is running.
OemName is set to the value extracted from the Win32_ComputerSystem.Manufacturer field by using WMI.
Model is set to the value extracted from the Win32_ComputerSystem.Model field by using WMI.
NetworkType is set to the value extracted from the NetworkInterface property.
Language is set to the name of the CurrentCulture property.
DomainNameRoleInstanceTelemetryInitializer Updates the RoleInstance property of the Device context for all telemetry items with the ___domain name of the computer where the web application is running.
OperationNameTelemetryInitializer Udates the Name property of RequestTelemetry and the Name property of the Operation context of all telemetry items based on the HTTP method, and the names of the ASP.NET MVC controller and action invoked to process the request.
OperationIdTelemetryInitializer or OperationCorrelationTelemetryInitializer Updates the Operation.Id context property of all telemetry items tracked while handling a request with the automatically generated RequestTelemetry.Id.
SessionTelemetryInitializer Updates the Id property of the Session context for all telemetry items with value extracted from the ai_session cookie generated by the ApplicationInsights JavaScript instrumentation code running in the user's browser.
SyntheticTelemetryInitializer or SyntheticUserAgentTelemetryInitializer Updates the User, Session, and Operation context properties of all telemetry items tracked when handling a request from a synthetic source, such as an availability test or search engine bot. By default, metrics explorer doesn't display synthetic telemetry.

The <Filters> set identifying properties of the requests.
UserTelemetryInitializer Updates the Id and AcquisitionDate properties of the User context for all telemetry items with values extracted from the ai_user cookie generated by the Application Insights JavaScript instrumentation code running in the user's browser.
WebTestTelemetryInitializer Sets the user ID, session ID, and synthetic source properties for HTTP requests that come from availability tests.

The <Filters> set identifying properties of the requests.

For .NET applications running in Azure Service Fabric, you can include the Microsoft.ApplicationInsights.ServiceFabric NuGet package. This package includes a FabricTelemetryInitializer property, which adds Service Fabric properties to telemetry items. For more information, see the GitHub page about the properties added by this NuGet package.

Telemetry processors

Telemetry processors can filter and modify each telemetry item before it's sent from the SDK to the portal.

You can write your own telemetry processors.

Adaptive sampling telemetry processor (from 2.0.0-beta3)

This functionality is enabled by default. If your app sends considerable telemetry, this processor removes some of it.


    <TelemetryProcessors>
      <Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
        <MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
      </Add>
    </TelemetryProcessors>

The parameter provides the target that the algorithm tries to achieve. Each instance of the SDK works independently. So, if your server is a cluster of several machines, the actual volume of telemetry will be multiplied accordingly.

Learn more about sampling.

Fixed-rate sampling telemetry processor (from 2.0.0-beta1)

There's also a standard sampling telemetry processor (from 2.0.1):


    <TelemetryProcessors>
     <Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.SamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">

     <!-- Set a percentage close to 100/N where N is an integer. -->
     <!-- E.g. 50 (=100/2), 33.33 (=100/3), 25 (=100/4), 20, 1 (=100/100), 0.1 (=100/1000) -->
     <SamplingPercentage>10</SamplingPercentage>
     </Add>
   </TelemetryProcessors>

Connection String

This setting determines the Application Insights resource in which your data appears. Typically, you create a separate resource, with a separate connection string, for each of your applications.

See Connection strings in Application Insights for code samples.

If you want to set the connection string dynamically, for example, to send results from your application to different resources, you can omit the connection string from the configuration file and set it in code instead.

To set the connection string for all instances of TelemetryClient, including standard telemetry modules, do this step in an initialization method, such as global.aspx.cs in an ASP.NET service:

using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights;

    protected void Application_Start()
    {
        TelemetryConfiguration configuration = TelemetryConfiguration.CreateDefault();
        configuration.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000";
        var telemetryClient = new TelemetryClient(configuration);

If you want to send a specific set of events to a different resource, you can set the key for a specific telemetry client:


    var tc = new TelemetryClient();
    tc.Context.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000";
    tc.TrackEvent("myEvent");
    // ...

To get a new key, create a new resource in the Application Insights portal.

ApplicationId Provider

The provider is available starting in v2.6.0.

The purpose of this provider is to look up an application ID based on a connection string. The application ID is included in RequestTelemetry and DependencyTelemetry and is used to determine correlation in the portal.

This functionality is available by setting TelemetryConfiguration.ApplicationIdProvider either in code or in the config file.

Interface: IApplicationIdProvider
public interface IApplicationIdProvider
{
    bool TryGetApplicationId(string instrumentationKey, out string applicationId);
}

We provide two implementations in the Microsoft.ApplicationInsights SDK: ApplicationInsightsApplicationIdProvider and DictionaryApplicationIdProvider.

ApplicationInsightsApplicationIdProvider

This wrapper is for our Profile API. It throttles requests and cache results.

This provider is added to your config file when you install either Microsoft.ApplicationInsights.DependencyCollector or Microsoft.ApplicationInsights.Web.

This class has an optional property ProfileQueryEndpoint. By default, it's set to https://dc.services.visualstudio.com/api/profiles/{0}/appId. If you need to configure a proxy for this configuration, we recommend that you proxy the base address and include "/api/profiles/{0}/appId". A {0} is substituted at runtime per request with the instrumentation key.

Example configuration via ApplicationInsights.config

<ApplicationInsights>
    ...
    <ApplicationIdProvider Type="Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId.ApplicationInsightsApplicationIdProvider, Microsoft.ApplicationInsights">
        <ProfileQueryEndpoint>https://dc.services.visualstudio.com/api/profiles/{0}/appId</ProfileQueryEndpoint>
    </ApplicationIdProvider>
    ...
</ApplicationInsights>

Example configuration via code

TelemetryConfiguration.Active.ApplicationIdProvider = new ApplicationInsightsApplicationIdProvider();
DictionaryApplicationIdProvider

This static provider relies on your configured instrumentation key/application ID pairs.

This class has the Defined property, which is a Dictionary<string,string> of instrumentation key/application ID pairs.

This class has the optional property Next, which can be used to configure another provider to use when a connection string is requested that doesn't exist in your configuration.

Example configuration via ApplicationInsights.config

<ApplicationInsights>
    ...
    <ApplicationIdProvider Type="Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId.DictionaryApplicationIdProvider, Microsoft.ApplicationInsights">
        <Defined>
            <Type key="InstrumentationKey_1" value="ApplicationId_1"/>
            <Type key="InstrumentationKey_2" value="ApplicationId_2"/>
        </Defined>
        <Next Type="Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId.ApplicationInsightsApplicationIdProvider, Microsoft.ApplicationInsights" />
    </ApplicationIdProvider>
    ...
</ApplicationInsights>

Example configuration via code

TelemetryConfiguration.Active.ApplicationIdProvider = new DictionaryApplicationIdProvider{
 Defined = new Dictionary<string, string>
    {
        {"InstrumentationKey_1", "ApplicationId_1"},
        {"InstrumentationKey_2", "ApplicationId_2"}
    }
};

Configure snapshot collection

Configure a snapshot collection for ASP.NET applications.

Telemetry initializers

To enrich telemetry with additional information or to override telemetry properties set by the standard telemetry modules, use telemetry initializers.

To learn how to use telemetry initializers with ASP.NET applications, see Filter and preprocess telemetry in the Application Insights SDK.

Telemetry processors

To learn how to use telemetry processors with ASP.NET applications, see Filter and preprocess telemetry in the Application Insights SDK.

Sampling

To learn how to configure sampling for ASP.NET applications, see Sampling in Application Insights.

Configure or remove default TelemetryModules

Application Insights automatically collects telemetry about specific workloads without requiring manual tracking by user.

By default, the following automatic-collection modules are enabled. These modules are responsible for automatically collecting telemetry. You can disable or configure them to alter their default behavior.

  • RequestTrackingTelemetryModule: Collects RequestTelemetry from incoming web requests.
  • DependencyTrackingTelemetryModule: Collects DependencyTelemetry from outgoing HTTP calls and SQL calls.
  • PerformanceCollectorModule: Collects Windows PerformanceCounters.
  • QuickPulseTelemetryModule: Collects telemetry to show in the live metrics pane.
  • AppServicesHeartbeatTelemetryModule: Collects heartbeats (which are sent as custom metrics), about the App Service environment where the application is hosted.
  • AzureInstanceMetadataTelemetryModule: Collects heartbeats (which are sent as custom metrics), about the Azure VM environment where the application is hosted.
  • EventCounterCollectionModule: Collects EventCounters. This module is a new feature and is available in SDK version 2.8.0 and later.

To learn how to configure or remove telemetry modules for ASP.NET application, see Configure the Application Insights SDK with ApplicationInsights.config or .xml.

Enrich data through HTTP

var requestTelemetry = HttpContext.Current?.Items["Microsoft.ApplicationInsights.RequestTelemetry"] as RequestTelemetry;

if (requestTelemetry != null)
{
    requestTelemetry.Properties["myProp"] = "someData";
}

Add client-side monitoring

The previous sections provided guidance on methods to automatically and manually configure server-side monitoring. To add client-side monitoring, use the client-side JavaScript SDK. You can monitor any web page's client-side transactions by adding a JavaScript (Web) SDK Loader Script before the closing </head> tag of the page's HTML.

Although it's possible to manually add the JavaScript (Web) SDK Loader Script to the header of each HTML page, we recommend that you instead add the JavaScript (Web) SDK Loader Script to a primary page. That action injects the JavaScript (Web) SDK Loader Script into all pages of a site.

For the template-based ASP.NET MVC app from this article, the file that you need to edit is _Layout.cshtml. You can find it under Views > Shared. To add client-side monitoring, open _Layout.cshtml and follow the JavaScript (Web) SDK Loader Script-based setup instructions from the article about client-side JavaScript SDK configuration.

Troubleshooting

See the dedicated troubleshooting article.

There's a known issue in Visual Studio 2019: storing the instrumentation key or connection string in a user secret is broken for .NET Framework-based apps. The key ultimately has to be hardcoded into the applicationinsights.config file to work around this bug. This article is designed to avoid this issue entirely, by not using user secrets.

Test connectivity between your application host and the ingestion service

Application Insights SDKs and agents send telemetry to get ingested as REST calls to our ingestion endpoints. You can test connectivity from your web server or application host machine to the ingestion service endpoints by using raw REST clients from PowerShell or curl commands. See Troubleshoot missing application telemetry in Azure Monitor Application Insights.

Open-source SDK

Read and contribute to the code.

For the latest updates and bug fixes, consult the release notes.

Release Notes

For version 2.12 and newer: .NET Software Development Kits (SDKs) including ASP.NET, ASP.NET Core, and Logging Adapters

Our Service Updates also summarize major Application Insights improvements.

Next steps