Published on
🍵 5 min read

Adding OpenTelemetry to Your .NET Core Project

Authors

Photo

Overview

Introduction

OpenTelemetry is one of the most popular open-source libraries for improving the observability of your applications. It provides a vendor-agnostic standard for collecting telemetry data—metrics, logs, and traces—so you can understand exactly what your code is doing in production.

You can plug it into your project, define instrumentation (instrumentation means which data you will collect), define the metrics and traces you are going to need. Then, choose a backend to display those metrics, logs, and traces such as Grafana, ELK Stack, Jaeger, or Aspire Dashboard.

In this article, I'll show you how to quickly integrate OpenTelemetry into an existing .NET Core project, define the data you want to collect, and use the Aspire Dashboard to visualize all your traces.

Requirements

To follow this guide, you will need:

  • .NET Core (version 6 or higher is recommended)
  • Docker (to easily run the Aspire Dashboard)

Step 1: Install the Necessary Packages

# Core SDK and Exporter
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol

# Instrumentation Packages (for common scenarios)
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.SqlClient
dotnet add package OpenTelemetry.Instrumentation.HttpClient
dotnet add package OpenTelemetry.Instrumentation.EntityFrameworkCore
# Add OpenTelemetry.Instrumentation.Redis if you use Redis

Step 2: Configure OpenTelemetry

// Program.cs

// ... existing builder setup

// Add OpenTelemetry
builder.Services.AddOpenTelemetry()
            .ConfigureResource(r => r.AddService("webapp"))
            .WithMetrics(metrics =>
                metrics
                    .AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddSqlClientInstrumentation())
            .WithTracing(tracing =>
                tracing
                    .AddHttpClientInstrumentation()
                    .AddAspNetCoreInstrumentation()
                    .AddEntityFrameworkCoreInstrumentation()
                    .AddRedisInstrumentation()
                    .AddSqlClientInstrumentation())
            .UseOtlpExporter(); 

// ... rest of the code

What is Instrumentation?

Instrumentation is simply the process of telling OpenTelemetry which libraries in your project should collect data. By adding .AddAspNetCoreInstrumentation(), you are telling the SDK: "Please collect data for all incoming web requests and their responses."

Step 3: Run the Aspire Dashboard with Docker Compose

Now that your application is collecting data, you need a backend to receive and display it. While options like Jaeger, Grafana, and ELK Stack are popular, the Microsoft Aspire Dashboard is a lightweight, zero-config option that is fantastic for local development.

Create a docker-compose.yml file in the root of your project:

Dockerfile

version: '3.8'

services:
  webapp:
    build:
      context: .
      dockerfile: Dockerfile # Assumes you have a Dockerfile for your .NET app
    ports:
      - "8080:8080" # Example port mapping for your .NET app
    environment:
      # CRITICAL: This environment variable tells your .NET app where to send the data.
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://aspire-dashboard:18889

  aspire-dashboard:
    container_name: aspire-dashboard
    image: mcr.microsoft.com/dotnet/aspire-dashboard:9.0 # Use the official Aspire image
    restart: always
    environment:
      - DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS=true # Allows access without login
    ports:
      # Map the container's OTLP receiver port (18889) to an accessible host port (28888)
      - 28888:18888

Environment Variable

The most important line in the docker-compose.yml is the environment variable in your webapp service:

- OTEL_EXPORTER_OTLP_ENDPOINT=http://aspire-dashboard:18889

This is how your application knows to send all the collected OpenTelemetry data to the aspire-dashboard service running on port 18889 (the default port for the dashboard's OTLP collector).

Run and Visualize

  1. Start the Services: Open your terminal in the directory containing the docker-compose.yml file and run:

    docker compose up
    
  2. Access the Dashboard: The Aspire Dashboard will be available in your browser at the host port you defined:

  3. Generate Traffic: Interact with your application (e.g., hit an API endpoint, make a database call).

  4. See the Traces: You will instantly see your service ("Biletall" in our example) appear in the list. Navigate to the Traces tab to see end-to-end details of every request, including database query times, HTTP calls, and more!

aspire-log
aspire-metrics
aspire-trace

Frequently Asked Questions

Banner Background

Emin Vergil

Software Engineer

I'm a curious and passionate person who likes building new things, learning new technologies, and sharing knowledge with others.

Subscribe to get future posts via email (or grab the RSS feed)