如何修复过时的ILoggerFactory方法?

65

我将我的项目升级到了.NET Core 2.2.x版本,并且在下面这两行代码处收到了一个关于已过时的警告:

public void Configure(IApplicationBuilder app, 
                      IHostingEnvironment env, 
                      ILoggerFactory loggerFactory) 
  {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
建议进行修复的是AddConsole(this ILoggingBuilder builder)方法,建议使用此方法作为替代方案。您可以检查一下自己是否已经在使用此方法。

“LoggerFactory” 肯定不是 “LoggingBuilder”,对吧? - MakePeaceGreatAgain
2
日志已在 WebHost 上设置(我相信自2.0以来一直如此)。请参阅文档。如果您使用 WebHost.CreateDefaultBuilder,则可以免费获得控制台日志记录。 - Kirk Larkin
6个回答

111

今天我也遇到了同样的问题。

从 Startup.cs 中移除您的日志配置,并转到 Program.cs 文件并添加类似以下内容:

var host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup<Startup>()
    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
    })
    .Build();

这里使用了“builder”,因为变量“logging”是一个IloggingBuilder(而您的代码仍在使用ILoggerFactory)

更新:我刚试过的另一种方法是留在Startup.cs文件中,但将记录日志的内容从“Configure”方法移动到“ConfigureServices”中,像这样:

public void ConfigureServices(IServiceCollection services)
{
    services.AddLogging(loggingBuilder =>
    {
        loggingBuilder.AddConfiguration(Configuration.GetSection("Logging"));
        loggingBuilder.AddConsole();
        loggingBuilder.AddDebug();
    });
}

或许能让 Program.cs 更加简洁……


这个 AddLogging 是不是真的必要?我刚创建了一个新的 Web API 项目,什么都没做。我只是通过参数注入了 ILogger<MyClass> logger,可以在控制台上轻松记录日志。所以我在想...为什么还需要 AddConsole - Ish Thomas
当您试图从实际程序配置类库的日志记录时,如何执行ConfigureServices方法? - jeancallisti

22

文档建议使用AddConsole(this ILoggingBuilder builder),这是正确的,但为了使其正常工作,您需要添加对NuGet包Microsoft.Extensions.Logging.Console的引用。


16

当我将日志记录代码从.Net Core 2.1升级到3.0时,也收到了同样的警告。建议的升级方式在MSDN文档中有详细说明。

在我的情况下,我试图获取一个针对控制台的LoggerFactory实例,在.NET Core 3.0中这非常简单:

using (var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()))
{
    // use loggerFactory
}

2
由于它不紧密绑定 ASP.NET Core DI 基础设施,因此最佳答案是接受全框架之外范围的答案。 - d_f
1
没错。我不得不更新我的日志扩展NuGet以解决另一个依赖关系,突然间它就崩溃了,让我想:“你这次把它移到哪里了”。这个回答简洁明了地解决了这个问题。 - Ran Sagy
它在.NET 5中无法工作。ILoggerFactory中没有AddConsole方法。 - Alex78191

9

别担心 - 这是有史以来最愚蠢的事情之一!

注意

以下代码示例使用一个已在2.2版本中过时的ConsoleLoggerProvider构造函数。过时的日志记录API的适当替代品将在3.0版本中提供。同时,可以安全地忽略和抑制警告。

如果您认为自己忘记了过时的含义 - 您没有!暂时不用担心它,只需忽略它或抑制警告(很抱歉我手头没有相关代码)。

(希望他们能给出更好的解释,这就是我所说的愚蠢之处。)


3
不确定自3.0版本推出后是否有新答案——因此,如果您正在使用3.0版本,则本回答本身现在已过时;-) - Simon_Weaver

3
根据 GitHub 上开放的问题,如果在 Program.cs 中使用 CreateDefaultBuilder() 方法,则已经调用了替换方法。我的唯一问题是,我只为非生产环境打开了这些内容,而且我不知道怎么继续做下去。请参考:https://github.com/aspnet/Docs/issues/9829

1
如果您无法访问LoggerFactory.Create(),仍然可以使用ILoggerFactoryAddProvider()方法,将其与ConsoleLoggerProvider()一起使用,但如果您想要做一些简单的事情,则会有点麻烦。问题是,ConsoleLoggerProvider()需要一个IOptionsMonitor<ConsoleLoggerOptions>作为参数,如果您想要最简单的方法,则可以这样做。
  • 你的代码库中没有访问选项机制的权限(我的问题),或者
  • 现有代码库中的真正选项机制与 IOptionsMonitor<> 不匹配,或者
  • 你有其他原因不使用 ASP.Net 选项设施

解决方法是创建一个虚拟类:

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;
    
    class DummyConsoleLoggerOptionsMonitor : IOptionsMonitor<ConsoleLoggerOptions>
    {
        private readonly ConsoleLoggerOptions option = new ConsoleLoggerOptions();

        public DummyConsoleLoggerOptionsMonitor(LogLevel level)
        {
            option.LogToStandardErrorThreshold = level;
        }

        public ConsoleLoggerOptions Get(string name)
        {
            return this.option;
        }

        public IDisposable OnChange(Action<ConsoleLoggerOptions, string> listener)
        {
            return new DummyDisposable();
        }

        public ConsoleLoggerOptions CurrentValue => this.option;

        private sealed class DummyDisposable : IDisposable
        {
            public void Dispose()
            {
            }
        }
    }

您可以像这样使用您的 ILoggerFactory
factory.AddProvider(
    new ConsoleLoggerProvider(
        new DummyConsoleLoggerOptionsMonitor(LogLevel.Debug)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接