Observability

Back

Loading concept...

🔭 Observability in ASP.NET: Seeing Inside Your App Like a Doctor with X-Ray Vision

The Hospital Analogy

Imagine your ASP.NET application is a patient in a hospital. When something goes wrong, you need to know:

  • What’s happening right now? (Metrics - like heart rate, temperature)
  • What happened step by step? (Tracing - like following the patient’s journey through the hospital)

OpenTelemetry is your magical medical toolkit that gives you X-ray vision into your application!


What is Observability?

Think of observability like being a detective with super powers:

Without Observability:

“My app is slow… somewhere… I think?” 😰

With Observability:

“Request #12345 took 3.2 seconds. It spent 2.8 seconds waiting for the database at line 47.” 🎯

The Three Pillars

graph TD A["🔭 Observability"] --> B["📊 Metrics"] A --> C["🔗 Traces"] A --> D["📝 Logs"] B --> E["Numbers over time"] C --> F["Request journey"] D --> G["Event messages"]

OpenTelemetry: Your Universal Translator

What is OpenTelemetry?

OpenTelemetry is like a universal language that all monitoring tools understand.

Simple Example:

  • You speak English
  • Your friend speaks Spanish
  • Another friend speaks French
  • OpenTelemetry is like having ONE translator who can talk to everyone!

Why Use OpenTelemetry?

Old Way OpenTelemetry Way
Different code for each tool One code, any tool
Locked to one vendor Switch anytime
Learn many libraries Learn once

Getting Started: Adding OpenTelemetry to ASP.NET

Step 1: Install the Packages

// In your terminal or package manager:
// dotnet add package
//   OpenTelemetry.Extensions.Hosting
// dotnet add package
//   OpenTelemetry.Instrumentation.AspNetCore

Step 2: Configure in Program.cs

builder.Services
  .AddOpenTelemetry()
  .WithTracing(tracing =>
  {
    tracing
      .AddAspNetCoreInstrumentation()
      .AddHttpClientInstrumentation();
  })
  .WithMetrics(metrics =>
  {
    metrics
      .AddAspNetCoreInstrumentation()
      .AddRuntimeInstrumentation();
  });

What this does:

  • 🔗 Tracks every HTTP request (tracing)
  • 📊 Counts requests and measures times (metrics)
  • 🤖 Works automatically!

Metrics: Counting What Matters

What Are Metrics?

Metrics are numbers that describe your app over time.

Real-Life Examples:

Metric What It Measures
http_requests_total How many requests came in
http_request_duration How long requests take
active_connections People connected right now

Types of Metrics

graph TD A["📊 Metric Types"] --> B["Counter"] A --> C["Gauge"] A --> D["Histogram"] B --> E["Goes up only<br>Like total visitors"] C --> F["Goes up & down<br>Like current users"] D --> G["Distribution<br>Like response times"]

Creating Custom Metrics

// Create a meter (like a measuring tool)
var meter = new Meter("MyApp.Orders");

// Create a counter
var orderCounter = meter
  .CreateCounter<int>("orders_placed");

// Use it!
orderCounter.Add(1);  // +1 order placed!

Built-in ASP.NET Core Metrics

When you add AddAspNetCoreInstrumentation(), you get FREE metrics:

Metric Name What It Tells You
http.server.duration Request response time
http.server.active_requests Concurrent requests
http.server.request.size Request body size

Tracing: Following the Breadcrumbs

What is Tracing?

Tracing is like leaving breadcrumbs through your code so you can follow what happened.

Simple Example:

“Hansel and Gretel left breadcrumbs to find their way home. Tracing leaves digital breadcrumbs to find where your request went!”

The Journey of a Request

graph TD A["🌐 User Request"] --> B["🚪 API Gateway"] B --> C["🎯 Your Controller"] C --> D["💾 Database Call"] D --> E["📤 Response"] style A fill:#e1f5fe style E fill:#c8e6c9

Each arrow is a Span - one step in the journey!

Key Tracing Concepts

1. Trace = The entire journey (all breadcrumbs) 2. Span = One single step (one breadcrumb) 3. Context = The invisible thread connecting spans

Creating Custom Spans

// Create an ActivitySource (tracer)
var tracer = new ActivitySource("MyApp");

