我正在使用 Azure Functionapp(版本 4)隔离工作进程。我在program.cs文件中配置了Serilog,如下所示。但在我的实际函数中,当我注入
Serilog.ILogger
时,它在运行时失败并出现错误,无法解析Serilog.ILogger
。
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Microsoft.Azure.Functions.Worker;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddApplicationInsightsTelemetryWorkerService();
s.ConfigureFunctionsApplicationInsights();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", "Application")
.Enrich.WithProperty("Environment", "Dev")
.MinimumLevel.Warning()
.WriteTo.ApplicationInsights(TelemetryConfiguration.CreateDefault(), TelemetryConverter.Traces)
.CreateLogger();
//configure seriLog
s.AddLogging(lb =>
{
lb.AddSerilog(Log.Logger, true);
});
s.Configure<LoggerFilterOptions>(options =>
{
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
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,但仍然失败-
s.AddSingleton<ILoggerProvider>((sp) =>
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.ApplicationInsights(sp.GetRequiredService<TelemetryClient>(), TelemetryConverter.Traces)
.CreateLogger();
return new SerilogLoggerProvider(Log.Logger, true);
});
Serilog.ILogger
不可解析的主要原因是AddSerilog
未将Serilog.ILogger
添加为可解析服务,因为您不应该请求Serilog.ILogger
。
您使用的
AddSerilog
是 Microsoft.Extensions.Logging.ILoggingBuilder
的扩展方法,它将 Serilog 添加为 ILoggerProvider
(参见源代码)。这样,当您请求 Microsoft.Extensions.Logging.ILogger
时,它将构建一个记录器,记录所有已注册的 ILoggerProvider
,因为 Serilog 可能不是唯一的提供者。
相反,您应该请求将
Microsoft.Extension.Logging.ILogger<T>
注入到您的函数中。
如果您真的想要注入
Serilog.ILogger
,那么您需要在AddSerilog
上使用扩展
IServiceCollection
并提供Log.Logger
。该函数的源代码是here。
您应该使用以下任何一种:
var host = new HostBuilder()
.UseSerilog()
.Build()
// OR
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.AddSerilog();
})
.Build();
// OR
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.ConfigureLogging(lb => lb.AddSerilog());
})
.Build();
然后注入
ILogger<T>
是推荐的做法,因为您的函数不应该了解有关 Serilog 的任何信息。您也永远不需要指定 Serilog 的静态 Log.Logger
,因为如果未指定 ILogger,默认情况下将使用它。
如果您想注射
Serilog.ILogger
,您应该这样做。
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.AddSerilog(Log.Logger);
})
.Build();
我没有指定是否需要使用dispose,这取决于你的实现。