Skip to content
Mogens Heller Grabe edited this page Feb 1, 2022 · 7 revisions

In order to provide a mechanism that you can use to track cause and effect in your event-driven systems, Rebus supports automatic flow of correlation IDs.

This means that Rebus will automatically provide a correlation ID on all outgoing messages, based on this logic:

  • if the outgoing message has a correlation ID already (e.g. provided explicitly when sending the message): leave it alone
  • if we're in a message handler: use the correlation ID of the message currently being handled
  • else: use the message ID of the message being sent

which will be put in the rbs2-corr-id header of the outgoing transport message.

So how do I put this to use?

One thing that has proven to be useful is to use the correlation ID of an incoming message as a context variable in your logging framework - e.g. with Serilog, you would first initializing it with the log context enricher

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext() // 👈
    .WriteTo.(...)
    .CreateLogger();

and then create scopes where appropriate, e.g. in a message handler:

public class SomeMessageHandler : IHandleMessages<SomeMessage>
{
	readonly IMessageContext messageContext;

	public SomeMessageHandler(IMessageContext messageContext) => this.messageContext = messageContext;

	public async Task Handle(SomeMessage message)
	{
		var correlationId = messageContext.Headers.GetValue(Headers.CorrelationId);
		
		using var _ = LogContext.PushProperty("CorrelationId", correlationId);

		// do your thing here
	}
}

or in a cross-cutting fashion by inserting a step into the incoming messages pipeline), allowing the logger to include the ID in each emitted log line by having the field {CorrelationId} in its layout.

This way, when you're querying across all of your log files to track why something happened, you can easily backtrack events and figure out where and why something happened.

Clone this wiki locally