Correlation Identifier Pattern with Azure Functions Middleware
Identifying and resolving issues in distributed applications can pose significant challenges. The strategic utilization of correlation identifier pattern1 is essential for precise mapping of the application's entire flow, streamlining the troubleshooting process effectively. In this post, learn how to implement correlation identifiers in Azure Functions (Isolated mode) using Middleware.
The application
In the context of an API, the implementation operates such that when generating a response, a correlationId is included. There are two straightforward scenarios: firstly, if no correlationId is initially provided, the implementation adds one. Secondly, if a correlationId is already provided, the implementation returns the same correlationId in the response.
As an example, the Function is a Http triggered endpoint that returns a Hello World message.
The middleware
The middleware implements the interface IFunctionsWorkerMiddleware
, which brings the method Invoke
containing FunctionContext
and FunctionExecutionDelegate
in its signature.
What is implemented is basically a wrapper around await next(context);
. The x-correlationId
is a convention often used to name the header that carries the correlation identifier within an HTTP request or response. This header is a way to associate a specific request with subsequent related events or actions in a distributed system. It's a custom header prefixed with "X-" to indicate that it's non-standard but widely adopted.
CorrelationIdMiddleware.cs
public class CorrelationIdMiddleware : IFunctionsWorkerMiddleware
{
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
var requestData = await context.GetHttpRequestDataAsync();
// find existing correlationId
// otherwise create new correlationId
var correlationId = requestData!.Headers.TryGetValues("x-correlationId", out var values)
? values.First()
: Guid.NewGuid().ToString();
// action executed
await next(context);
// set correlationId to response
context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
}
}
The way of how this is hooked to Azure Functions is through the project initialisation on Program.cs
.
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(workerApplication =>
{
// Register custom middleware with the worker
workerApplication.UseMiddleware<CorrelationIdMiddleware>();
})
.Build();
host.Run();
Testing the scenarios
For when the correlationId is not provided via header, a new x-correlationId
is added to response:
For when the correlationId is provided via header, the same x-correlationId
remains on response:
The sample code is available on PlayGoKids repository
- Reference Correlation Identifier Pattern↩