Azure Function v4独立进程注入Serilog.ILogger时依赖解析失败
问题根源
你碰到的Serilog.ILogger无法解析的问题,核心原因很明确:.NET的DI容器默认只注册了Microsoft.Extensions.Logging.ILogger(包括泛型版本ILogger<T>),而Serilog.ILogger并没有被自动加入DI容器。你当前的配置只是把Serilog作为日志提供器接入了微软的日志框架,但没把Serilog自身的ILogger接口注册进去。
两种解决方案
方案1:改用微软标准ILogger<T>注入(推荐)
这是.NET生态的标准做法,也是Azure Functions官方推荐的日志注入方式,不需要额外注册Serilog接口,直接在函数类中注入泛型日志接口即可:
using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Logging; public class MyFunction { private readonly ILogger<MyFunction> _logger; // 注入微软的ILogger<T>,底层会自动用Serilog处理日志 public MyFunction(ILogger<MyFunction> logger) { _logger = logger; } [Function("MyFunction")] public void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer) { _logger.LogInformation("函数触发执行"); } }
方案2:手动注册Serilog.ILogger到DI容器
如果你确实需要直接注入Serilog.ILogger,可以在ConfigureServices中手动将其注册为单例:
修改你的Program.cs配置,在构建好Serilog实例后添加注册代码:
var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices(s => { s.AddApplicationInsightsTelemetryWorkerService(); s.ConfigureFunctionsApplicationInsights(); // 先构建Serilog Logger实例 var serilogLogger = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.WithProperty("Application", "Application") .Enrich.WithProperty("Environment", "Dev") .MinimumLevel.Warning() .WriteTo.ApplicationInsights(TelemetryConfiguration.CreateDefault(), TelemetryConverter.Traces) .CreateLogger(); // 把Serilog.ILogger注册为单例 s.AddSingleton<Serilog.ILogger>(serilogLogger); // 将Serilog接入微软日志框架 s.AddLogging(lb => { lb.AddSerilog(serilogLogger, true); }); // 移除默认的Application Insights日志过滤器(保留你原有的代码) s.Configure<LoggerFilterOptions>(options => { LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider"); if (toRemove is not null) { options.Rules.Remove(toRemove); } }); }) .Build(); host.Run();
之后就能在函数中直接注入Serilog.ILogger:
using Microsoft.Azure.Functions.Worker; using Serilog; public class MyFunction { private readonly ILogger _logger; public MyFunction(ILogger logger) { _logger = logger; } [Function("MyFunction")] public void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer) { _logger.Information("函数触发执行"); } }
额外提醒
- 采用方案2时,不要重复创建Logger实例,确保整个应用只有一个全局的Serilog Logger。
- 优先选择方案1,因为它符合.NET日志规范,与Azure Functions生态兼容性更好,还能自动收集函数上下文信息。
内容的提问来源于stack exchange,提问作者Sai
相关产品推荐
相关产品推荐

