Distributed Tracing with OpenTelemetry
In this lesson, you will learn how to instrument your .NET services to propagate trace headers, allowing you to visualize the flow of requests across your microservices architecture.
When a user triggers an action that spans multiple services, the request context needs a way to "stay alive" as it traverses network boundaries. This is achieved through Distributed Tracing. OpenTelemetry uses standard headers (primarily the W3C traceparent header) to carry a unique TraceId. Every service that participates in the request must extract this ID from the incoming HTTP request and attach it to its own outgoing downstream requests.
Implementing Propagation in .NET
The beauty of the OpenTelemetry.Instrumentation.AspNetCore and OpenTelemetry.Instrumentation.Http libraries is that they handle the heavy lifting of header injection and extraction automatically. However, to ensure this works across your infrastructure, you must configure the TracerProvider at the entry point of every service.
// In Program.cs
builder.Services.AddOpenTelemetry()
.WithTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
.AddAspNetCoreInstrumentation() // Auto-extracts incoming trace headers
.AddHttpClientInstrumentation() // Auto-injects headers to outgoing requests
.AddOtlpExporter(); // Sends traces to your collector
});
When a request enters Service A, the ASP.NET Core instrumentation extracts the traceparent header. When Service A calls Service B using an HttpClient, the HTTP instrumentation automatically injects that same TraceId into the outgoing headers.
Why this matters for complex dependencies
Without explicit propagation, your monitoring dashboard sees disconnected "islands" of execution. With headers correctly passed, your tracing backend can stitch these fragments into a single, cohesive waterfall diagram. This allows you to identify exactly which downstream microservice is introducing latency or failing in a chain of five or six different service calls. By maintaining this context, you gain the observability required to debug performance bottlenecks in high-scale distributed environments.
Key Takeaway: Distributed tracing relies on injecting and extracting W3C trace headers, which allows the .NET OpenTelemetry instrumentation to link disparate service spans into a single, visual request lifecycle.