Section 6 of 6

Distributed Tracing

🎯 What You'll Learn

  • What is distributed tracing
  • OpenTelemetry
  • Jaeger setup
  • Activity and spans
  • Correlation IDs

What is Distributed Tracing?

Distributed tracing tracks requests as they flow through multiple services, helping you understand performance bottlenecks and debug issues in microservices.

OpenTelemetry

Install Packages Bash
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
dotnet add package OpenTelemetry.Exporter.Jaeger
Program.cs C#
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

builder.Services.AddOpenTelemetry()
    .WithTracing(tracerProviderBuilder =>
    {
        tracerProviderBuilder
            .AddSource("InvenTrack")
            .SetResourceBuilder(
                ResourceBuilder.CreateDefault()
                    .AddService("InvenTrack"))
            .AddAspNetCoreInstrumentation()
            .AddHttpClientInstrumentation()
            .AddJaegerExporter(options =>
            {
                options.AgentHost = "localhost";
                options.AgentPort = 6831;
            });
    });

Run Jaeger with Docker

Start Jaeger Bash
docker run -d --name jaeger \
  -p 6831:6831/udp \
  -p 16686:16686 \
  jaegertracing/all-in-one:latest

Access Jaeger UI at: http://localhost:16686

Custom Activity

Create ActivitySource C#
public static class Telemetry
{
    public static readonly ActivitySource ActivitySource = 
        new ActivitySource("InvenTrack");
}
Use in Service C#
public class ProductService
{
    public async Task<Product> GetProductAsync(int id)
    {
        using (var activity = Telemetry.ActivitySource.StartActivity("GetProduct"))
        {
            activity?.SetTag("product.id", id);
            
            var product = await _context.Products.FindAsync(id);
            
            activity?.SetTag("product.name", product?.Name);
            
            return product;
        }
    }
}

Correlation IDs

Middleware C#
public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;
    private const string CorrelationIdHeader = "X-Correlation-ID";

    public async Task InvokeAsync(HttpContext context)
    {
        var correlationId = context.Request.Headers[CorrelationIdHeader].FirstOrDefault() 
            ?? Guid.NewGuid().ToString();

        context.Response.Headers.Add(CorrelationIdHeader, correlationId);
        context.Items["CorrelationId"] = correlationId;

        await _next(context);
    }
}
Register Middleware C#
app.UseMiddleware<CorrelationIdMiddleware>();

InvenTrack Example

OrderService with Tracing C#
public class OrderService
{
    public async Task CreateOrderAsync(Order order)
    {
        using (var activity = Telemetry.ActivitySource.StartActivity("CreateOrder"))
        {
            activity?.SetTag("order.id", order.Id);
            activity?.SetTag("order.total", order.Total);
            
            // Validate stock
            using (var stockActivity = Telemetry.ActivitySource.StartActivity("ValidateStock"))
            {
                await ValidateStockAsync(order);
            }
            
            // Save order
            await _context.Orders.AddAsync(order);
            await _context.SaveChangesAsync();
        }
    }
}

Key Takeaways

  • Distributed tracing: Track requests across services
  • OpenTelemetry: Standard for observability
  • Jaeger: Tracing backend and UI
  • ActivitySource: Create custom spans
  • SetTag(): Add metadata to spans
  • Correlation IDs: Track requests across services
🎉 Part XIX Complete!

Congratulations! You've completed Part XIX: Advanced Topics. You now understand:

  • ✅ SignalR (real-time communication, Hubs, groups)
  • ✅ gRPC (high-performance RPC, Protocol Buffers)
  • ✅ Background Services (IHostedService, BackgroundService)
  • ✅ Microservices Patterns (API Gateway, circuit breaker, retry)
  • ✅ Health Checks (monitoring, custom checks, UI)
  • ✅ Distributed Tracing (OpenTelemetry, Jaeger, correlation IDs)

You're now ready for advanced ASP.NET Core development! 🚀