Serilog.Enrichers.ClientInfo在.NET Core 6 API中日志增强失效排查
问题排查与解决方案
针对你遇到的API1无法通过Serilog.Enrichers.ClientInfo记录客户端IP、CorrelationId及请求头的问题,结合两个API的配置差异,可按以下步骤排查:
1. 检查IHttpContextAccessor服务注册
Serilog.Enrichers.ClientInfo的所有增强器(WithClientIp、WithRequestHeader等)均依赖IHttpContextAccessor获取当前请求上下文。虽然.NET Core 6 Web API默认会注册该服务,但如果API1的Program.cs中存在自定义容器配置、手动移除服务的情况,会导致增强器无法获取请求上下文,输出空值。
解决方法:在API1的Program.cs中显式注册该服务:
builder.Services.AddHttpContextAccessor();
2. 调整UseSerilogRequestLogging()的中间件顺序
API1额外添加了app.UseSerilogRequestLogging(),而API2没有。该中间件的位置直接决定能否捕获请求上下文:
- 正确顺序:需放在
app.UseRouting()之后、app.UseAuthorization()之前,确保在请求路由完成后捕获完整上下文。 - 错误顺序:如果放在
app.MapControllers()或app.Run()之后,中间件不会被执行,无法为日志提供上下文。
调整后的API1中间件示例:
var app = builder.Build(); app.UseHttpsRedirection(); app.UseRouting(); // 关键:放在UseRouting之后,UseAuthorization之前 app.UseSerilogRequestLogging(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 排除MediatR的上下文隔离影响
API1使用了MediatR发送命令,虽然控制器日志写在mediator.Send()之前,但如果MediatR配置了自定义调度器或范围隔离,可能意外清空HttpContext。可临时注释mediator.Send()代码,单独测试控制器日志是否能正常输出客户端信息,以此排除MediatR的影响。
4. 验证日志实例的注入方式
确保API1控制器中的日志实例是通过构造函数注入的ILogger<YourController>,而非手动创建的静态实例——静态实例无法获取请求范围的上下文,会导致增强器字段为空。
正确注入示例:
private readonly ILogger<YourController> _logger; private readonly IMediator _mediator; public YourController(ILogger<YourController> logger, IMediator mediator) { _logger = logger; _mediator = mediator; }
内容的提问来源于stack exchange,提问作者lasjan
相关产品推荐
相关产品推荐

