Статический регистратор Serilog не регистрируется после IHost.Run()

#c# #serilog #asp.net-core-5.0

Вопрос:

Я использую Serilog (Серилог.AspNetCore, версия 4.0.0) в ASP.Net Приложение Core 5.
По большей части это работает нормально, но теперь я заметил, что статический регистратор в Program.cs ничего не регистрирует после IHost.Метод Run завершается (либо регулярно, либо в виде исключения).

Я пытаюсь включить проверку параметров, реализовав интерфейс IValidateOptions. Это работает до сих пор: если опция недопустима, создается исключение OptionsValidationException, и поток программы переходит к соответствующей ветви catch в основном методе. Там, однако, ошибки не записываются в файл журнала.
Отладчик показал, что в этот момент все уровни журналов внезапно отключены, хотя они все еще были правильно включены до IHost.Был выполнен метод Run.

Вот мой код:

 Program.cs:

public static void Main(string[] args)
{
    try
    {
        IHost host = CreateHostBuilder(args).Build();
        // this is logged, debugger shows that log levels are correctly enabled
        Log.Information("Logging message in Main, before IHost.Run() - this works.");
        host.Run();
    }
    catch (OptionsValidationException ex)
    {
        // this is never logged, debugger shows that all log levels are disabled
        Log.Information("Just check if this is logged - no, it is not logged.");
        Log.Fatal("Options validation failed. Please review the configuration (appsettings.json and appsettings.internal.json).");
        Log.Fatal("Failing option is {FailingOptionsName}", ex.OptionsName);
        foreach (string msg in ex.Failures)
        {
            Log.Fatal(msg);
        }
    }
    catch (Exception ex)
    {
        // this is never logged, debugger shows that all log levels are disabled
        Log.Fatal(ex, "Application start-up failed");
    }
    finally
    {
        // this is never logged, debugger shows that all log levels are disabled
        Log.Information("Shutdown logger");
        Log.CloseAndFlush();
    }
}

public static IHostBuilder CreateHostBuilder(string[] args)
{
    BuildConfiguration();
    CreateLogger();
    Log.Information("Application startup ...");

    IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
    .UseSerilog((hostingContext, loggerConfiguration) =>
    {
        loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
            .Enrich.With(new ThreadIdEnricher());
    });

    return hostBuilder
    .UseWindowsService()
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseConfiguration(Configuration);
        webBuilder.UseStartup<Startup>();

        webBuilder.UseHttpSys(options =>
        {
            ...
        });
    });
}

private static void BuildConfiguration()
{
    var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
    Configuration = builder.Build();
}

private static void CreateLogger()
{
    Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
            .Enrich.With(new ThreadIdEnricher()).CreateLogger();
    Serilog.Debugging.SelfLog.Enable(Console.Out);
    Serilog.Debugging.SelfLog.Out = Console.Out;
    Serilog.Debugging.SelfLog.WriteLine("Write to selflog");
}
 

а вот часть serilog из appsettings.json:

   "Serilog": {
    "MinimumLevel": {
      "Default": "Verbose"
    },
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "Async",
        "Args": {
          "configure": [
            {
              "Name": "File",
              "Args": {
                "path": "Logs/WebDAVLog-.log",
                "rollingInterval": "Day",
                "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} ({ThreadID}) [{Level:u3}] {Message:lj}{NewLine}{Exception}",
                "retainedFileCountLimit": 5,
                "shared": true
              }
            }
          ]
        }
      }
    ]
  },
 

Я также попытался включить самозапуск Serilog (см. Метод CreateLogger), но более одной строки, которую я выводил там напрямую («Запись в selflog»), не регистрируется даже при этом.

  1. Что мне нужно сделать, чтобы сообщения журнала были правильно записаны в файл журнала после IHost.Метод запуска?
  2. Что мне нужно сделать, чтобы правильно включить SelfLog Serilog?

Комментарии:

1. UseSerilog заменяет статический регистратор. По крайней мере, один из необязательных логических аргументов для него управляет тем, как это работает. Возможно, вы захотите взглянуть на это, если вы еще этого не сделали