Search code examples
asp.net-coreconfigurationinlineserilogseq-logging

How do I configure Serilog aspnetcore with Seq sink?


I can't get log statements in Seq from my IIS hosted .net core 2.2 app. The logs appear when I debug and run the app with IISExpres. However only RequestLogging logs show up in Seq when the app runs from the application pool of a real IIS. I miss my logs.

Here's what I've done:

  1. Installed Nuget packages Serilog, Serilog.Aspnetcore and Serilog.Sinks.Seq.

  2. Removed all Microsoft.Extensions.Logging and references.

  3. Implemented inline configuration in Program.cs following the sample on Serilog.Aspnetcore Github page:

public class Program
{
      ...

      public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSerilog((hostingContext, loggerConfiguration) =>
                       loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
                        , preserveStaticLogger: true, writeToProviders: false);


}
  1. Added request logging in Startup.cs:
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ....

            app.UseHttpsRedirection();
            app.UseSerilogRequestLogging();
            app.UseMvc();
        }
  1. Configured Serilog in appsettings.json so apiKey and Seq serverUrl are configurable in deployment by Azure DevOps for Dev, Test and Production environments:
{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Seq" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "Enrich": [ "FromLogContext" ],
    "WriteTo": [
      {
        "Name": "Seq",
        "Args": {
          "apiKey": "iVPcw1...",
          "serverUrl": "http://localhost:5341"
        }
      }
    ]
  },
    ...
}
  1. Added logger and initializing in classes as usual like this:
     public class SomeService : ISomeService
     {
        private readonly ILogger logger;
        ...

        public SomeService( ...injections...) {

            logger = Log.ForContext<SomeService>();
            ...
        }

        ...
        public async Task ServiceMethod(Data d) 
        {
            logger.Information("ServiceMethod called with {@d}");
        }

        ...
    }

Solution

  • Among the arguments to UseSerilog() you have:

    preserveStaticLogger: true
    

    This instructs UseSerilog() to not set/modify the static Log.Logger instance, which means when you use it in:

    logger = Log.ForContext<SomeService>();
    

    you'll be getting the default, unconfigured, do-nothing logger.

    Setting preserveStaticLogger: false should fix this.