DEV Community

Ahmed Omeiza
Ahmed Omeiza

Posted on

OpenTelemetry in .NET: Stop Guessing What Your Application Is Doing

Your API is slow.

But why?

Is the database taking too long?
Is another service failing?
Is an external API responding slowly?

Logs can give you clues, but when you're dealing with a distributed application, logs alone can make debugging painful.

This is where OpenTelemetry comes in.

What is OpenTelemetry?

OpenTelemetry (OTel) is an open-source observability framework for collecting telemetry data from your applications.

It focuses mainly on three types of data:

  • Traces — What happened during a request?
  • Metrics — How is the application performing?
  • Logs — What events are happening?

The goal is simple:

Understand what your application is doing without guessing.


Why Does This Matter in .NET?

Imagine a request going through your application:

Client
  ↓
ASP.NET Core API
  ↓
Order Service
  ↓
Payment Service
  ↓
Database
Enter fullscreen mode Exit fullscreen mode

The user only sees:

Request took 3.2 seconds
Enter fullscreen mode Exit fullscreen mode

But where did those 3.2 seconds go?

OpenTelemetry can give you a trace like:

HTTP Request          3.2s
 ├── Order Service    1.1s
 ├── Payment API      1.7s
 └── Database         0.4s
Enter fullscreen mode Exit fullscreen mode

Now you have something useful.

Instead of saying:

"The API is slow."

You can say:

"The Payment API is responsible for most of the request latency."

That's the difference between logging events and understanding system behavior.


Traces: Following a Request

A trace represents the journey of a request through your system.

Each operation within that journey is represented as a span.

For example:

Trace
│
├── HTTP GET /orders
│
├── SQL Query
│
└── HTTP POST /payments
Enter fullscreen mode Exit fullscreen mode

Each span can contain information such as:

  • Duration
  • Operation name
  • Status
  • Attributes
  • Errors
  • Relationships to other spans

The important part is that these spans can be connected together into one trace.


Metrics: Measuring Performance

Metrics give you numbers about your application.

For example:

HTTP Requests:       15,420
Request Errors:          73
Average Duration:      180ms
Active Requests:          12
Enter fullscreen mode Exit fullscreen mode

Metrics are useful when you want to answer questions like:

"Are errors increasing?"

or:

"Has API latency gotten worse?"


Logs: Understanding Events

Logs record events happening inside your application.

For example:

Order 4821 created
Payment request started
Payment failed
Enter fullscreen mode Exit fullscreen mode

OpenTelemetry can also help correlate logs with traces.

That means you can go from:

Trace → Span → Log
Enter fullscreen mode Exit fullscreen mode

and understand what happened during a specific request.


Setting Up OpenTelemetry in ASP.NET Core

Install the required packages:

dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
dotnet add package OpenTelemetry.Instrumentation.Runtime
Enter fullscreen mode Exit fullscreen mode

Then configure OpenTelemetry in Program.cs:

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing
            .AddAspNetCoreInstrumentation()
            .AddHttpClientInstrumentation()
            .AddOtlpExporter();
    })
    .WithMetrics(metrics =>
    {
        metrics
            .AddAspNetCoreInstrumentation()
            .AddRuntimeInstrumentation()
            .AddOtlpExporter();
    });
Enter fullscreen mode Exit fullscreen mode

Now your application can automatically collect telemetry from common ASP.NET Core and HTTP operations.


Where Does the Data Go?

OpenTelemetry doesn't try to be your dashboard.

Instead, it collects and exports telemetry to an observability backend.

A common architecture looks like this:

.NET Application
       │
       ▼
 OpenTelemetry
       │
       ▼
   OTLP Exporter
       │
       ▼
Observability Backend
       │
       ▼
    Dashboard
Enter fullscreen mode Exit fullscreen mode

You can use tools such as Grafana, Jaeger, Zipkin, or other systems that support OpenTelemetry.

This separation is important.

Your application produces telemetry.

Your observability platform stores, analyzes, and visualizes it.


Automatic vs Manual Instrumentation

OpenTelemetry can automatically instrument many common operations.

For example:

.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
Enter fullscreen mode Exit fullscreen mode

This can give you useful telemetry without manually creating spans for every request.

But sometimes you want to track your own business operations.

For example:

using var activity = ActivitySource.StartActivity("ProcessOrder");

activity?.SetTag("order.id", orderId);
activity?.SetTag("customer.id", customerId);
Enter fullscreen mode Exit fullscreen mode

Now you have a custom span representing your business operation.

This becomes useful when infrastructure-level telemetry isn't enough to understand your application's behavior.


OpenTelemetry Is Not Just Logging

This is one of the most important distinctions.

Traditional logging might tell you:

Payment failed for order 4821
Enter fullscreen mode Exit fullscreen mode

A trace can tell you:

Request
  ↓
Create Order
  ↓
Database Query       120ms
  ↓
Payment API          1.8s
  ↓
Payment Failed
Enter fullscreen mode Exit fullscreen mode

The second gives you context.

That's why observability becomes increasingly important as applications become distributed.


The Key Takeaway

OpenTelemetry gives your .NET applications a standardized way to collect traces, metrics, and logs.

Instead of asking:

"Why is this request slow?"

you can investigate the actual path the request took.

For a small application, you might get away with logs.

For a system with multiple services, databases, queues, and external APIs, observability becomes much harder to ignore.

Don't just collect logs. Understand the journey of your requests.

Top comments (0)