Nick
Nick

Reputation: 5696

Serilog sending blank CorrelationId to Seq logger

I'm using Serilog and Seq in a .net core web api to handle the logging. I've added a reference to Steve Gordon's CorrelationId Middleware to get the X-Correlation-ID from the headers (or create a new one) to update the TraceIdentifier.

I've then added another middleware class to push the correlation id into the log context, but this isn't working correctly:

public class LogCorrelationIdMiddleware
{
    private readonly RequestDelegate _next;
    public LogCorrelationIdMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext context)
    {
        // doesn't work - blank CorrelationId in Seq
        using (LogContext.PushProperty("CorrelationId", context.Request.HttpContext.TraceIdentifier)) { return _next(context); }

        // works - correct CorrelationId2 in Seq 
        //using (LogContext.PushProperty("CorrelationId2", context.Request.HttpContext.TraceIdentifier)) { return _next(context); }
    }
}

Any ideas why?

Upvotes: 3

Views: 5594

Answers (2)

JRichardsz
JRichardsz

Reputation: 16544

Old school

What worked for me was to add a classic middleware:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Serilog.Context;

namespace Common.Middleware
{
    public class MiddlewareLogConfigurer : IMiddleware
    {

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            LogContext.PushProperty("CorrelationId", Guid.NewGuid().ToString());
            await next(context);
        }

    }
}

Then at the startup

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<MiddlewareLogConfigurer >();//first line!!!
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

New school

In this fashion way, you don't need extra classes. You can do it at the startup (copied from nodejs + express)

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    LogContext.PushProperty("CorrelationId", Guid.NewGuid().ToString());
    await next(context);
});

Lectures

Upvotes: 0

Tod Thomson
Tod Thomson

Reputation: 4939

It's working for me when I do the following (not as middleware):

using (LogContext.PushProperty("CorrelationId", "This is a test..."))
{
    Log.Write(level, exception, messageTemplate, propertyValues);
}

So I suspect that it's your CorrelationId being overwritten by ASP.NET Core MVC as eluded to here: https://github.com/serilog/serilog-aspnetcore/issues/59

Some background to the issue and their plan to deal with it in 3.0 is also here: https://github.com/aspnet/AspNetCore/issues/5918

Apologies that this isn't a "fix", however I had the same issue and was able to work around it by adding a level of indirection between the log call (in my code) and the call to Log.Write (as shown above).

Upvotes: 2

Related Questions