// Create a span for your operation
using var span = tracer.StartActivity(
  "ProcessOrder");

// Add useful information
span?.SetTag("orderId", "12345");
span?.SetTag("customerName", "Alice");

// Do your work here...
// Span automatically ends when block exits

Adding Events to Spans

using var span = tracer.StartActivity(
  "SendEmail");

span?.AddEvent(new ActivityEvent(
  "Email validated"));

// Send the email...

span?.AddEvent(new ActivityEvent(
  "Email sent successfully"));

Events are like sticky notes on your breadcrumbs!


Connecting Traces Across Services

Distributed Tracing

When your request travels across multiple services:

graph LR A["🌐 Web App"] --> B["🛒 Order Service"] B --> C["💳 Payment Service"] C --> D["📧 Email Service"]

OpenTelemetry automatically passes the Trace ID so everything connects!

How It Works

// Service A calls Service B
// OpenTelemetry adds special headers:
// traceparent: 00-abc123-def456-01
//
// Service B reads this header
// and continues the SAME trace!

Result: One request = One connected story across all services!


Exporting Your Data

Where Does the Data Go?

OpenTelemetry collects data, but you need to send it somewhere:

builder.Services
  .AddOpenTelemetry()
  .WithTracing(t => t
    .AddConsoleExporter()     // Print to console
    .AddOtlpExporter())       // Send to collector
  .WithMetrics(m => m
    .AddPrometheusExporter()  // For Prometheus
    .AddOtlpExporter());      // Send to collector

Common Exporters

Exporter Best For
Console Debugging locally
OTLP Production (Jaeger, Zipkin)
Prometheus Metrics dashboards

Real-World Example: E-Commerce Order

Let’s trace an order from start to finish:

public async Task<Order> PlaceOrder(
  OrderRequest request)
{
  using var span = _tracer.StartActivity(
    "PlaceOrder");

  span?.SetTag("customerId",
    request.CustomerId);

  // Step 1: Validate
  using (_tracer.StartActivity("ValidateOrder"))
  {
    ValidateOrder(request);
    span?.AddEvent(new("Order validated"));
  }

  // Step 2: Process payment
  using (_tracer.StartActivity("ProcessPayment"))
  {
    await _paymentService.Charge(request);
    span?.AddEvent(new("Payment processed"));
  }

  // Step 3: Update inventory
  using (_tracer.StartActivity("UpdateInventory"))
  {
    await _inventoryService.Reserve(request);
    span?.AddEvent(new("Inventory updated"));
  }

  return order;
}

What you’ll see in your monitoring tool:

PlaceOrder (total: 450ms)
├── ValidateOrder (12ms)
├── ProcessPayment (320ms)  ← The slow part!
└── UpdateInventory (118ms)

Now you know exactly where time is spent!


Quick Setup Checklist

graph TD A["1️⃣ Install Packages"] --> B["2️⃣ Configure Services"] B --> C["3️⃣ Add Instrumentation"] C --> D["4️⃣ Choose Exporter"] D --> E["5️⃣ View in Dashboard"]

Minimal Complete Setup

// Program.cs - Complete example
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenTelemetry()
  .ConfigureResource(r => r
    .AddService("MyWebApp"))
  .WithTracing(t => t
    .AddAspNetCoreInstrumentation()
    .AddHttpClientInstrumentation()
    .AddOtlpExporter())
  .WithMetrics(m => m
    .AddAspNetCoreInstrumentation()
    .AddRuntimeInstrumentation()
    .AddOtlpExporter());

var app = builder.Build();
app.Run();

Key Takeaways

Concept Remember This
Observability Seeing inside your running app
OpenTelemetry Universal language for monitoring
Metrics Numbers over time (counting things)
Tracing Following a request’s journey
Spans Individual steps in a trace
Exporters Where to send your data

You Did It! 🎉

You now understand how to:

  • ✅ Add OpenTelemetry to ASP.NET
  • ✅ Collect metrics automatically
  • ✅ Trace requests across services
  • ✅ Create custom spans and metrics
  • ✅ Export data to monitoring tools

Remember: Observability is like having night-vision goggles for your code. You can finally see what’s happening instead of guessing!

“The best time to add observability was yesterday. The second best time is now.” 🔭

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.