记一个ASP.Net Core配置文件问题

  最近排查一个ASP.Net Core项目的Bug,用LogInformation()记录一些运行日志,本地测试日志记录正常,然后发到RC环境测试,结果发现死活没有日志信息。

  首先想到就是LogLevel设置有问题。检查了基础的配置文件(appsettings.json)没有问题,而RC环境的配置文件(appsettings.RC.json)未配置Logging节点,也就不会覆盖。

 1 "Logging": {
 2   "IncludeScopes": false,
 3   "LogLevel": {
 4     "Default": "Information",
 5     "System": "Warning",
 6     "Microsoft": "Warning"
 7   },
 8   "Console": {
 9     "LogLevel": {
10       "Default": "Warning"
11     }
12   }
13 }

appsettings.json

  然后检查了涉及appsettings.json的代码。在Startup.cs中,会根据“environment.json”文件中配置的“EnvironmentName”值,来加载不同配置文件。

 1 private readonly ILoggerFactory m_LoggerFactory;
 2 private readonly IConfiguration m_Configuration;
 3
 4 public Startup(IHostingEnvironment env, ILoggerFactory loggerFactory)
 5 {
 6     m_LoggerFactory = loggerFactory;
 7
 8     var environmentName = GetEnvironmentName();
 9     var builder = new ConfigurationBuilder()
10         .SetBasePath(env.ContentRootPath)
11         .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
12         .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true);
13
14     m_Configuration = builder.Build();
15 }
16
17 private static string GetEnvironmentName()
18 {
19     var configuration = new ConfigurationBuilder()
20         .AddJsonFile("environment.json", optional: true)
21         .Build();
22     return configuration["EnvironmentName"] ?? string.Empty;
23 }

Startup

  可是environment.json配置也没问题,而其中的m_Configuration变量只是会注入IoC中供业务代码读取配置使用,并没有对Logging配置做任何修改。

  之后又想到,所有环境的配置文件都是放在同一个目录下,是否是串文件了呢?而其中appsettings.Production.json中确实有配置Logging.LogLevel为“Warning”,如果加载了这个配置,那LogInformation()就不会输出日志了。因而调整了下appsettings.Production.json中的Loggind.LogLevel为“Information”,然后再测试,嘿,有日记信息了!也就是说,Production的配置文件确实被加载了。

  再次检查代码发现并未有明确加载Production文件,那该不会是某个系统方法通过环境变量ASPNETCORE_ENVIRONMENT加载的吧?因为未设置该值(确实没设置)默认就会是Production[1]

  于是立马修改ASPNETCORE_ENVIRONMENT=RC(注意是1个“_”),还原appsettings.Production.json,然后重启服务测试,不出所料,日志正常记录。那么,接下来就是找到那个“系统方法”了。

  仔细翻了翻官方文档,找到了以下内容[2]

  CreateDefaultBuilder方法(2.0新增[4])会调用2次AddJsonFile(),第1次加载appsettings.json,第2次加载appsettings.{Environment}.json,而Environment取至IHostingEnvironment.EnvironmentName,即环境值。对应源码[5]

 1 builder.UseKestrel((builderContext, options) =>
 2 {
 3     options.Configure(builderContext.Configuration.GetSection("Kestrel"));
 4 })
 5 .ConfigureAppConfiguration((hostingContext, config) =>
 6 {
 7     var env = hostingContext.HostingEnvironment;
 8
 9     config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
10           .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
11
12     if (env.IsDevelopment())
13     {
14         var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
15         if (appAssembly != null)
16         {
17             config.AddUserSecrets(appAssembly, optional: true);
18         }
19     }
20
21     config.AddEnvironmentVariables();
22
23     if (args != null)
24     {
25         config.AddCommandLine(args);
26     }
27 })

CreateDefaultBuilder

  好嘛,真相大白:

  1. 未设置环境变量ASPNETCORE_ENVIRONMENT,则默认为Production
  2. 调用CreateDefaultBuilder方法构建WebHost,自动加载appsettings.Production.json
  3. 最终,Logging.LogLevel被设置为了Production配置的值“Warning”,因而LogInformation()失效

  那么,只要正确设置ASPNETCORE_ENVIRONMENT值即可解决问题咯。

  但是,还记得上面提到的“environment.json”文件吗?这个文件目的本就是为了方便切换不同环境的配置文件而建立的,Logging的配置理应由它来决定,如果通过ASPNETCORE_ENVIRONMENT来设置,就多此一举了。那怎么才能让在Startup构造方法中构建的m_Configuration对象对Logging生效呢?官方也给出了方案:ConfigureAppConfiguration方法[2]!是不是觉得眼熟?在上面的CreateDefaultBuilder方法中正是通过ConfigureAppConfiguration()来加载默认配置的。

  最终,代码修正如下:

 1 private static IWebHost BuildWebHost(string[] args)
 2 {
 3     return WebHost.CreateDefaultBuilder(args)
 4         .CaptureStartupErrors(true)
 5         .UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
 6         .ConfigureAppConfiguration((hostingContext, config) =>
 7         {
 8             config.Sources.Clear();
 9             config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
10                 .AddJsonFile($"appsettings.{GetEnvironmentName()}.json", optional: true, reloadOnChange: true);
11         })
12         .UseStartup<Startup>()
13         .UseNLog()
14         .Build();
15 }
16
17 private static string GetEnvironmentName()
18 {
19     var configuration = new ConfigurationBuilder()
20         .AddJsonFile("environment.json", optional: true)
21         .Build();
22     return configuration["EnvironmentName"] ?? string.Empty;
23 }

