Azure FunctionApps(隔离工作线程)与 Serilog 无法解析

问题描述 投票:0回答:1

我正在使用 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);
     });
c# azure-functions serilog
1个回答
0
投票

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,这取决于你的实现。

© www.soinside.com 2019 - 2024. All rights reserved.