Наше ASP. NET базовое приложение, размещенное в Azure службе приложений, использует Serilog для ведения журнала.
Мы заметили, что если во время запуска хоста возникают ошибки, они будут не войти. Это легко исправить, переместив конфигурацию Serilog до сборки + запуска хоста, а не внутри нее:
Проблема:
public static void Main(string[] args) {
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.UseSerilog((context, loggerConfig) => { loggerConfig.WriteTo.SomeLogger(); })
.Build()
.Run();
}
Не проблема:
public static void Main(string[] args) {
try {
Log.Logger = new LoggerConfiguration().WriteTo.SomeLogger();
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.UseSerilog()
.Build()
.Run();
} catch (Exception ex) {
Log.Fatal(ex, "Host terminated unexpectedly");
} finally {
Log.CloseAndFlush();
}
}
Однако, если вам нужно выполнить дополнительную оркестровку (например, получить данные из хранилища ключей, которые необходимы serilog), то у нас возникнет проблема:
public static void Main(string[] args) {
try {
Log.Logger = new LoggerConfiguration().WriteTo.SomeLogger(loggerSecret: KeyVault.GetSecret("foo"));
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.UseSerilog()
.Build()
.Run();
} catch (Exception ex) {
Log.Fatal(ex, "Host terminated unexpectedly");
} finally {
Log.CloseAndFlush();
}
}
Если получение хранилища ключей не удалось, инициализация регистратора также завершится ошибкой, поэтому, даже если исключения будут обнаружены, Log
все равно будет неинициализированным, и сбой не будет регистрироваться.
Строка Log.Logger
, вероятно, может быть в try/catch
сам по себе, но если я просто сделаю Console.WriteLine()
в catch, это будет нелегко получить в AppService.
Как мы можем убедиться, что исключения, возникающие до инициализации регистратора, правильно обрабатываются и могут быть обнаружены где-нибудь в AppService?