.NET 6中通过中间件将Correlation ID传入Serilog文件日志的问题
解决Serilog日志中不显示Correlation ID的问题
以下是针对性的解决步骤,按顺序排查调整即可:
1. 启用Serilog的LogContext增强
Serilog默认不会自动读取LogContext中的属性,必须在配置里显式开启这个功能。在Program.cs的Serilog配置代码中添加Enrich.FromLogContext():
var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog((context, config) => config .ReadFrom.Configuration(context.Configuration) .Enrich.FromLogContext() // 关键配置:开启LogContext属性采集 .Enrich.WithMachineName() .Enrich.WithEnvironmentName() .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day));
2. 调整中间件注册顺序
CorrelationIdHandler必须在Serilog请求日志中间件(UseSerilogRequestLogging())以及路由、端点中间件之前注册,这样才能确保记录日志前,Correlation ID已经被放入LogContext。
修改Program.cs中的中间件顺序:
var app = builder.Build(); // 先注册CorrelationId中间件 app.UseMiddleware<CorrelationIdHandler>(); // 再注册Serilog请求日志中间件 app.UseSerilogRequestLogging(); // 后续是其他业务中间件 app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 修正CorrelationIdHandler的类型兼容性问题
原代码中使用StringValues作为Correlation ID的类型,虽然可以隐式转换为字符串,但显式转换能避免潜在的序列化问题,确保LogContext能正确识别属性值:
修改后的CorrelationIdHandler代码:
using AspNet.CorrelationIdGenerator; using Serilog.Context; namespace MyService.Middlewares.CorrelationId; public class CorrelationIdHandler { private readonly RequestDelegate _next; private const string _correlationIdHeader = "X-Correlation-Id"; public CorrelationIdHandler(RequestDelegate next) => _next = next; public async Task Invoke(HttpContext context, ICorrelationIdGenerator correlationIdGenerator) { var correlationId = GetCorrelationId(context, correlationIdGenerator); AddCorrelationIdHeaderToResponse(context, correlationId); using (LogContext.PushProperty(_correlationIdHeader, correlationId)) { await _next(context); } } private static string GetCorrelationId(HttpContext context, ICorrelationIdGenerator correlationIdGenerator) { if (context.Request.Headers.TryGetValue(_correlationIdHeader, out var correlationId)) { var id = correlationId.ToString(); correlationIdGenerator.Set(id); return id; } else { return correlationIdGenerator.Get().ToString(); } } private static void AddCorrelationIdHeaderToResponse(HttpContext context, string correlationId) => context.Response.OnStarting(() => { context.Response.Headers.Add(_correlationIdHeader, correlationId); return Task.CompletedTask; }); }
验证结果
完成以上修改后重启API,发起请求后查看日志文件,就能在Properties字段中看到X-Correlation-Id的记录:
{ "Timestamp": "2022-08-19T23:22:04.1299119+00:00", "Level": "Information", "MessageTemplate": "{\"Id\":\"-1\"}", "RenderedMessage": "{\"Id\":\"-1\"}", "Properties": { "X-Correlation-Id": "1ff3d20e-e8a3-4cb3-a5ab-3b0f3c50b2fc", "MachineName": "VMA", "ApplicationName": "MyService", // 其他原有属性... } }
内容的提问来源于stack exchange,提问作者tRuEsAtM
相关产品推荐
相关产品推荐

