Skip to content

Instantly share code, notes, and snippets.

@hasmukhlalpatel
Last active May 12, 2025 16:26
Show Gist options
  • Select an option

  • Save hasmukhlalpatel/a4fe35e8dbe955c3e835339b380d65de to your computer and use it in GitHub Desktop.

Select an option

Save hasmukhlalpatel/a4fe35e8dbe955c3e835339b380d65de to your computer and use it in GitHub Desktop.
CorrelationId Middleware in dotnet

CorrelationIdMiddleware

public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;

    public CorrelationIdMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // Generate or retrieve existing correlation ID
        var correlationId = context.Request.Headers["X-Correlation-ID"].FirstOrDefault() ?? Guid.NewGuid().ToString();

        // Store it in HttpContext for downstream access
        context.Items["CorrelationId"] = correlationId;

        // Optionally, push it into logging scope for automatic inclusion in logs
        using (LogContext.PushProperty("CorrelationId", correlationId))
        {
            await _next(context);
        }
    }
}

Extract from payload

public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;

    public CorrelationIdMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        string correlationId = null;

        // Enable request body buffering
        context.Request.EnableBuffering();

        using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true))
        {
            var body = await reader.ReadToEndAsync();
            if (!string.IsNullOrWhiteSpace(body))
            {
                // Deserialize JSON payload to extract correlationId
                var requestData = JsonSerializer.Deserialize<Dictionary<string, string>>(body);
                if (requestData != null && requestData.ContainsKey("CorrelationId"))
                {
                    correlationId = requestData["CorrelationId"];
                }
            }
        }

        // Reset request body position for downstream processing
        context.Request.Body.Position = 0;

        // Use header fallback if correlationId is not found in payload
        correlationId ??= context.Request.Headers["X-Correlation-ID"].FirstOrDefault() ?? Guid.NewGuid().ToString();

        // Store correlationId in HttpContext
        context.Items["CorrelationId"] = correlationId;

        // Push Correlation ID to logging scope
        using (LogContext.PushProperty("CorrelationId", correlationId))
        {
            var correlationId = HttpContext.Items["CorrelationId"]?.ToString();
            _logger.LogInformation("Processing request with CorrelationId: {CorrelationId}", correlationId);
            await _next(context);
        }
    }
}

setup with serilog

dotnet add package Serilog.Formatting.Compact
using Serilog;
using Serilog.Formatting.Compact;

var logger = new LoggerConfiguration()
    .Enrich.WithCorrelationId()
    .WriteTo.Console(new RenderedCompactJsonFormatter())  // Outputs JSON logs to console
    .WriteTo.File("logs.json", formatter: new RenderedCompactJsonFormatter()) // Saves logs to a file
    .CreateLogger();

Log.Logger = logger;

Override Mictrosoft and system logs

var logger = new LoggerConfiguration()
    .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)  // Suppress Microsoft logs
    .MinimumLevel.Override("System", Serilog.Events.LogEventLevel.Warning)    // Suppress System logs
    .WriteTo.Console()
    .CreateLogger();

Log.Logger = logger;


OR

.MinimumLevel.Override("Microsoft.AspNetCore", Serilog.Events.LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", Serilog.Events.LogEventLevel.Error)

builder.Logging.ClearProviders();
builder.Host.UseSerilog(logger);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment