OpenTelemetry.Instrumentation.AspNetCore 1.13.0

Prefix Reserved
dotnet add package OpenTelemetry.Instrumentation.AspNetCore --version 1.13.0
                    
NuGet\Install-Package OpenTelemetry.Instrumentation.AspNetCore -Version 1.13.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.13.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.13.0" />
                    
Directory.Packages.props
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OpenTelemetry.Instrumentation.AspNetCore --version 1.13.0
                    
#r "nuget: OpenTelemetry.Instrumentation.AspNetCore, 1.13.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OpenTelemetry.Instrumentation.AspNetCore@1.13.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OpenTelemetry.Instrumentation.AspNetCore&version=1.13.0
                    
Install as a Cake Addin
#tool nuget:?package=OpenTelemetry.Instrumentation.AspNetCore&version=1.13.0
                    
Install as a Cake Tool

ASP.NET Core Instrumentation for OpenTelemetry .NET

Status
Stability Stable
Code Owners @open-telemetry/dotnet-contrib-maintainers

NuGet NuGet codecov.io

This is an Instrumentation Library, which instruments ASP.NET Core and collect metrics and traces about incoming web requests. This instrumentation also collects traces from incoming gRPC requests using Grpc.AspNetCore. Instrumentation support for gRPC server requests is supported via an experimental feature flag.

This component is based on the v1.23 of http semantic conventions. For details on the default set of attributes that are added, checkout Traces and Metrics sections below.

Steps to enable OpenTelemetry.Instrumentation.AspNetCore

Step 1: Install Package

Add a reference to the OpenTelemetry.Instrumentation.AspNetCore package. Also, add any other instrumentations & exporters you will need.

dotnet add package OpenTelemetry.Instrumentation.AspNetCore

Step 2: Enable ASP.NET Core Instrumentation at application startup

ASP.NET Core instrumentation must be enabled at application startup. This is typically done in the ConfigureServices of your Startup class. Both examples below enables OpenTelemetry by calling AddOpenTelemetry() on IServiceCollection. This extension method requires adding the package OpenTelemetry.Extensions.Hosting to the application. This ensures instrumentations are disposed when the host is shutdown.

Traces

The following example demonstrates adding ASP.NET Core instrumentation with the extension method WithTracing() on OpenTelemetryBuilder. then extension method AddAspNetCoreInstrumentation() on TracerProviderBuilder to the application. This example also sets up the Console Exporter, which requires adding the package OpenTelemetry.Exporter.Console to the application.

using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Trace;

public void ConfigureServices(IServiceCollection services)
{
    services.AddOpenTelemetry()
        .WithTracing(builder => builder
            .AddAspNetCoreInstrumentation()
            .AddConsoleExporter());
}

Following list of attributes are added by default on activity. See http-spans for more details about each individual attribute:

  • error.type
  • http.request.method
  • http.request.method_original
  • http.response.status_code
  • http.route
  • network.protocol.version
  • user_agent.original
  • server.address
  • server.port
  • url.path
  • url.query - By default, the values in the query component are replaced with the text Redacted. For example, ?key1=value1&key2=value2 becomes ?key1=Redacted&key2=Redacted. You can disable this redaction by setting the environment variable OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION to true.
  • url.scheme

Enrich Api can be used if any additional attributes are required on activity.

Metrics

The following example demonstrates adding ASP.NET Core instrumentation with the extension method WithMetrics() on OpenTelemetryBuilder then extension method AddAspNetCoreInstrumentation() on MeterProviderBuilder to the application. This example also sets up the Console Exporter, which requires adding the package OpenTelemetry.Exporter.Console to the application.

using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Metrics;

public void ConfigureServices(IServiceCollection services)
{
    services.AddOpenTelemetry()
        .WithMetrics(builder => builder
            .AddAspNetCoreInstrumentation()
            .AddConsoleExporter());
}

Following list of attributes are added by default on http.server.request.duration metric. See http-metrics for more details about each individual attribute. .NET8.0 and above supports additional metrics, see list of metrics produced for more details.

  • error.type
  • http.response.status_code
  • http.request.method
  • http.route
  • network.protocol.version
  • url.scheme
