WoodmanBlockerville
WoodmanBlockerville

Reputation: 173

Serilog using appsettings.json instead of appsettings.Development.json

I am setting up Serilog for a .NET 5 Worker Service, and running it locally. Everything was working as expected, then I changed the "DOTNET_ENIVORNMENT" environment variable in launchSettings.json from "Development" to "asdf" to test using appsettings.json config instead of appsettings.Development.json. Again everything worked as expected. But now that I have changed that environment variable back to "Development", Serilog is still using the settings from appsettings.json.

I set both appsettings files to be copied to output directory always.

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

Here is my current launchSettings.json file.

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

When I run the program Serilog only writes to one file, instead of 2 files and the console. However I am passing the WorkerSettings configuration to my Worker.cs class and it is getting the "TaskInterval" setting of 5 seconds from appsettings.Development.json. Why is Serilog not using config from appsettings.Development.json?

Below are my appsettings files and Program.cs file.

appsettings.Development.json - I setup Serilog settings to write to console and to 2 files. I also created a setting "TaskInterval" set to 5 seconds.

{
  "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 - I setup Serilog settings to write to only 1 file. This time I set the "TaskInterval" setting to 10 seconds.

{
  "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
  }
}

Program.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();
        }
    }

Upvotes: 5

Views: 5016

Answers (2)

Pascal Carmoni
Pascal Carmoni

Reputation: 594

.Net6 : DOTNET_ENVIRONMENT

Package : Serilog.Settings.Configuration

var environmentName = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile($"appsettings.{environmentName}.json")
    .Build();

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

Upvotes: 2

Andrew Bennett
Andrew Bennett

Reputation: 71

This works for me:

            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();
            })

Upvotes: 1

Related Questions