You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core WebAPI中如何用NLog获取关联ID并记录响应?

How to Get Correlation ID in .NET Core WebAPI and Log Responses with NLog

Hey there! Since you're new to .NET Core WebAPI, let's break this down into simple, actionable steps—first how to get that correlation ID sorted, then how to hook it up with NLog to log your responses properly.

1. Getting the Correlation ID

A correlation ID helps you track a single request through your entire system, which is super handy for debugging. There are two main ways to get one:

Option 1: Use the Built-in TraceIdentifier

.NET Core automatically generates a unique TraceIdentifier for every incoming HTTP request. You can grab it directly from HttpContext in your controller:

[HttpGet]
public IActionResult Get()
{
    var correlationId = HttpContext.TraceIdentifier;
    // Use this ID for tracking, attaching to responses, etc.
    return Ok(new { CorrelationId = correlationId });
}

The downside? This ID is a system-generated string (like 0HL9V2M3K8T1N:00000001) which isn't as human-friendly as a UUID. If you want a custom format, go with Option 2.

Option 2: Create a Custom Middleware for Correlation IDs

This lets you generate a UUID (or any format you want) and even check for a pre-existing ID from the client's request headers (like X-Correlation-ID).

First, create the middleware class:

public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task InvokeAsync(HttpContext context)
    {
        // Check if the client sent a correlation ID; if not, generate a new UUID
        var correlationId = context.Request.Headers.TryGetValue("X-Correlation-ID", out var incomingId)
            ? incomingId.ToString()
            : Guid.NewGuid().ToString();

        // Store the ID in HttpContext.Items so it's accessible anywhere in the request pipeline
        context.Items["CorrelationId"] = correlationId;
        // Add it to the response header so the client can track the request too
        context.Response.Headers.Add("X-Correlation-ID", correlationId);

        // Pass the request to the next middleware in the pipeline
        await _next(context);
    }
}

Then register it in your Program.cs—make sure to add it before routing to ensure it runs early:

var builder = WebApplication.CreateBuilder(args);

// Register the middleware
builder.Services.AddTransient<CorrelationIdMiddleware>();

var app = builder.Build();

// Use the middleware first
app.UseMiddleware<CorrelationIdMiddleware>();

app.UseRouting();
// Add other middleware (like authorization, endpoints) here...

Now you can access the ID anywhere in your app via HttpContext.Items:

var correlationId = HttpContext.Items["CorrelationId"]?.ToString();

2. Logging with NLog (Including Correlation ID and Responses)

First, make sure you have the NLog NuGet package installed: NLog.Web.AspNetCore

Step 1: Configure NLog to Include Correlation ID

Create (or update) your NLog.config file to add the correlation ID to your log layout. Here's a basic example:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">

  <targets>
    <target name="file" xsi:type="File" 
            fileName="logs/${shortdate}.log"
            layout="${longdate} | ${level:uppercase=true} | CorrelationID: ${aspnet-item:item=CorrelationId} | ${message} | ${exception:format=tostring}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="file" />
  </rules>
</nlog>

The ${aspnet-item:item=CorrelationId} placeholder pulls the ID we stored in HttpContext.Items earlier—easy peasy!

Step 2: Log Response Content with NLog

To log the actual response content, we can extend our correlation ID middleware to capture the response stream (since the default stream can't be read multiple times):

Update the InvokeAsync method in CorrelationIdMiddleware:

public async Task InvokeAsync(HttpContext context)
{
    // Existing correlation ID logic stays the same
    var correlationId = context.Request.Headers.TryGetValue("X-Correlation-ID", out var incomingId)
        ? incomingId.ToString()
        : Guid.NewGuid().ToString();
    context.Items["CorrelationId"] = correlationId;
    context.Response.Headers.Add("X-Correlation-ID", correlationId);

    // Capture the response content
    var originalResponseBody = context.Response.Body;
    using var responseBodyStream = new MemoryStream();
    context.Response.Body = responseBodyStream;

    // Let the request proceed through the pipeline
    await _next(context);

    // Reset the stream position to read the content
    responseBodyStream.Seek(0, SeekOrigin.Begin);
    var responseContent = await new StreamReader(responseBodyStream).ReadToEndAsync();
    responseBodyStream.Seek(0, SeekOrigin.Begin);

    // Copy the content back to the original response stream so the client gets it
    await responseBodyStream.CopyToAsync(originalResponseBody);
    context.Response.Body = originalResponseBody;

    // Log the response with correlation ID using NLog
    var logger = NLog.LogManager.GetCurrentClassLogger();
    logger.Info("Request completed. CorrelationID: {CorrelationId} | Response Content: {ResponseContent}", 
                correlationId, 
                responseContent);
}

This way, every time a request finishes, NLog will write a log entry with the correlation ID and the full response content.

Alternative: Log from Controllers

If you prefer to log directly from your controllers, inject ILogger<T> and pass the correlation ID as a parameter:

private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
    _logger = logger;
}

[HttpGet]
public IActionResult Get()
{
    var correlationId = HttpContext.Items["CorrelationId"]?.ToString();
    var response = new { Message = "Hello from WebAPI!" };
    
    _logger.LogInformation("Sent response. CorrelationID: {CorrelationId} | Data: {Response}", 
                          correlationId, 
                          response);
    
    return Ok(response);
}

Since we configured NLog to include the correlation ID in the layout, it will show up automatically in your logs—no extra work needed!

Quick Notes to Remember

  • Middleware Order: Always register your correlation ID middleware early in the pipeline (before routing/authorization) so it runs before any other request processing.
  • Large Responses: If your API returns big files or large payloads, consider skipping logging the full response content to avoid bloating your log files.
  • Custom Headers: If you use a different header name than X-Correlation-ID, make sure to update it everywhere (middleware, client requests, etc.).

内容的提问来源于stack exchange,提问作者Nithin Bhaharadwaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:14:09