List of metrics produced

When the application targets .NET6.0 or .NET7.0, the instrumentation emits the following metric:

Name Details
http.server.request.duration Specification

Starting from .NET8.0, metrics instrumentation is natively implemented, and the ASP.NET Core library has incorporated support for built-in metrics following the OpenTelemetry semantic conventions. The library includes additional metrics beyond those defined in the specification, covering additional scenarios for ASP.NET Core users. When the application targets .NET8.0 and newer versions, the instrumentation library automatically enables all built-in metrics by default.

Note that the AddAspNetCoreInstrumentation() extension simplifies the process of enabling all built-in metrics via a single line of code. Alternatively, for more granular control over emitted metrics, you can utilize the AddMeter() extension on MeterProviderBuilder for meters listed in built-in-metrics-aspnetcore. Using AddMeter() for metrics activation eliminates the need to take dependency on the instrumentation library package and calling AddAspNetCoreInstrumentation().

If you utilize AddAspNetCoreInstrumentation() and wish to exclude unnecessary metrics, you can utilize Views to achieve this.

There is no difference in features or emitted metrics when enabling metrics using AddMeter() or AddAspNetCoreInstrumentation() on .NET8.0 and newer versions.

The http.server.request.duration metric is emitted in seconds as per the semantic convention. While the convention recommends using custom histogram buckets , this feature is not yet available via .NET Metrics API. A workaround has been included in OTel SDK starting version 1.6.0 which applies recommended buckets by default for http.server.request.duration. This applies to all targeted frameworks.

Advanced configuration

Tracing

This instrumentation can be configured to change the default behavior by using AspNetCoreTraceInstrumentationOptions, which allows adding Filter, Enrich as explained below.

// TODO: This section could be refined. When used with OpenTelemetry.Extensions.Hosting, all configurations to AspNetCoreTraceInstrumentationOptions can be done in the ConfigureServices method of you applications Startup class as shown below.

// Configure
services.Configure<AspNetCoreTraceInstrumentationOptions>(options =>
{
    options.Filter = (httpContext) =>
    {
        // only collect telemetry about HTTP GET requests
        return httpContext.Request.Method.Equals("GET");
    };
});

services.AddOpenTelemetry()
    .WithTracing(builder => builder
        .AddAspNetCoreInstrumentation()
        .AddConsoleExporter());
Filter

This instrumentation by default collects all the incoming http requests. It allows filtering of requests by using the Filter function in AspNetCoreTraceInstrumentationOptions. This defines the condition for allowable requests. The Filter receives the HttpContext of the incoming request, and does not collect telemetry about the request if the Filter returns false or throws exception.

The following code snippet shows how to use Filter to only allow GET requests.

services.AddOpenTelemetry()
    .WithTracing(builder => builder
        .AddAspNetCoreInstrumentation((options) => options.Filter = httpContext =>
        {
            // only collect telemetry about HTTP GET requests
            return httpContext.Request.Method.Equals("GET");
        })
        .AddConsoleExporter());

It is important to note that this Filter option is specific to this instrumentation. OpenTelemetry has a concept of a Sampler, and the Filter option does the filtering after the Sampler is invoked.

Enrich

This instrumentation library provides EnrichWithHttpRequest, EnrichWithHttpResponse and EnrichWithException options that can be used to enrich the activity with additional information from the raw HttpRequest, HttpResponse and Exception objects respectively. These actions are called only when activity.IsAllDataRequested is true. It contains the activity itself (which can be enriched) and the actual raw object.

The following code snippet shows how to enrich the activity using all 3 different options.

services.AddOpenTelemetry()
    .WithTracing(builder => builder
        .AddAspNetCoreInstrumentation(o =>
        {
            o.EnrichWithHttpRequest = (activity, httpRequest) =>
            {
                activity.SetTag("requestProtocol", httpRequest.Protocol);
            };
            o.EnrichWithHttpResponse = (activity, httpResponse) =>
            {
                activity.SetTag("responseLength", httpResponse.ContentLength);
            };
            o.EnrichWithException = (activity, exception) =>
            {
                if (exception.Source != null)
                {
                    activity.SetTag("exception.source", exception.Source);
                }
            };
        }));

Processor, is the general extensibility point to add additional properties to any activity. The Enrich option is specific to this instrumentation, and is provided to get access to HttpRequest and HttpResponse.

When overriding the default settings provided by instrumentation or adding additional telemetry, it is important to consider the sequence of callbacks. Generally, it is recommended to use EnrichWithHttpResponse for any activity enrichment that does not need access to exceptions, as the instrumentation library populates all telemetry following the OTel specification before this callback. The following is the sequence in which these callbacks are executed:

  1. Processor OnStart
  2. EnrichWithHttpRequest
  3. EnrichWithException
  4. EnrichWithHttpResponse
  5. Processor OnEnd

As an example, if you need to override the default DisplayName or tags set by the library you can do so as follows:

.AddAspNetCoreInstrumentation(o =>
{
  o.EnrichWithHttpResponse = (activity, response) =>
  {
      // Access request object if needed
      // response.HttpContext.Request
      activity.DisplayName = "CustomDisplayName";

      // Overrides the value
      activity.SetTag("http.route", "CustomRoute");

      // Removes the tag
      activity.SetTag("network.protocol.version", null);
  };
});
RecordException

This instrumentation automatically sets Activity Status to Error if an unhandled exception is thrown. Additionally, RecordException feature may be turned on, to store the exception to the Activity itself as ActivityEvent.

Activity duration and http.server.request.duration metric calculation

Activity.Duration and http.server.request.duration values represents the time used to handle an inbound HTTP request as measured at the hosting layer of ASP.NET Core. The time measurement starts once the underlying web host has:

  • Sufficiently parsed the HTTP request headers on the inbound network stream to identify the new request.
  • Initialized the context data structures such as the HttpContext.

The time ends when:

  • The ASP.NET Core handler pipeline is finished executing.
  • All response data has been sent.
  • The context data structures for the request are being disposed.

Experimental support for gRPC requests

gRPC instrumentation can be enabled by setting OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION flag to True. The flag can be set as an environment variable or via IConfiguration as shown below.

var appBuilder = WebApplication.CreateBuilder(args);

appBuilder.Configuration.AddInMemoryCollection(
    new Dictionary<string, string?>
    {
        ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = "true",
    });

appBuilder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
    .AddAspNetCoreInstrumentation());

Semantic conventions for RPC are still experimental and hence the instrumentation only offers it as an experimental feature.

Troubleshooting

This component uses an EventSource with the name "OpenTelemetry-Instrumentation-AspNetCore" for its internal logging. Please refer to SDK troubleshooting for instructions on seeing these internal logs.

References

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (361)

Showing the top 5 NuGet packages that depend on OpenTelemetry.Instrumentation.AspNetCore:

Package Downloads
Azure.Monitor.OpenTelemetry.AspNetCore

An OpenTelemetry .NET distro that exports to Azure Monitor

OpenTelemetry.AutoInstrumentation.Runtime.Managed

Managed components used by the OpenTelemetry.AutoInstrumentation project.

Sitko.Core.App.Web

Sitko.Core is a set of libraries to help build .NET Core applications fast

AspNetCore.SignalR.OpenTelemetry

SignalR instrumentation for OpenTelemetry .NET

Grafana.OpenTelemetry

Full Grafana distribution of OpenTelemetry .NET

GitHub repositories (161)

Showing the top 20 popular GitHub repositories that depend on OpenTelemetry.Instrumentation.AspNetCore:

