Modern distributed applications are composed of multiple services, APIs, databases, and external dependencies. When a request fails or performance degrades, identifying the root cause becomes challenging without proper observability.
Traditional logging alone is no longer sufficient. Developers need visibility into how requests flow across services, where latency occurs, and which components contribute to failures. This is where OpenTelemetry comes in.
OpenTelemetry is an open-source observability framework that standardizes the collection of logs, metrics, and distributed traces. It enables developers to monitor applications consistently while remaining vendor-neutral.
In this guide, you'll learn how to integrate OpenTelemetry into an ASP.NET Core application and adopt best practices for production environments.
What Is OpenTelemetry?
OpenTelemetry (OTel) provides a unified way to collect telemetry data from applications.
It focuses on three pillars of observability:
Logs – Record application events and errors.
Metrics – Measure application health and performance.
Traces – Track a request across multiple services.
Together, these signals help answer critical questions such as:
Why is an API slow?
Which service caused a failure?
How long does each database call take?
Where is the application's bottleneck?
Unlike vendor-specific SDKs, OpenTelemetry allows you to send telemetry to multiple monitoring platforms without changing application code.
Understanding the OpenTelemetry Architecture
A typical OpenTelemetry workflow looks like this:
ASP.NET Core Application
│
OpenTelemetry SDK
│
Telemetry Data
│
OpenTelemetry Collector (Optional)
│
Monitoring Platform
The SDK collects telemetry, while the optional OpenTelemetry Collector processes and exports data to systems like Azure Monitor, Jaeger, Prometheus, Grafana, or Elastic.
Installing OpenTelemetry
Install the required NuGet packages:
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
dotnet add package OpenTelemetry.Instrumentation.SqlClient
dotnet add package OpenTelemetry.Exporter.Console
These packages enable automatic instrumentation for common ASP.NET Core components.
Configuring OpenTelemetry
Register OpenTelemetry during application startup.
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource =>
resource.AddService("ProductApi"))
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSqlClientInstrumentation()
.AddConsoleExporter();
});
var app = builder.Build();
app.MapControllers();
app.Run();
This configuration automatically captures incoming HTTP requests, outgoing HTTP calls, SQL queries, and exports trace information to the console.
Collecting Metrics
Metrics help monitor application performance over time.
Configure metrics collection:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics
.AddAspNetCoreInstrumentation()
.AddRuntimeInstrumentation()
.AddConsoleExporter();
});
Common metrics include:
Request count
Request duration
CPU usage
Memory consumption
Active requests
These measurements help identify trends before they become production issues.
Understanding Distributed Tracing
Distributed tracing follows a request as it moves through different services.
Example flow:
Client
│
Product API
│
Order API
│
SQL Server
Each operation becomes a span, while the complete request forms a trace.
If a request takes five seconds, tracing reveals how much time was spent in:
ASP.NET Core middleware
Business logic
External API calls
Database queries
This makes performance bottlenecks much easier to identify.
Adding Custom Traces
Automatic instrumentation covers common scenarios, but custom business operations can also be traced.
using System.Diagnostics;
private static readonly ActivitySource ActivitySource =
new("ProductService");
public async Task<Product> GetProductAsync(int id)
{
using var activity = ActivitySource.StartActivity("Get Product");
return await repository.GetByIdAsync(id);
}
Custom spans provide visibility into business workflows that automatic instrumentation cannot detect.
Choosing an Exporter
OpenTelemetry supports multiple exporters depending on your monitoring platform.
| Exporter | Best Use Case |
|---|---|
| Console | Local development |
| Jaeger | Distributed tracing |
| Prometheus | Metrics collection |
| Azure Monitor | Azure-hosted applications |
| OTLP | Vendor-neutral export |
Using the OTLP exporter provides flexibility to switch monitoring platforms without modifying application instrumentation.
Best Practices
Instrument only meaningful operations.
Use descriptive service names.
Add custom spans for critical business processes.
Monitor all three telemetry signals—logs, metrics, and traces.
Avoid collecting sensitive information in telemetry.
Sample traces in high-traffic applications to reduce storage costs.
Centralize telemetry using the OpenTelemetry Collector where appropriate.
Common Mistakes
Relying Only on Logs
Logs explain what happened, but traces reveal where it happened and metrics show how often it occurs. Combining all three signals provides a complete picture.
Instrumenting Everything
Capturing every operation generates excessive telemetry, increasing storage costs and making analysis more difficult. Focus on critical application paths.
Ignoring Sampling
High-volume production systems can generate millions of traces. Configure sampling strategies to balance observability with operational cost.
Exposing Sensitive Data
Avoid recording passwords, authentication tokens, personal information, or confidential business data in logs or traces.
Conclusion
OpenTelemetry has become the standard for observability in modern ASP.NET Core applications. By combining logs, metrics, and distributed traces, it enables developers to understand application behavior, diagnose failures, and optimize performance across distributed systems.
Automatic instrumentation provides immediate visibility into HTTP requests, database operations, and external service calls, while custom spans allow teams to monitor business-specific workflows. Combined with appropriate exporters and thoughtful sampling strategies, OpenTelemetry offers a scalable, vendor-neutral approach to monitoring applications in development and production.
Implementing observability early in the development lifecycle not only simplifies troubleshooting but also helps build resilient, high-performing .NET applications that are easier to maintain as they grow.

Jasen FiciPosted Jul 30, 2026, 12:04 PM
Great writeup — we included it in DotNetNews here: https://dotnetnews.co/archive/the-net-news-daily-issue-508/