Course contentsShow
← C#
Lesson 1543 of 1,90814. Background Work and MessagingFree lesson

Distributed Tracing with Correlation IDs

Propagate trace identifiers across service boundaries to reconstruct asynchronous request flows.

In this lesson, you will learn how to maintain visibility into asynchronous request flows by propagating trace identifiers across service boundaries using Correlation IDs.

When a request enters your system and triggers a chain of events—such as a BackgroundService picking up a message from a queue—the execution path often leaves the context of the original HTTP request. Without a mechanism to link these actions, your logs will look like a collection of disjointed events, making it nearly impossible to debug failures in distributed workflows.

To solve this, we use a Correlation ID. This is a unique identifier (often a Guid or ActivityId) generated at the start of a transaction. When your producer (e.g., an API controller) sends a message to a message broker, it must inject this ID into the message metadata (headers).

Propagating the Context

When your BackgroundService consumes that message, it must extract the header and re-associate it with the current execution context. In modern C#, we use System.Diagnostics.Activity to automatically flow this context.

// Inside your Producer (API Controller)
var activity = new Activity("ProcessOrder").Start();
var message = new OrderMessage { 
    CorrelationId = activity.TraceId.ToString() 
};
await _messageQueue.PublishAsync(message);

// Inside your BackgroundService Consumer
public async Task ExecuteAsync(CancellationToken stoppingToken)
{
    var message = await _queue.ReceiveAsync();
    
    // Restore the trace context
    using var activity = new Activity("ProcessOrder").SetParentId(message.CorrelationId).Start();
    
    _logger.LogInformation("Processing order {Id}", message.OrderId);
}

By manually setting the ParentId on a new Activity scope within your background worker, you inform the diagnostic infrastructure that the current operation is a continuation of the upstream event. When you use ILogger or an Application Insights SDK, the CorrelationId is automatically attached to every log entry, allowing you to filter your logging dashboard by that single ID to see the full "story" of the request across the entire system.

Key Takeaway: To maintain observability, you must treat the Correlation ID as part of your message contract, injecting it into message headers at the source and restoring it as an Activity context within your background consumers.