【发布时间】:2020-07-31 22:25:34
【问题描述】:
我正在尝试从配置服务部分中的 Program.cs 访问配置部分 (appsettings.json) 以设置日志记录,但当我使用 hostContext.Configuration.GetSection("AppSettings") 时我得到空值。在网上搜索了不同的答案,但没有任何运气。我错过了什么?
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseEnvironment(Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"))
.UseWindowsService()
.ConfigureLogging(loggerFactory =>
{
loggerFactory.AddEventLog();
loggerFactory.AddEventSourceLogger();
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
hostingContext.HostingEnvironment.EnvironmentName = env;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
.Build();
if (env.Contains("Development"))
{
var appAssembly = Assembly.Load(new AssemblyName(hostingContext.HostingEnvironment.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.UseSerilog()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
services.Configure<AppSettings>(hostContext.Configuration.GetSection("AppSettings"));
services.AddScoped<IMarketplaceOrderProcessor, MarketplaceOrderProcessor>();
IConfiguration configuration = hostContext.Configuration;
var env = hostContext.HostingEnvironment;
var logLevel = (LogEventLevel)Enum.Parse(typeof(LogEventLevel), configuration.GetSection("Serilog").GetSection("LogLevel").Value);
var retentionPolicy = (LogGroupRetentionPolicy)Enum.Parse(typeof(LogGroupRetentionPolicy), configuration.GetSection("Serilog").GetSection("RententionPolicy").Value);
var levelSwitch = new LoggingLevelSwitch();
levelSwitch.MinimumLevel = logLevel;
// customer formatter
var formatter = new CustomLogFormatter();
var options = new CloudWatchSinkOptions
{
LogGroupName = configuration.GetSection("Serilog").GetSection("LogGroup").Value,
TextFormatter = formatter,
MinimumLogEventLevel = logLevel,
BatchSizeLimit = 100,
QueueSizeLimit = 10000,
Period = TimeSpan.FromSeconds(10),
CreateLogGroup = true,
LogStreamNameProvider = new DefaultLogStreamProvider(),
RetryAttempts = 5,
LogGroupRetentionPolicy = retentionPolicy
};
var providerAwsId = configuration.GetSection("AppSettings").GetSection("s3AwsSecretAccessKeyId").Value;
var providerAwsKey = configuration.GetSection("AppSettings").GetSection("s3AwsSecretAccessKey").Value;
var awsCredentials = new BasicAWSCredentials(providerAwsId, providerAwsKey);
var region = RegionEndpoint.GetBySystemName(configuration.GetSection("Serilog").GetSection("Region").Value);
var client = new AmazonCloudWatchLogsClient(awsCredentials, region);
if (env.EnvironmentName.Contains("Development"))
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration, "Serilog")
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.Enrich.WithNewRelicLogsInContext()
.WriteTo.Console()
.WriteTo.Async(a => a.File(formatter: new NewRelicFormatter(), path: Environment.GetEnvironmentVariable("SVC_NEWRELIC"), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, buffered: true))
.WriteTo.AmazonCloudWatch(options, client)
.CreateLogger();
}
else
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration, "Serilog")
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.Enrich.WithNewRelicLogsInContext()
.WriteTo.Console()
.WriteTo.Async(a => a.File(formatter: new NewRelicFormatter(), path: Environment.GetEnvironmentVariable("SVC_NEWRELIC"), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, buffered: true))
.CreateLogger();
}
});
}
【问题讨论】:
-
即使您不一定需要它,我还是建议将它移到
Startup.cs类中。在 Startup 中,你可以注入 IConfiguration 并解决这个问题。 -
从我的角度来看,它看起来确实正确。您确定
GetSection()返回一个实际的null而不仅仅是一个空部分吗?您可以调试应用程序并检查hostingContext.Configuration包含的内容吗?请注意,您不应像ConfigureAppConfiguration中那样覆盖托管环境。另外,既然已经在使用默认主机构建器,为什么还要设置这么多?
标签: c# asp.net-core