如何在C#中向控制台输出日志

8

我想使用Microsoft.Extensions.Logging将日志输出到控制台。我已经按照以下方式设置它:

static void Main()
{
    ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
    ILogger logger = loggerFactory.CreateLogger<Program>();
    logger.LogInformation("Current directory {0}", Directory.GetCurrentDirectory());
}

然而,没有任何内容输出到控制台。

如果您要向记录器发送更多数据,则无需处理。您需要使用flush()方法。您正在写入流,Windows不会持续将流写入文件。Windows使用计时器和大小来将数据从流移动到文件中。flush()方法将数据从流移动到文件中。 - jdweng
也许清除stdout缓冲区也可以解决问题,但是根据这个问题https://github.com/aspnet/Logging/issues/631,处理某些内容是正确的方法。 - Sunday
你只有在应用程序结束时才能处理,而不能在中途处理。是的,当应用程序正常终止时,处理可以解决问题,但当应用程序崩溃时,处理无法解决问题。当应用程序崩溃时,您仍然希望查看记录器数据,如果您没有处理,那么您就会迷失方向。 - jdweng
这就是 using 关键字的作用,确保在发生异常的情况下也能够正确地处理对象的释放。编辑:https://learn.microsoft.com/de-de/dotnet/csharp/language-reference/keywords/using-statement “using 语句确保即使在 using 块内部发生异常,Dispose 也会被调用。” - Sunday
2个回答

14
问题在于通过 AddConsole 添加到 loggerFactory 中的 ConsoleLoggerProviderIDisposable 的,必须被处理以刷新输出。处理 loggerFactory 将会实现此操作。所以要么在程序结束时调用 loggerFactory.Dispose(),要么在创建 loggerFactory 时添加 using
static void Main()
{
    using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
    ILogger logger = loggerFactory.CreateLogger<Program>();
    logger.LogInformation("Current directory {0}", Directory.GetCurrentDirectory());
}

1
我发布了这个问答,因为我花了太长时间才找到不使用ServiceCollection或ASP.NET通用主机等重型工具来完成此操作的方法。 - Sunday
8
没错,但是也要记得添加 Nuget 包 Microsoft.Extensions.Logging.Console,否则 .AddConsole 找不到。 - Alessandro R

2

我认为最简单的方法是使用ServiceCollection独立实现,而不使用GenericHost。

public static void Main()
{
    var collection = new ServiceCollection();
    collection.AddLogging(b => {
        b.AddConsole();
        b.SetMinimumLevel(LogLevel.Information);
    });
    var sp = collection.BuildServiceProvider();

    using(var scope = sp.CreateScope())
    {
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
        logger.LogInformation("Current directory {0}", Directory.GetCurrentDirectory());
    }
}

.netfiddle example

的英译中文为:

.netfiddle示例


谢谢你的回答,我之前看过这个解决方案,但是我觉得为了让日志正常工作而添加很多模板代码有些过于麻烦了。我强烈认为每个包/模块应该可以单独工作,而不需要额外的三个类和对象。就像我在自己的答案下面评论的那样,我特别寻找一种方法来让日志正常工作,而不必添加我不需要的其他东西。也许这应该不只是一个评论,而是问题的一部分。 - Sunday
@Sunday,没问题,我只是想在这里补充一下,如果有人需要记录日志并且使用ServiceCollection也可以。但是你说得对,这也是我的观点。尽管如此,在net-core中它的工作方式就是这样 :) - Martin
再次感谢,显然你是对的,这个答案对于那些(愿意)使用ServiceCollection的人也很有用,并且完美地符合所述问题。让我们等待并看看哪个问题会得到更多的赞(如果有的话;))。 - Sunday

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