Instrument your ASP.NET Core application with OpenTelemetry NuGet packages and send HTTP, Kestrel, and .NET runtime metrics to SigNoz.
Prerequisites
- .NET 10 or later
- An instance of SigNoz (either Cloud or Self-Hosted)
Send Metrics to SigNoz
Step 1. Add NuGet packages
<ItemGroup>
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
</ItemGroup>
Or with the .NET CLI:
dotnet add package OpenTelemetry.Extensions.Hosting --version 1.15.3
dotnet add package OpenTelemetry.Instrumentation.AspNetCore --version 1.15.2
dotnet add package OpenTelemetry.Instrumentation.Runtime --version 1.15.1
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol --version 1.15.3
Step 2. Configure OpenTelemetry in Program.cs
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
var builder = WebApplication.CreateBuilder(args);
var serviceName = Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME") ?? "my-aspnetcore-app";
builder.Services.AddOpenTelemetry()
.ConfigureResource(r => r.AddService(serviceName))
.WithMetrics(m => m
.AddAspNetCoreInstrumentation()
.AddRuntimeInstrumentation()
.AddMeter("Microsoft.AspNetCore.MemoryPool")
.AddOtlpExporter());
var app = builder.Build();
// ... your routes ...
app.Run();
The OTel SDK reads OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, and OTEL_EXPORTER_OTLP_PROTOCOL automatically.
.AddMeter("Microsoft.AspNetCore.MemoryPool") enables aspnetcore.memory_pool.* metrics, which only emit on .NET 10+. On .NET 8 or 9, all other HTTP, Kestrel, and runtime metrics populate as expected. The memory pool panels stay empty.
Step 3. Set environment variables
export OTEL_SERVICE_NAME="my-aspnetcore-app"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production"
$env:OTEL_SERVICE_NAME = "my-aspnetcore-app"
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://ingest.<region>.signoz.cloud:443"
$env:OTEL_EXPORTER_OTLP_HEADERS = "signoz-ingestion-key=<your-ingestion-key>"
$env:OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
$env:OTEL_RESOURCE_ATTRIBUTES = "deployment.environment=production"
docker run \
-e OTEL_SERVICE_NAME="my-aspnetcore-app" \
-e OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443" \
-e OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>" \
-e OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \
-e OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production" \
your-image:latest
env:
- name: OTEL_SERVICE_NAME
value: "my-aspnetcore-app"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://ingest.<region>.signoz.cloud:443"
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "signoz-ingestion-key=<your-ingestion-key>"
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: "http/protobuf"
- name: OTEL_RESOURCE_ATTRIBUTES
value: "deployment.environment=production"
Verify these values:
<region>: Your SigNoz Cloud region<your-ingestion-key>: Your ingestion keyOTEL_RESOURCE_ATTRIBUTES: Setsdeployment.environmenton all telemetry — the ASP.NET Core Metrics dashboard uses this to filter by environment
Step 4. Validate
Start your application, send some requests, then open SigNoz.
- Go to Metrics > Metrics Explorer.
- Search for
http.server.request.duration.
Metrics appear within the first export interval (default: 60 seconds).

Troubleshooting
Metrics not appearing
Check that OTEL_EXPORTER_OTLP_ENDPOINT is reachable from your application host. Look for OpenTelemetry startup messages in the application logs — the SDK logs the endpoint and exporter configuration at startup.
Metrics delayed
The default export interval is 60 seconds. Reduce it for faster feedback during development:
OTEL_METRIC_EXPORT_INTERVAL=10000
Authentication errors
Verify the header is exactly signoz-ingestion-key=<your-key> with no extra spaces or quotes.
Metric aspnetcore.memory_pool.* not appearing
These metrics require .NET 10+ and only emit when Kestrel reads request bodies. Add POST endpoints that read req.Body to trigger them.
Next steps
- ASP.NET Core Metrics dashboard — import the pre-built dashboard for this setup
- Set up alerts on your metrics
- Send traces from your .NET application