Repository Stars
microsoft/semantic-kernel
Integrate cutting-edge LLM technology quickly and easily into your apps
ardalis/CleanArchitecture
Clean Architecture Solution Template: A proven Clean Architecture Template for ASP.NET Core 9
dotnet/runtime
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
dotnet/AspNetCore.Docs
Documentation for ASP.NET Core
JustArchiNET/ArchiSteamFarm
C# application with primary purpose of farming Steam cards from multiple accounts simultaneously.
dotnet/orleans
Cloud Native application framework for .NET
dodyg/practical-aspnetcore
Practical samples of ASP.NET Core 10 RC 1, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.
dotnet/eShop
A reference .NET application implementing an eCommerce site
dotnet/yarp
A toolkit for developing high-performance HTTP reverse proxy applications.
quartznet/quartznet
Quartz Enterprise Scheduler .NET
fullstackhero/dotnet-starter-kit
Production Grade Cloud-Ready .NET 9 Starter Kit (Web API + Blazor Client) with Multitenancy Support, and Clean/Modular Architecture that saves roughly 200+ Development Hours! All Batteries Included.
Azure/azure-sdk-for-net
This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
dotnet/aspire
Aspire is the tool for code-first, extensible, observable dev and deploy.
microsoft/fluentui-blazor
Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
grpc/grpc-dotnet
gRPC for .NET
ravendb/ravendb
ACID Document Database
oskardudycz/EventSourcing.NetCore
Examples and Tutorials of Event Sourcing in .NET
open-telemetry/opentelemetry-dotnet
The OpenTelemetry .NET Client
thomhurst/TUnit
A modern, fast and flexible .NET testing framework
Dotnet-Boxed/Templates
.NET project templates with batteries included, providing the minimum amount of code required to get you going faster.
Version Downloads Last Updated
1.13.0 1,210 10/22/2025
1.12.0 16,436,949 5/5/2025
1.11.1 8,770,619 3/5/2025
1.11.0 4,620,744 1/27/2025
1.10.1 4,343,600 12/10/2024
1.10.0 505,668 12/9/2024
1.9.0 43,174,375 6/17/2024
1.8.1 25,486,490 4/12/2024
1.8.0 540,597 4/4/2024 1.8.0 is deprecated; 1.8.0 has at least one vulnerability with moderate severity.
1.7.1 3,623,984 2/10/2024 1.7.1 is deprecated; 1.7.1 has at least one vulnerability with moderate severity.
1.7.0 6,000,672 12/14/2023 1.7.0 is deprecated; 1.7.0 has at least one vulnerability with moderate severity.
1.6.0 1,311,961 12/14/2023 1.6.0 is deprecated; 1.6.0 has at least one vulnerability with moderate severity.
1.6.0-rc.1 399,506 12/2/2023 1.6.0-rc.1 is deprecated; 1.6.0-rc.1 has at least one vulnerability with moderate severity.
1.6.0-beta.3 1,012,939 11/17/2023 1.6.0-beta.3 is deprecated; 1.6.0-beta.3 has at least one vulnerability with moderate severity.
1.6.0-beta.2 720,723 10/27/2023 1.6.0-beta.2 is deprecated; 1.6.0-beta.2 has at least one vulnerability with moderate severity.
1.5.1-beta.1 6,930,106 7/21/2023 1.5.1-beta.1 is deprecated; 1.5.1-beta.1 has at least one vulnerability with moderate severity.
1.5.0-beta.1 2,562,288 6/6/2023 1.5.0-beta.1 is deprecated; 1.5.0-beta.1 has at least one vulnerability with moderate severity.
1.0.0-rc9.14 10,987,150 2/24/2023 1.0.0-rc9.14 is deprecated; 1.0.0-rc9.14 has at least one vulnerability with moderate severity.
1.0.0-rc9.13 888,233 2/11/2023 1.0.0-rc9.13 is deprecated; 1.0.0-rc9.13 has at least one vulnerability with moderate severity.
1.0.0-rc9.12 650,294 2/2/2023 1.0.0-rc9.12 is deprecated; 1.0.0-rc9.12 has at least one vulnerability with moderate severity.
1.0.0-rc9.11 743,105 1/9/2023 1.0.0-rc9.11 is deprecated; 1.0.0-rc9.11 has at least one vulnerability with moderate severity.
1.0.0-rc9.10 1,053,576 12/12/2022 1.0.0-rc9.10 is deprecated; 1.0.0-rc9.10 has at least one vulnerability with moderate severity.
1.0.0-rc9.9 1,768,139 11/7/2022 1.0.0-rc9.9 is deprecated; 1.0.0-rc9.9 has at least one vulnerability with moderate severity.
1.0.0-rc9.8 443,391 10/17/2022 1.0.0-rc9.8 is deprecated; 1.0.0-rc9.8 has at least one vulnerability with moderate severity.
1.0.0-rc9.7 315,836 9/30/2022 1.0.0-rc9.7 is deprecated; 1.0.0-rc9.7 has at least one vulnerability with moderate severity.
1.0.0-rc9.6 1,531,126 8/18/2022 1.0.0-rc9.6 is deprecated; 1.0.0-rc9.6 has at least one vulnerability with moderate severity.
1.0.0-rc9.5 1,309,427 8/3/2022 1.0.0-rc9.5 is deprecated; 1.0.0-rc9.5 has at least one vulnerability with moderate severity.
1.0.0-rc9.4 7,328,846 6/3/2022 1.0.0-rc9.4 is deprecated; 1.0.0-rc9.4 has at least one vulnerability with moderate severity.
1.0.0-rc9.3 2,532,970 4/20/2022 1.0.0-rc9.3 is deprecated; 1.0.0-rc9.3 has at least one vulnerability with moderate severity.
1.0.0-rc9.2 2,020,892 4/13/2022 1.0.0-rc9.2 is deprecated; 1.0.0-rc9.2 has at least one vulnerability with moderate severity.
1.0.0-rc9.1 774,658 3/30/2022 1.0.0-rc9.1 is deprecated; 1.0.0-rc9.1 has at least one vulnerability with moderate severity.
1.0.0-rc9 3,060,430 2/3/2022 1.0.0-rc9 is deprecated; 1.0.0-rc9 has at least one vulnerability with moderate severity.
1.0.0-rc8 6,493,161 10/8/2021 1.0.0-rc8 is deprecated; 1.0.0-rc8 has at least one vulnerability with moderate severity.
1.0.0-rc7 2,054,795 7/13/2021 1.0.0-rc7 is deprecated; 1.0.0-rc7 has at least one vulnerability with moderate severity.
1.0.0-rc6 374,517 6/26/2021 1.0.0-rc6 is deprecated; 1.0.0-rc6 has at least one vulnerability with moderate severity.
1.0.0-rc5 456,594 6/9/2021 1.0.0-rc5 is deprecated; 1.0.0-rc5 has at least one vulnerability with moderate severity.
1.0.0-rc4 372,803 4/23/2021 1.0.0-rc4 is deprecated; 1.0.0-rc4 has at least one vulnerability with moderate severity.
1.0.0-rc3 527,161 3/19/2021 1.0.0-rc3 is deprecated; 1.0.0-rc3 has at least one vulnerability with moderate severity.
1.0.0-rc2 752,081 1/30/2021 1.0.0-rc2 is deprecated; 1.0.0-rc2 has at least one vulnerability with moderate severity.
1.0.0-rc1.1 528,171 11/18/2020 1.0.0-rc1.1 is deprecated; 1.0.0-rc1.1 has at least one vulnerability with moderate severity.
0.8.0-beta.1 98,922 11/5/2020 0.8.0-beta.1 is deprecated; 0.8.0-beta.1 has at least one vulnerability with moderate severity.
0.7.0-beta.1 15,944 10/16/2020 0.7.0-beta.1 is deprecated; 0.7.0-beta.1 has at least one vulnerability with moderate severity.
0.6.0-beta.1 132,243 9/16/2020 0.6.0-beta.1 is deprecated; 0.6.0-beta.1 has at least one vulnerability with moderate severity.
0.5.0-beta.2 10,154 8/28/2020 0.5.0-beta.2 is deprecated; 0.5.0-beta.2 has at least one vulnerability with moderate severity.
0.4.0-beta.2 118,851 7/25/2020 0.4.0-beta.2 is deprecated; 0.4.0-beta.2 has at least one vulnerability with moderate severity.
0.3.0-beta.1 1,499 7/23/2020 0.3.0-beta.1 is deprecated; 0.3.0-beta.1 has at least one vulnerability with moderate severity.