Serilog 不使用 .NET 5 控制台应用程序中的 LoggerFactory 写入文件,不产生错误或输出

Serilog does not write to a file using LoggerFactory in .NET 5 Console App, produces no errors or output

我正在尝试使用 Serilog 的 AddFile by way of LoggerFactory,但我无法让它做任何事情

This is my appsettings.json,与入门指南相同。

这是我的:

IConfiguration Configuration = new ConfigurationBuilder()
    //.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "Logs"))
    .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "Properties", "appsettings.json"), optional: false, reloadOnChange: false)
    //.AddEnvironmentVariables()
    //.AddCommandLine(args)
    .Build();

ILoggerFactory loggerFactory = LoggerFactory.Create(builder => {
    builder
        .AddConfiguration(Configuration.GetSection("Logging"))
        .AddConsole()
        .AddDebug()
        .AddFile("log.txt"); //Configuration.GetSection("Logging"));
});

ILogger<Program> logger = loggerFactory.CreateLogger<Program>();

logger.LogTrace("Trace");
logger.LogInformation("Information");
logger.LogDebug("Debug");
logger.LogError("Error");
logger.LogCritical("Critical");

我在控制台看到了输出。我没有收到任何错误。即使建议添加:

Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));

发件人:https://github.com/serilog/serilog/wiki/Debugging-and-Diagnostics

您正在使用的 Serilog 扩展 (Serilog.Extensions.Logging.File) internally writes to the file asynchronously on a separate thread, and your application is terminating before Serilog had the chance to flush the logs to the file on disk (which could take about ~2 seconds)。

通常你会使用一个 application host 在应用程序终止之前处理记录器(和其他服务),强制刷新写入磁盘,但在你的情况下使用简单的控制台应用程序,没有人处理日志,因此在应用程序终止之前不会发生最终刷新。

Serilog 有一个 Log.CloseAndFlush method that is normally used in cases like this and you're expected to call it before your app terminates, however Log.CloseAndFlush doesn't work with Serilog.Extensions.Logging.File(至少在撰写本文时的最新版本),因为它没有将它创建的记录器分配给 Log.Logger,这正是 CloseAndFlush 尝试的处理。

因此,在您的情况下,没有主机且无法使用 CloseAndFlush,您需要防止您的应用程序终止几秒钟,例如,通过阻塞主线程Thread.Sleep 或等待用户输入 Console.ReadLine,或类似的...

// ...
logger.LogError("Error");
logger.LogCritical("Critical");

// Just for the sake of proving that the file is being written (not production code)
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); // <<<<<

相关问题:Means to troubleshoot/debug logging? #48