首页 > 解决方案 > Serilog 使用 appsettings.json 而不是 appsettings.Development.json

问题描述

我正在为 .NET 5 Worker 服务设置 Serilog,并在本地运行它。一切都按预期工作,然后我将 launchSettings.json 中的“DOTNET_ENIVORNMENT”环境变量从“Development”更改为“asdf”,以使用 appsettings.json 配置而不是 appsettings.Development.json 进行测试。一切都按预期工作。但是现在我已将该环境变量改回“开发”,Serilog 仍在使用来自 appsettings.json 的设置。

我将两个 appsettings 文件都设置为始终复制到输出目录。

<ItemGroup>
    <Content Update="appsettings.Development.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Update="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

这是我当前的 launchSettings.json 文件。

{
  "profiles": {
    "MyMicroservice": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}

当我运行程序时,Serilog 只写入一个文件,而不是 2 个文件和控制台。但是,我将 WorkerSettings 配置传递给我的 Worker.cs 类,它从 appsettings.Development.json 获取 5 秒的“TaskInterval”设置。为什么 Serilog 不使用 appsettings.Development.json 中的配置?

下面是我的 appsettings 文件和 Program.cs 文件。

appsettings.Development.json - 我设置 Serilog 设置以写入控制台和 2 个文件。我还创建了一个设置“TaskInterval”设置为 5 秒。

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Information",
        "System": "Warning"
      }
    },
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": "C:/temp/MyMicroservice/HealthCheck.txt",
          "outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}) {Message}{NewLine}{Exception}",
          "rollingInterval": "Day"
        }
      }
    ],
    "WriteTo:Async": {
      "Name": "Async",
      "Args": {
        "configure": [
          {
            "Name": "File",
            "Args": {
              "path": "%TEMP%/MyMicroservice/HealthCheck.txt",
              "outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}) {Message}{NewLine}{Exception}",
              "rollingInterval": "Day"
            }
          }
        ]
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  },
  "WorkerSettings": {
    "TaskInterval": 5000
  }
}

appsettings.json - 我将 Serilog 设置设置为仅写入 1 个文件。这次我将“TaskInterval”设置为 10 秒。

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Information",
        "System": "Warning"
      }
    },
    "WriteTo:Async": {
      "Name": "Async",
      "Args": {
        "configure": [
          {
            "Name": "File",
            "Args": {
              "path": "%TEMP%/MyMicroservice/HealthCheck.txt",
              "outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}) {Message}{NewLine}{Exception}",
              "rollingInterval": "Day"
            }
          }
        ]
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  },
  "WorkerSettings": {
    "TaskInterval": 10000
  }
}

程序.cs

public static class Program
    {
        public static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder();
            BuildConfig(builder);

            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(builder.Build())
                .CreateLogger();

            try
            {
                Log.Information("Starting up {Service}.", nameof(MyMicroservice));
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "There was a problem starting {Service}.", nameof(MyMicroservice));
            }
            finally
            {
                Log.Information("Ending {Service}.", nameof(MyMicroservice));
                Log.CloseAndFlush();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                        .ConfigureServices((hostContext, services) =>
                        {
                            services.AddOptions<WorkerSettings>().Bind(hostContext.Configuration.GetSection(nameof(WorkerSettings)));
                            //services.Configure<Settings>(hostContext.Configuration.GetSection(nameof(Settings)));
                            services.AddHostedService<Worker>();
                        })
                        .UseSerilog();
        }

        static void BuildConfig(IConfigurationBuilder builder)
        {
            builder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"apsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
        }
    }

标签: c#.net.net-5serilog

解决方案


这对我有用:

            var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            var isDevelopment = environmentName == "Development";
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: isDevelopment)
                .AddJsonFile($"appsettings.{environmentName}.json", true, isDevelopment)
                .Build();

            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateBootstrapLogger();

            CreateHostBuilder(args, configuration)
                .Build()
                .Run();
...


    private static IHostBuilder CreateHostBuilder(string[] args, IConfiguration configuration) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog((hostingContext, services, loggerConfiguration) =>
            {
                loggerConfiguration.ReadFrom.Configuration(configuration);
                loggerConfiguration.ReadFrom.Services(services);
                loggerConfiguration.Enrich.FromLogContext();
            })

推荐阅读