Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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
- An Azure subscription. If you don't have one already, create a free Azure account.
- An Application Insights workspace-based resource.
- A functioning web application. If you don't have one already, see Create a basic web app.
- The latest version of Visual Studio with the following workloads:
- ASP.NET and web development
- Azure development
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.
- Open Visual Studio.
- Select Create a new project.
- Choose ASP.NET Web Application (.NET Framework) with C# and select Next.
- Enter a Project name, then select Create.
- 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:
Select Project > Add Application Insights Telemetry > Application Insights Sdk (local) > Next > Finish > Close.
Open the ApplicationInsights.config file.
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>
Select Project > Manage NuGet Packages > Updates. Then update each
Microsoft.ApplicationInsights
NuGet package to the latest stable release.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.
Add the following NuGet packages and their dependencies to your project:
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.
Copy the following XML configuration into your newly created file:
Expand to view the configuration
<?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>
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" };
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); } } }
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()); } } }
If Web.config is already updated, skip this step. Otherwise, update the file as follows:
Expand to view the configuration
<?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=\"Web\" /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:
Install the NuGet package Microsoft.ApplicationInsights.PerfCounterCollector.
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
By default, the Application Insights provider only sends logs with a severity of
Warning
or higher. To includeInformation
or lower-level logs, update the log level settings inappsettings.json
.The
Microsoft.ApplicationInsights.WorkerService
NuGet package, used to enable Application Insights for background services, is out of scope. For more information, see Application Insights for Worker Service apps.
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
For more information, see telemetry modules.
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:
- Add the Application Insights Extension for Azure web apps.
- Add the Application Monitoring Extension for Azure Virtual Machines and Azure Virtual Machine Scale Sets IIS-hosted apps.
- Add the Application Insights SDK to your app code, run Application Insights Agent for IIS web servers, or enable the Java agent for Java web apps.
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:
- TelemetryClient.TrackEvent is typically used for monitoring usage patterns, but the data it sends also appears under Custom Events in diagnostic search. Events are named and can carry string properties and numeric metrics on which you can filter your diagnostic searches.
- TelemetryClient.TrackTrace lets you send longer data such as POST information.
- TelemetryClient.TrackException sends exception details, such as stack traces to Application Insights.
To see these events, on the left menu, open Search. Select the dropdown menu Event types, and then choose Custom Event, Trace, or Exception.
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:
- Add the Application Insights SDK to your app code.
- Insert code in your application to call Microsoft.ApplicationInsights.TrackTrace(). Send the POST data in the message parameter. There's a limit to the permitted size, so you should try to send only the essential data.
- When you investigate a failed request, find the associated traces.
Capture exceptions and related diagnostic data
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
}
}
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());
}
}
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());
}
}
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());
}
}
}
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());
}
}
}
As alternatives, you could:
- Replace the only
ExceptionHandler
instance with a custom implementation ofIExceptionHandler
. 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
}
}
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 using 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 alerts built around those metrics 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 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 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.
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.
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.
In the metrics explorer:
Notice that you can't split the metric by your new custom dimension or view your custom dimension with the metrics view.
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 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 have dimensions stored.
View your metric aggregations for each FormFactor
dimension.
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 don't have Context.Operation.Name
set to Special Operation
. The TrackMetric()
method or any other TrackXXX()
method has 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 is set to Special Operation
:
_telemetryClient.GetMetric("Request Size", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation");
The value of this special dimension is copied into TelemetryContext
and isn't 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 isn't 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 toTrackValue()
that would normally result in a new series returnfalse
.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);
}
Counters in Application Insights
Application Insights supports performance counters and event counters. This guide provides an overview of both, including their purpose, configuration, and usage in .NET applications.
Overview
Performance counters are built into the Windows operating system and offer predefined metrics like CPU usage, memory consumption, and disk activity. These counters are ideal for monitoring standard performance metrics with minimal setup. They help track resource utilization or troubleshoot system-level bottlenecks in Windows-based applications but don't support custom application-specific metrics.
Event counters work across multiple platforms, including Windows, Linux, and macOS. They allow developers to define and monitor lightweight, customizable application-specific metrics, providing more flexibility than performance counters. Event counters are useful when system metrics are insufficient or when detailed telemetry is needed in cross-platform applications. They require explicit implementation and configuration, which makes setup more effort-intensive.
Performance counters
Windows provides various performance counters, such as those used to gather processor, memory, and disk usage statistics. You can also define your own performance counters.
Your application supports performance counter collection if it runs under Internet Information Server (IIS) on an on-premises host or a virtual machine with administrative access. Applications running as Azure Web Apps can't directly access performance counters, but Application Insights collects a subset of available counters.
Tip
Like other metrics, you can set an alert to warn if a counter goes outside a specified limit. To set an alert, open the Alerts pane and select Add Alert.
Prerequisites
Grant the app pool service account permission to monitor performance counters by adding it to the Performance Monitor Users group.
net localgroup "Performance Monitor Users" /add "IIS APPPOOL\NameOfYourPool"
View counters
The Metrics pane shows the default set of performance counters.
Default counters for ASP.NET web applications:
- % Process\Processor Time
- % Process\Processor Time Normalized
- Memory\Available Bytes
- ASP.NET Requests/Sec
- .NET Common Language Runtime (CLR) Exceptions Thrown / sec
- ASP.NET ApplicationsRequest Execution Time
- Process\Private Bytes
- Process\IO Data Bytes/sec
- ASP.NET Applications\Requests In Application Queue
- Processor(_Total)\% Processor Time
Add counters
If the performance counter you want isn't included in the list of metrics, you can add it.
Option 1: Configuration in ApplicationInsights.config
Find out what counters are available in your server by using this PowerShell command on the local server:
Get-Counter -ListSet *
For more information, see
Get-Counter
.Open
ApplicationInsights.config
.If you added Application Insights to your app during development:
- Edit
ApplicationInsights.config
in your project. - Redeploy it to your servers.
- Edit
Edit the performance collector directive:
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector"> <Counters> <Add PerformanceCounter="\Objects\Processes"/> <Add PerformanceCounter="\Sales(photo)\# Items Sold" ReportAs="Photo sales"/> </Counters> </Add>
You capture both standard counters and counters you implement yourself. \Objects\Processes
is an example of a standard counter that's available on all Windows systems. \Sales(photo)\# Items Sold
is an example of a custom counter that might be implemented in a web service.
The format is \Category(instance)\Counter
, or for categories that don't have instances, just \Category\Counter
.
The ReportAs
parameter is required for counter names that don't match [a-zA-Z()/-_ \.]+
.
If you specify an instance, it becomes a dimension CounterInstanceName
of the reported metric.
Option 2: Configuration in code
See the following section.
Collect performance counters in code for ASP.NET web applications or .NET/.NET Core console applications
To collect system performance counters and send them to Application Insights, you can adapt the following snippet:
var perfCollectorModule = new PerformanceCollectorModule();
perfCollectorModule.Counters.Add(new PerformanceCounterCollectionRequest(
@"\Process([replace-with-application-process-name])\Page Faults/sec", "PageFaultsPerfSec"));
perfCollectorModule.Initialize(TelemetryConfiguration.Active);
Or you can do the same thing with custom metrics that you created:
var perfCollectorModule = new PerformanceCollectorModule();
perfCollectorModule.Counters.Add(new PerformanceCounterCollectionRequest(
@"\Sales(photo)\# Items Sold", "Photo sales"));
perfCollectorModule.Initialize(TelemetryConfiguration.Active);
Performance counters for applications running in Azure Web Apps and Windows containers on Azure App Service
Both ASP.NET and ASP.NET Core applications deployed to Azure Web Apps run in a special sandbox environment. Applications deployed to Azure App Service can utilize a Windows container or be hosted in a sandbox environment. If the application is deployed in a Windows container, all standard performance counters are available in the container image.
The sandbox environment doesn't allow direct access to system performance counters. However, a limited subset of counters is exposed as environment variables as described in Perf Counters exposed as environment variables. Only a subset of counters is available in this environment. For the full list, see Perf Counters exposed as environment variables.
The Application Insights SDK for ASP.NET and ASP.NET Core detects if code is deployed to a web app or a non-Windows container. The detection determines whether it collects performance counters in a sandbox environment or utilizes the standard collection mechanism when hosted on a Windows container or virtual machine.
Log Analytics queries for performance counters
You can search and display performance counter reports in Log Analytics.
The performanceCounters schema exposes the category
, counter
name, and instance
name of each performance counter. In the telemetry for each application, you see only the counters for that application. For example, to see what counters are available:
performanceCounters | summarize count(), avg(value) by category, instance, counter
Here, Instance
refers to the performance counter instance, not the role, or server machine instance. The performance counter instance name typically segments counters, such as processor time, by the name of the process or application.
To get a chart of available memory over the recent period:
performanceCounters | where counter == "Available Bytes" | summarize avg(value), min(value) by bin(timestamp, 1h) | render timechart
Like other telemetry, performanceCounters also has a column cloud_RoleInstance
that indicates the identity of the host server instance on which your app is running. For example, to compare the performance of your app on the different machines:
performanceCounters | where counter == "% Processor Time" and instance == "SendMetrics" | summarize avg(value) by cloud_RoleInstance, bin(timestamp, 1d)
Performance counters FAQ
To review frequently asked questions (FAQ), see Performance counters FAQ.
Event counters
EventCounter
is .NET/.NET Core mechanism to publish and consume counters or statistics. EventCounters are supported in all OS platforms - Windows, Linux, and macOS. It can be thought of as a cross-platform equivalent for the PerformanceCounters that is only supported in Windows systems.
While users can publish any custom event counters to meet their needs, .NET publishes a set of these counters by default. This document walks through the steps required to collect and view event counters (system defined or user defined) in Azure Application Insights.
Tip
Like other metrics, you can set an alert to warn if a counter goes outside a specified limit. To set an alert, open the Alerts pane and select Add Alert.
Using Application Insights to collect EventCounters
Application Insights supports collecting EventCounters
with its EventCounterCollectionModule
, which is part of the newly released NuGet package Microsoft.ApplicationInsights.EventCounterCollector. EventCounterCollectionModule
is automatically enabled when using either AspNetCore or WorkerService. EventCounterCollectionModule
collects counters with a nonconfigurable collection frequency of 60 seconds. There are no special permissions required to collect EventCounters. For ASP.NET Core applications, you also want to add the Microsoft.ApplicationInsights.AspNetCore package.
dotnet add package Microsoft.ApplicationInsights.EventCounterCollector
dotnet add package Microsoft.ApplicationInsights.AspNetCore
Default counters collected
Starting with 2.15.0 version of either AspNetCore SDK or WorkerService SDK, no counters are collected by default. The module itself is enabled, so users can add the desired counters to collect them.
To get a list of well known counters published by the .NET Runtime, see Available Counters document.
Customizing counters to be collected
The following example shows how to add/remove counters. This customization would be done as part of your application service configuration after Application Insights telemetry collection is enabled using either AddApplicationInsightsTelemetry()
or AddApplicationInsightsWorkerService()
. Following is an example code from an ASP.NET Core application. For other type of applications, refer to this document.
using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector;
using Microsoft.Extensions.DependencyInjection;
builder.Services.ConfigureTelemetryModule<EventCounterCollectionModule>(
(module, o) =>
{
// Removes all default counters, if any.
module.Counters.Clear();
// Adds a user defined counter "MyCounter" from EventSource named "MyEventSource"
module.Counters.Add(
new EventCounterCollectionRequest("MyEventSource", "MyCounter"));
// Adds the system counter "gen-0-size" from "System.Runtime"
module.Counters.Add(
new EventCounterCollectionRequest("System.Runtime", "gen-0-size"));
}
);
Disabling EventCounter collection module
EventCounterCollectionModule
can be disabled by using ApplicationInsightsServiceOptions
.
The following example uses the ASP.NET Core SDK.
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
using Microsoft.Extensions.DependencyInjection;
var applicationInsightsServiceOptions = new ApplicationInsightsServiceOptions();
applicationInsightsServiceOptions.EnableEventCounterCollectionModule = false;
builder.Services.AddApplicationInsightsTelemetry(applicationInsightsServiceOptions);
A similar approach can be used for the WorkerService SDK as well, but the namespace must be changed as shown in the following example.
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
using Microsoft.Extensions.DependencyInjection;
var applicationInsightsServiceOptions = new ApplicationInsightsServiceOptions();
applicationInsightsServiceOptions.EnableEventCounterCollectionModule = false;
builder.Services.AddApplicationInsightsTelemetry(applicationInsightsServiceOptions);
Log Analytics queries for event counters
You can search and display event counter reports in Log Analytics, in the customMetrics table.
For example, run the following query to see what counters are collected and available to query:
customMetrics | summarize avg(value) by name
To get a chart of a specific counter (for example: ThreadPool Completed Work Item Count
) over the recent period, run the following query.
customMetrics
| where name contains "System.Runtime|ThreadPool Completed Work Item Count"
| where timestamp >= ago(1h)
| summarize avg(value) by cloud_RoleInstance, bin(timestamp, 1m)
| render timechart
Like other telemetry, customMetrics also has a column cloud_RoleInstance
that indicates the identity of the host server instance on which your app is running. The prior query shows the counter value per instance, and can be used to compare performance of different server instances.
Event counters FAQ
To review frequently asked questions (FAQ), see Event counters FAQ.
Configure the Application Insights SDK
In this section
- Telemetry channels
- Telemetry modules
- Disable telemetry
- Telemetry initializers
- Telemetry processor
- ApplicationId Provider
- Snapshot collection
- Sampling
- Enrich and correlate over HTTP
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. After compiling, it gets copied to the bin folder. It's also added to a web app by Application Insights Agent on an IIS server.
Important
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.
Telemetry channels
Telemetry channels are an integral part of the Application Insights SDKs. They manage buffering and transmission of telemetry to the Application Insights service. The .NET and .NET Core versions of the SDKs have two built-in telemetry channels: InMemoryChannel
and ServerTelemetryChannel
. This article describes each channel and shows how to customize channel behavior.
Note
To review frequently asked questions (FAQ), see Telemetry channels FAQ
What are telemetry channels?
Telemetry channels are responsible for buffering telemetry items and sending them to the Application Insights service, where they're stored for querying and analysis. A telemetry channel is any class that implements the Microsoft.ApplicationInsights.ITelemetryChannel
interface.
The Send(ITelemetry item)
method of a telemetry channel is called after all telemetry initializers and telemetry processors are called. So, any items dropped by a telemetry processor doesn't reach the channel. The Send()
method doesn't ordinarily send the items to the back end instantly. Typically, it buffers them in memory and sends them in batches for efficient transmission.
Avoid calling Flush()
unless it's critical to send buffered telemetry immediately. Use it only in scenarios like application shutdown, exception handling, or when using short-lived processes such as background jobs or command-line tools. In web applications or long-running services, the SDK handles telemetry sending automatically. Calling Flush()
unnecessarily can cause performance problems.
Live Metrics Stream also has a custom channel that powers the live streaming of telemetry. This channel is independent of the regular telemetry channel, and this document doesn't apply to it.
Built-in telemetry channels
The Application Insights .NET and .NET Core SDKs ship with two built-in channels:
InMemoryChannel: A lightweight channel that buffers items in memory until they're sent. Items are buffered in memory and flushed once every 30 seconds, or whenever 500 items are buffered. This channel offers minimal reliability guarantees because it doesn't retry sending telemetry after a failure. This channel also doesn't keep items on disk. So any unsent items are lost permanently upon application shutdown, whether it's graceful or not. This channel implements a
Flush()
method that can be used to force-flush any in-memory telemetry items synchronously. This channel is well suited for short-running applications where a synchronous flush is ideal.This channel is part of the larger Microsoft.ApplicationInsights NuGet package and is the default channel that the SDK uses when nothing else is configured.
ServerTelemetryChannel: A more advanced channel that has retry policies and the capability to store data on a local disk. This channel retries sending telemetry if transient errors occur. This channel also uses local disk storage to keep items on disk during network outages or high telemetry volumes. Because of these retry mechanisms and local disk storage, this channel is considered more reliable. We recommend it for all production scenarios. This channel is the default for ASP.NET and ASP.NET Core applications that are configured according to the official documentation. This channel is optimized for server scenarios with long-running processes. The
Flush()
method that's implemented by this channel isn't synchronous.This channel is shipped as the Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel NuGet package and is acquired automatically when you use either the Microsoft.ApplicationInsights.Web or Microsoft.ApplicationInsights.AspNetCore NuGet package.
Configure a telemetry channel
You configure a telemetry channel by setting it to the active telemetry configuration. For ASP.NET applications, configuration involves setting the telemetry channel instance to TelemetryConfiguration.Active
or by modifying ApplicationInsights.config
. For ASP.NET Core applications, configuration involves adding the channel to the dependency injection container.
The following sections show examples of configuring the StorageFolder
setting for the channel in various application types. StorageFolder
is just one of the configurable settings. For the full list of configuration settings, see the Configurable settings in channels section later in this article.
Option 1: Configuration in code
The following code sets up a ServerTelemetryChannel
instance with StorageFolder
set to a custom location. Add this code at the beginning of the application, typically in the Application_Start()
method in Global.aspx.cs.
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
protected void Application_Start()
{
var serverTelemetryChannel = new ServerTelemetryChannel();
serverTelemetryChannel.StorageFolder = @"d:\temp\applicationinsights";
serverTelemetryChannel.Initialize(TelemetryConfiguration.Active);
TelemetryConfiguration.Active.TelemetryChannel = serverTelemetryChannel;
}
Option 2: Configuration in ApplicationInsights.config
The following section from ApplicationInsights.config shows the ServerTelemetryChannel
channel configured with StorageFolder
set to a custom location:
<TelemetrySinks>
<Add Name="default">
<TelemetryProcessors>
<!-- Telemetry processors omitted for brevity -->
</TelemetryProcessors>
<TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel">
<StorageFolder>d:\temp\applicationinsights</StorageFolder>
</TelemetryChannel>
</Add>
</TelemetrySinks>
Configuration in code for console applications
For console apps, the code is the same for both .NET and .NET Core:
var serverTelemetryChannel = new ServerTelemetryChannel();
serverTelemetryChannel.StorageFolder = @"d:\temp\applicationinsights";
serverTelemetryChannel.Initialize(TelemetryConfiguration.Active);
TelemetryConfiguration.Active.TelemetryChannel = serverTelemetryChannel;
Operational details of ServerTelemetryChannel
ServerTelemetryChannel
stores arriving items in an in-memory buffer. The items are serialized, compressed, and stored into a Transmission
instance once every 30 seconds, or when 500 items are buffered. A single Transmission
instance contains up to 500 items and represents a batch of telemetry that's sent over a single HTTPS call to the Application Insights service.
By default, a maximum of 10 Transmission
instances can be sent in parallel. If telemetry is arriving at faster rates, or if the network or the Application Insights back end is slow, Transmission
instances are stored in memory. The default capacity of this in-memory Transmission
buffer is 5 MB. When the in-memory capacity is exceeded, Transmission
instances are stored on local disk up to a limit of 50 MB.
Transmission
instances are stored on local disk also when there are network problems. Only those items that are stored on a local disk survive an application crash. They're sent whenever the application starts again. If network issues persist, ServerTelemetryChannel
uses an exponential backoff logic ranging from 10 seconds to 1 hour before retrying to send telemetry.
Configurable settings in channels
For the full list of configurable settings for each channel, see:
Here are the most commonly used settings for ServerTelemetryChannel
:
MaxTransmissionBufferCapacity
: The maximum amount of memory, in bytes, used by the channel to buffer transmissions in memory. When this capacity is reached, new items are stored directly to local disk. The default value is 5 MB. Setting a higher value leads to less disk usage, but remember that items in memory are lost if the application crashes.MaxTransmissionSenderCapacity
: The maximum number ofTransmission
instances that are sent to Application Insights at the same time. The default value is 10. This setting can be configured to a higher number, which we recommend when a huge volume of telemetry is generated. High volume typically occurs during load testing or when sampling is turned off.StorageFolder
: The folder that's used by the channel to store items to disk as needed. In Windows, either %LOCALAPPDATA% or %TEMP% is used if no other path is specified explicitly. In environments other than Windows, you must specify a valid location or telemetry isn't stored to local disk.
Which channel should I use?
We recommend ServerTelemetryChannel
for most production scenarios that involve long-running applications. For more about flushing telemetry, read about using Flush()
.
When to use Flush()
The Flush()
method sends any buffered telemetry immediately. However, it should only be used in specific scenarios.
Use Flush()
when:
- The application is about to shut down and you want to ensure telemetry is sent before exit.
- You're in an exception handler and need to guarantee telemetry is delivered.
- You're writing a short-lived process like a background job or CLI tool that exits quickly.
Avoid using Flush()
in long-running applications such as web services. The SDK automatically manages buffering and transmission. Calling Flush()
unnecessarily can cause performance problems and doesn't guarantee all data is sent, especially when using ServerTelemetryChannel
, which doesn't flush synchronously.
Telemetry modules
Application Insights automatically collects telemetry about specific workloads without requiring manual tracking by user.
By default, the following automatic-collection modules are enabled. You can disable or configure them to alter their default behavior.
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.
Area | Description |
---|---|
Request tracking | Collects request telemetry (response time, result code) for incoming web requests. Module: Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule NuGet: Microsoft.ApplicationInsights.Web |
Dependency tracking | Collects telemetry about outgoing dependencies (HTTP calls, SQL calls). To work in IIS, install Application Insights Agent. You can also write custom dependency tracking using TrackDependency API. Supports autoinstrumentation with App Service and VM/VMSS monitoring. Module: Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule NuGet: Microsoft.ApplicationInsights.DependencyCollector |
Performance counters | Collects Windows Performance Counters (CPU, memory, network load from IIS installs). Specify which counters (including custom ones). For more information, see Collects system performance counters. Module: Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule NuGet:Microsoft.ApplicationInsights.PerfCounterCollector |
Event counters | Collects .NET EventCounters. Recommended for ASP.NET Core and cross‑platform in place of Windows perf counters. Module: EventCounterCollectionModule (SDK ≥ 2.8.0) |
Live Metrics (QuickPulse) | Collects telemetry for Live Metrics pane. Module: QuickPulseTelemetryModule |
Heartbeats (App Service) | Sends heartbeats and custom metrics for App Service environment. Module: AppServicesHeartbeatTelemetryModule |
Heartbeats (VM/VMSS) | Sends heartbeats and custom metrics for Azure VM environment. Module: AzureInstanceMetadataTelemetryModule |
Diagnostics telemetry | Reports errors in Application Insights instrumentation code (for example, missing counters, ITelemetryInitializer exceptions). Trace telemetry appears in Diagnostic Search.Module: Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule NuGet: Microsoft.ApplicationInsights Note: If you only install this package, the ApplicationInsights.config file isn't automatically created. |
Developer mode (debugger attached) | Forces TelemetryChannel to send items immediately when debugger is attached. Reduces latency but increases CPU/network overhead.Module: Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule NuGet: Application Insights Windows Server |
Exception tracking (Web) | Tracks unhandled exceptions in web apps. See Failures and exceptions. Module: Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule NuGet: Microsoft.ApplicationInsights.Web |
Exception tracking (Unobserved/Unhandled) | Tracks unobserved task exceptions and unhandled exceptions for worker roles, Windows services, and console apps. Modules: • Microsoft.ApplicationInsights.WindowsServer.UnobservedExceptionTelemetryModule • Microsoft.ApplicationInsights.WindowsServer.UnhandledExceptionTelemetryModule NuGet: Microsoft.ApplicationInsights.WindowsServer |
EventSource tracking | Sends configured EventSource events to Application Insights as traces. Module: Microsoft.ApplicationInsights.EventSourceListener.EventSourceTelemetryModule NuGet: Microsoft.ApplicationInsights.EventSourceListener |
ETW collector | Sends configured ETW provider events to Application Insights as traces. Module: Microsoft.ApplicationInsights.EtwCollector.EtwCollectorTelemetryModule NuGet: Microsoft.ApplicationInsights.EtwCollector |
Core API (not a module) | Core API used by other telemetry components and for custom telemetry. Module: Microsoft.ApplicationInsights package NuGet: Microsoft.ApplicationInsights Note: If you only install this package, the ApplicationInsights.config file isn't automatically created. |
Configure telemetry modules
Use the TelemetryModules
section in ApplicationInsights.config to configure, add, or remove modules. The following examples:
- Configure
DependencyTrackingTelemetryModule
(enable W3C header injection). - Configure
EventCounterCollectionModule
(clear defaults and add a single counter). - Disable perf‑counter collection by removing
PerformanceCollectorModule
.
<ApplicationInsights>
<TelemetryModules>
<!-- Dependency tracking -->
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
<!-- Match Core example: enable W3C header injection -->
<EnableW3CHeadersInjection>true</EnableW3CHeadersInjection>
</Add>
<!-- EventCounterCollectionModule: add a single counter (if you use event counters) -->
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.EventCounterCollectionModule, Microsoft.AI.PerfCounterCollector">
<Counters>
<!-- Mirrors Core example: only collect 'gen-0-size' from System.Runtime -->
<Add ProviderName="System.Runtime" CounterName="gen-0-size" />
</Counters>
</Add>
<!-- PerformanceCollectorModule (classic Windows performance counters).
To DISABLE perf-counter collection, do NOT include this module.
If it already exists in your file, remove or comment it out.
Example of the line you would remove:
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector" />
-->
</TelemetryModules>
</ApplicationInsights>
Note
The exact set of modules present in your ApplicationInsights.config
depends on which SDK packages you installed.
Disable telemetry
There's a node in the configuration file for each module. To disable a module, delete the node or comment it out.
Telemetry initializers
To enrich telemetry with additional information or to override telemetry properties set by the standard telemetry modules, use 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 |
Updates 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. |
Note
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.
To learn how to use telemetry initializers with ASP.NET applications, see Filter and preprocess telemetry in the Application Insights SDK.
Telemetry processors
Telemetry processors can filter and modify each telemetry item before it's sent from the SDK to the portal.
To learn how to use telemetry processors with ASP.NET applications, see Filter and preprocess telemetry in the Application Insights SDK.
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 is 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 connection string, create a new resource in the Application Insights portal.
ApplicationId Provider
Note
For ASP.NET, this provider is available starting in SDK 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
.
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 automatically included when you install either Microsoft.ApplicationInsights.DependencyCollector or Microsoft.ApplicationInsights.Web.
The class exposes an optional property called ProfileQueryEndpoint
. By default, it's set to https://dc.services.visualstudio.com/api/profiles/{0}/appId
.
If you need to configure a proxy, we recommend proxying the base address and ensuring the path includes /api/profiles/{0}/appId
. At runtime, {0}
is replaced with the instrumentation key for each request.
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
To learn how to configure snapshot collection for ASP.NET and ASP.NET Core applications, see Enable Snapshot Debugger for .NET apps in Azure Service Fabric, Cloud Services, and Virtual Machines.
Sampling
To learn how to configure sampling for ASP.NET and ASP.NET Core applications, see Sampling in Application Insights.
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
- To review frequently asked questions (FAQ), see Applications Insights for ASP.NET FAQ and Application Insights for ASP.NET Core FAQ.
- Validate you're running a supported version of the Application Insights SDK.
- Add synthetic transactions to test that your website is available from all over the world with availability monitoring.
- Explore user flows to understand how users move through your app.
- Configure a snapshot collection to see the state of source code and variables at the moment an exception is thrown.
- Use the API to send your own events and metrics for a detailed view of your app's performance and usage.