BuildWebHost

  构建m_Configuration的代码,由Startup.cs转移到了Program.cs,而在Startup.cs中,Configuration对象可直接注入:

1 private readonly ILoggerFactory m_LoggerFactory;
2 private readonly IConfiguration m_Configuration;
3
4 public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
5 {
6     m_LoggerFactory = loggerFactory;
7     m_Configuration = configuration;
8 }

Startup

  至此,告一段落!

  参考文档

  1. 官方文档:配置Environment
  2. 官方文档:配置Configuration
  3. 官方文档:配置Logging
  4. ASP.Net Core 1.x迁移至2.0
  5. CreateDefaultBuilder源码
  6. asp.netcore 深入了解配置文件加载过程

原文地址:https://www.cnblogs.com/linys2333/p/9970597.html

时间: 2024-07-30 10:19:07

记一个ASP.Net Core配置文件问题的相关文章

使用Visual Studio Code创建第一个ASP.NET Core应用程序

全文翻译自:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 这篇文章将向你展示如何在Mac上写出你的第一个ASP.NET Core应用程序. 本文内容: 搭建开发环境 使用Yeoman搭建应用程序 使用Visual Studio Core开发ASP.NET应用程序 使用Kestrel在本地运行这个应用程序 将这个应用程序发布至Azure 学习资源 搭建开发环境 在你的开发机上下载并安装.Net Core和

Kubernetes初探[1]:部署你的第一个ASP.NET Core应用到k8s集群

转自:https://www.cnblogs.com/RainingNight/p/first-aspnetcore-app-in-k8s.html Kubernetes简介 Kubernetes是Google基于Borg开源的容器编排调度引擎,作为CNCF(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动得达到和维持在这个状态

从零写一个Asp.net core手脚架(模型验证)

一个asp.net core项目,一定包含了各种的实体,在RESTful api里面,有很多的参数传递,不建立实体则大量的参数需要自定验证正确性,并且Action上面会写的密密麻麻的参数 在asp.net 2.0的时候,就推出了ModelState,顾名思义,这个是模型状态,用于验证实体对象的 如何模型验证 用法是在需要验证的地方打上继承了ValidationAttribute的特性,比如常见的RequiredAttribute,这个是验证对象是否存在 /// <summary> /// Ad

ASP.NET Core 配置文件(无处不在的依赖注入)

前烟: .NET Core 中取消了以往的 XML 节点配置文件,改用了 *.json 格式. 在 Startup.cs 文件中,构造方法 build appsetting.json 文件, 本文主要对解析配置文件的官方工具类做总结: 一.appsettings.json 文件 在新建的 Core Web 项目中,默认会有一个全局的配置变量:IConfigurationRoot 提供了索引器.GetSection 方法: { "Host": "http://localhost

【翻译】在Mac上使用VSCode创建你的第一个Asp.Net Core应用

Setting Up Your Development Environment 设置你的开发环境 To setup your development machine download and install .NET Core and Visual Studio Code with the C# extension. Node.js and npm is also required. If not already installed visit nodejs.org. 首先在你的机器上下载.Ne

创建第一个ASP.NET CORE程序 使用DBFirst模式连接数据库

第一步: 第二步: 第三步: 第四步:在控制台输入命令 (1)Install-Package Microsoft.EntityFrameworkCore (2)Install-Package Microsoft.EntityFrameworkCore.SqlServer (3)Install-Package Microsoft.EntityFrameworkCore.Tools (4)Install-Package Microsoft.EntityFrameworkCore.SqlServer.

利用一个ASP.NET Core应用来发布静态文件

虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件的请求.针对不同格式的静态文件请求的处理,ASP.NET Core为我们提供了三个中间件,它们将是本系列文章论述的重点.不过在针对对它们展开介绍之前,我们照理通过一些简单的实例来体验一下如何在一个ASP.NET Core应用中发布静态文件.[本文已经同步到<ASP.NET Core框架揭秘>之中]

如何远程关闭一个ASP.NET Core应用?

在<历数依赖注入的N种玩法>演示系统自动注册服务的实例中,我们会发现输出的列表包含两个特殊的服务,它们的对应的服务接口分别是IApplicationLifetime和IHostingEnvironment,我们将分别实现这两个接口的服务统称在ApplicationLifetime和HostingEnvironment.我们从其命名即可以看出ApplicationLifetime与应用的声明周期有关,而HostingEnvironment则用来表示当前的执行环境,本篇文章我们着重来了解Appli

用VSCode开发一个asp.net core 2.0+angular 5项目(4): Angular5全局错误处理

第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三部分: https://www.cnblogs.com/cgzl/p/8525541.html 这篇文章将介绍angular 5的全局错误处理. 需要使用到代码: https://pan.baidu.com/s/1F0KjbwVE8_Tzfwy69Alp-A angular 5 全局错误处理 参考文