I want to pass a header and have it automatically appear in all log entries on the backend service.

This is part 1 of my blog post series on log correlation between a frontend website and a back end service.

  1. Send an ID between API calls and have it included in the log files.
  2. The ID should be in the same property in all logs.
  3. Easily access the correlation ID.
  4. When possible, it should automatically be added to the correct HttpClient requests.

So far creating a request and getting the id automatically in the logs on the back end is semi-easy. Set the Request-Id header and it will automatically be put into the log entries as the CorrelationId property.

For example, the following raw request:

GET https://localhost:44396/api/values HTTP/1.1
Host: localhost:44396
Request-Id: 0HLK1OTNC9O8D:00000001

Will output entries like (notice the CorrelationId near the end):

{
    "Timestamp": "2019-01-23T21:54:09.9140634-07:00",
    "Level": "Information",
    "MessageTemplate": "Executed action {ActionName} in {ElapsedMilliseconds}ms",
    "RenderedMessage": "Executed action \"ExampleCorrelationIdApi.Controllers.ValuesController.Get (ExampleCorrelationIdApi)\" in 179217.6396ms",
    "Properties": {
        "ActionName": "ExampleCorrelationIdApi.Controllers.ValuesController.Get (ExampleCorrelationIdApi)",
        "ElapsedMilliseconds": 179217.6396,
        "EventId": {
            "Id": 2
        },
        "SourceContext": "Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker",
        "ActionId": "2d525c1c-8d6f-4d7f-9a85-ea2d5ea7d8b1",
        "RequestId": "0HLK1LU666:00000004",
        "RequestPath": "/api/values",
        "CorrelationId": "0HLK1OTNC9O8D:00000001",
        "ConnectionId": "0HLK1MU2O8IOE"
    }
}

The C# code to make that request (this is just an action method on a controller):

public async Task<IActionResult> Index()
{
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44396/api/values");
    request.Headers.Add("Request-Id", HttpContext.TraceIdentifier);
    await client.SendAsync(request);
}

That's one step closer to my end goal and takes care of my primary requirement, sending a header and getting it in the logs, but we're not quite there yet.

It's not the same property name so it's it cumbersome to search the logs, it's not easy to access it in the called API to pass it to any other downstream API's and it's not automatically added so we may forget to add it in the code.

Onto Part 2, the ID should be in the same property in all logs.