在 ASP.NET Core 2 中的 webhost 之前开始记录
Start logging before webhost in ASP.NET Core 2
我想在 webhost 之前开始记录,所以记录了启动错误。所以我遵循 Serilog's recommended init order:1) 配置,2) 日志记录,3) webhost。我没有使用 CreateDefaultBuilder()
.
所以我的 Program.cs
有:
// setup config
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
.AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
// setup Serilog logging
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration) // <<< uses config from above
.CreateLogger()
// setup webhost
new WebHostBuilder()
.UseConfiguration(configuration) // <<< uses config from above
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
这有效,但即使我指定了 reloadOnChange:true
,也未检测到 appsettings.json
中的更改。
但是,当我使用 ConfigureAppConfiguration()
时,会检测到更改:
new WebHostBuilder()
.ConfigureAppConfiguration((context, config) => {
// .. duplicate config here
})
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
但这意味着重复和可能无法预料的问题 - 即这是一个 hack。我该如何解决这个问题?
更新
根据@StephenZeng 的回答,UseConfiguration
在这里帮不了我,所以我想我需要使用 ConfigureAppConfiguration
。但问题仍然存在 - 我如何先初始化我的配置,然后多次使用它而不重新定义它?
根据文档,它是设计使然:
"UseConfiguration only copies keys from the provided IConfiguration to the host builder configuration. Therefore, setting reloadOnChange: true for JSON, INI, and XML settings files has no effect."
我 运行 遇到了同样的问题,我创建了一个负责配置生成器的方法。然后我从 Main
和构建 Web 主机时调用该方法。像这样:
public static class Program
{
public static int Main()
{
var configuration = new ConfigurationBuilder()
.AddConfiguration()
.Build();
// setup Serilog logging
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
// Code removed for brevity...
}
private static IWebHost BuildWebHost() =>
WebHost.CreateDefaultBuilder()
.UseSerilog()
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Clear default configuration
config.Sources.Clear();
// Replace with our own configuration
config.AddConfiguration();
})
.Build();
private static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder self) =>
self
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
.AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
.AddEnvironmentVariables();
}
解决方案是避免UseConfiguration
并使用ConfigureAppConfiguration
代替:
// setup config
// ..as before
// ..this is done only once
// setup Serilog logging
// ...as before
// setup webhost
new WebHostBuilder()
.ConfigureAppConfiguration((context, config) => {
config.AddConfiguration(configuration); // <<< uses config from above
})
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
我想在 webhost 之前开始记录,所以记录了启动错误。所以我遵循 Serilog's recommended init order:1) 配置,2) 日志记录,3) webhost。我没有使用 CreateDefaultBuilder()
.
所以我的 Program.cs
有:
// setup config
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
.AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
// setup Serilog logging
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration) // <<< uses config from above
.CreateLogger()
// setup webhost
new WebHostBuilder()
.UseConfiguration(configuration) // <<< uses config from above
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
这有效,但即使我指定了 reloadOnChange:true
,也未检测到 appsettings.json
中的更改。
但是,当我使用 ConfigureAppConfiguration()
时,会检测到更改:
new WebHostBuilder()
.ConfigureAppConfiguration((context, config) => {
// .. duplicate config here
})
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
但这意味着重复和可能无法预料的问题 - 即这是一个 hack。我该如何解决这个问题?
更新
根据@StephenZeng 的回答,UseConfiguration
在这里帮不了我,所以我想我需要使用 ConfigureAppConfiguration
。但问题仍然存在 - 我如何先初始化我的配置,然后多次使用它而不重新定义它?
根据文档,它是设计使然:
"UseConfiguration only copies keys from the provided IConfiguration to the host builder configuration. Therefore, setting reloadOnChange: true for JSON, INI, and XML settings files has no effect."
我 运行 遇到了同样的问题,我创建了一个负责配置生成器的方法。然后我从 Main
和构建 Web 主机时调用该方法。像这样:
public static class Program
{
public static int Main()
{
var configuration = new ConfigurationBuilder()
.AddConfiguration()
.Build();
// setup Serilog logging
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
// Code removed for brevity...
}
private static IWebHost BuildWebHost() =>
WebHost.CreateDefaultBuilder()
.UseSerilog()
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Clear default configuration
config.Sources.Clear();
// Replace with our own configuration
config.AddConfiguration();
})
.Build();
private static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder self) =>
self
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
.AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
.AddEnvironmentVariables();
}
解决方案是避免UseConfiguration
并使用ConfigureAppConfiguration
代替:
// setup config
// ..as before
// ..this is done only once
// setup Serilog logging
// ...as before
// setup webhost
new WebHostBuilder()
.ConfigureAppConfiguration((context, config) => {
config.AddConfiguration(configuration); // <<< uses config from above
})
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();