Azure Function(.NET 8)中Serilog.ClientInfo增强器无日志输出问题
解决.NET 8 Azure Function中Serilog无法获取HttpContext的问题
核心原因
.NET 8 Azure Functions默认使用隔离进程模型,该模型下HttpContextAccessor无法直接获取请求上下文——因为隔离进程的执行环境和传统ASP.NET Core不同,需通过FunctionContext来访问Http相关信息。
解决方案步骤
1. 用IFunctionContextAccessor替代HttpContextAccessor
在隔离进程模型中,获取当前请求上下文要依赖IFunctionContextAccessor,而非HttpContextAccessor。该服务已由Functions runtime默认注册,无需手动添加。
2. 自定义Serilog增强器提取Http信息
创建自定义增强器,通过IFunctionContextAccessor获取函数上下文,再从中提取HttpContext及请求头、IP等信息:
public class HttpRequestEnricher : ILogEventEnricher { private readonly IFunctionContextAccessor _functionContextAccessor; public HttpRequestEnricher(IFunctionContextAccessor functionContextAccessor) { _functionContextAccessor = functionContextAccessor; } public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { var functionContext = _functionContextAccessor.FunctionContext; if (functionContext == null) return; // 从函数上下文提取HttpContext if (functionContext.Features.TryGetValue(typeof(HttpContext), out var httpContextObj) && httpContextObj is HttpContext httpContext) { // 添加请求头信息 if (httpContext.Request.Headers.TryGetValue("X-Platform", out var platform)) { logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("XPlatform", platform.ToString())); } if (httpContext.Request.Headers.TryGetValue("X-App-Version", out var version)) { logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("X-App-Version", version.ToString())); } // 添加客户端IP var clientIp = httpContext.Connection.RemoteIpAddress?.ToString(); if (!string.IsNullOrEmpty(clientIp)) { logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("ClientIp", clientIp)); } } } }
3. 重新配置Serilog与依赖注入
修改启动配置,注册自定义增强器并添加到Serilog配置中:
var sinkOptions = new MSSqlServerSinkOptions { TableName = "Logs", AutoCreateSqlTable = true, BatchPostingLimit = 10 }; // 注册自定义增强器到DI容器 builder.Services.AddSingleton<ILogEventEnricher, HttpRequestEnricher>(); // 从DI中获取增强器实例 var enricher = builder.Services.BuildServiceProvider().GetRequiredService<ILogEventEnricher>(); Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.With(enricher) // 使用自定义增强器 .WriteTo.MSSqlServer( connectionString: "xxx", columnOptions: new ColumnOptions(), sinkOptions: sinkOptions, restrictedToMinimumLevel: LogEventLevel.Warning ) .CreateLogger(); builder.Services.AddLogging(lb => { lb.AddSerilog(Log.Logger, true); });
4. 进程内模型的额外说明
若你使用进程内模型(需在host.json中配置"functionRuntime": "dotnet"),可通过构造函数注入HttpContextAccessor,但需注意:仅HTTP触发的函数执行期间HttpContext有效,非HTTP触发的函数中HttpContext本身就是null。
内容的提问来源于stack exchange,提问作者user3526149
相关产品推荐
相关产品推荐

