Search code examples
asp.net-coreloggingasp.net-core-webapiserilog

Serilog config in appsettings.json for an ASP.NET CORE application


Disclaimer

I know there are several similar questions posted about this subject, but I couldn't find one that exactly represented the problems I'm experiencing. That's why I'm opening a new question.

Current situation

I have an ASP.NET CORE API application build using VS2019 where I want to use Serilog for logging to a database server. To achieve this, I'm using some of the available Serilog NuGet packages

<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Exceptions" Version="6.1.0" />
<PackageReference Include="Serilog.Exceptions.EntityFrameworkCore" Version="6.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.MSSqlServer" Version="5.6.0" />

This application uses 4 build configurations: 'Develop', 'Test', 'Acceptance' and 'Production'

For setting up Serilog so I can use it in my application I've done the following in the Program.cs

public class Program
{
    public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        [...]
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
        .Build();

    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(Configuration)
            .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder()
              .WithDefaultDestructurers()
              .WithDestructurers(new[] { new DbUpdateExceptionDestructurer() })
              .WithFilter(new IgnorePropertyByNameExceptionFilter("StackTrace")))
            .Enrich.WithProperty([...])
            .WriteTo.Console()
            .CreateLogger();

        [...]
    }

    public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseConfiguration(Configuration)
        .UseSerilog()
        .Build();
}

And the appsettings.*.json:

{
  "Serilog": {
    "MinimumLevel": "Warning",
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": [...],
          "tableName": [...],
          "autoCreateSqlTable": false,
          "columnOptionsSection": {
            [...]
          }
        }
      }
    ]
  }
}

And the launchsettings.json:

{
  [...]  
  "profiles": {
    "Develop": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Test": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Test"
      }
    },
    "Acceptance": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Acceptance"
      }
    },
    "Production": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    }
  }
}

[edit] All of the appsettings files (appsettings.json as well as all the appsettings.*.json) have these properties

enter image description here

The challenges I'm facing

When I'm running the application locally on my machine (using the Develop build configuration), all works as expected. Logging is working well and logging to my develop SQL server.

The issues start when I'm using TFS to deploy the application to a remote machine. Whether I'm deploying to my Development server or Test server, the logging is not working. The appsetting.json, as well as the appsetting.*.json files are deployed to the server correctly. When I'm manually copying the settings from the appropriate appsettings.*.json to the appsettings.json, everything works as expected. The logging is be done in the correct SQL database. Therefore I know the settings are correct. It just looks like my deployment is somehow only picking up the settings from the appsettings.json, not including the settings from the appsettings.*.json. I must be overlooking something, but I can't see what. Hopefully someone can help me with this.


Solution

  • My suspicion is your application that's running on a remote machine doesn't have the environment variable ASPNETCORE_ENVIRONMENT set correctly.

    For instance, if you're on the Staging environment and expect the appsettings.Staging.json to load, You have to set the ASPNETCORE_ENVIRONMENT environment variable to Staging, otherwise, the settings file won't load.

    NOTE: the launchsettings.json file works only for local development and not for hosting on a remote server.