6

I am using NET5 ASP.NET MVC application. Application is using Serilog.AspNetCore 3.4.0 for logging

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Error"
    }
  },
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console"],
    "WriteTo": [
      {
        "Name": "Console"
      }
    ]
  }
}

Program.cs

     public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder
                   .UseStartup<Startup>()
                   .ConfigureLogging((hostingContext, logging) =>
                   {
                       logging.ClearProviders();                    
                   })                       
                   .UseSerilog((hostingContext, logging) =>
                   {
                      logging.ReadFrom.Configuration(hostingContext.Configuration);
                   });
            });

I have also tried

 public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder
                   .UseStartup<Startup>()
                   .ConfigureLogging((hostingContext, logging) =>
                   {
                       logging.ClearProviders();
                       Log.Logger = new LoggerConfiguration()
                       .ReadFrom.Configuration(hostingContext.Configuration)                           
                       .CreateLogger();
                       logging.AddSerilog();
                   });                       
               
            });

Issue
My expectation is no Information log will be shown in Console since default LogLevel is Error. However, that is not working. In console I see every request is getting logged including Information

Throughout my application I am using Microsoft.Extensions.Logging.ILogger<MyClassName> to log information. All those statements are actually logging Info even if the LogLevel is Error.

Looks like Serilog ignoring LogLevel from Microsoft.Extensions.Logging.

Note that, I can set serilog's restrictedToMinimumLevel property to Error and that stops logging information. However I think serilog should obey the LogLevel from Microsoft.Extension.Logging

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
LP13
  • 30,567
  • 53
  • 217
  • 400

3 Answers3

5

If you check the project's Github page it advises to actually remove the standard "Logging" section in appsettings.json :-(

Serilog's guidelines

I think this is bad since it actually breaks the compatibility with Microsoft.Extensions.Logging framework (you can't anymore change the actual log provider (Log4Net, NLog, Serilog) without changing the appsettings.json).

fededim
  • 429
  • 5
  • 12
  • I have opened a [feature request](https://github.com/serilog/serilog-aspnetcore/issues/299) on Serilog project, if someone wants to support it – fededim Jun 08 '22 at 19:25
3

Use MinimumLevel property:

  "Logging": {
    "MinimumLevel": {
      "Default": "Error"
    }
  }

Also it supports overrides for categories:

  "Logging": {
    "MinimumLevel": {
      "Default": "Error",
      "Override": {
        "System": "Information",
        "Microsoft": "Information",
        "Microsoft.Hosting.Lifetime": "Information",
        "Microsoft.EntityFrameworkCore": "Debug"
      }
    }
  }
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • Serilog.Settings.Configuration is already included in `Serilog.AspNetCore` package. and it used for `A Serilog settings provider that reads from Microsoft.Extensions.Configuration sources, including .NET Core's appsettings.json file.` – LP13 Jan 28 '21 at 22:36
  • @LP13 yep, missed that you use the `AspNetCore` one. – Guru Stron Jan 28 '21 at 22:40
  • 1
    btw the yes, if i set Serilog's Minimum Level directly then it works. However serilog should read minimum level from Microsoft's logging. Thats the whole point of Serilog.Settings.Configuration – LP13 Jan 28 '21 at 22:42
  • 1
    @LP13 "However serilog should read minimum level from Microsoft's logging. Thats the whole point of Serilog.Settings.Configuration" - no, it is not, check their [docs](https://github.com/serilog/serilog-settings-configuration). For example by default their check only `Serilog` section of the config. – Guru Stron Jan 28 '21 at 22:48
  • I have another application that is using NET Core 2 and in that application Serilog is reading Default level from `Logging` section. May be its not support in `NET5`? Not sure https://github.com/serilog/serilog-settings-configuration#net-50-single-file-applications – LP13 Jan 28 '21 at 22:51
  • 2
    Serilog never uses Microsoft's configuration sections - always under `"Serilog"` even in the older versions. @LP13 you might be seeing a difference between `AddSerilog()` in your older app (plugs Serilog in as a provider under MEL's logging framework), vs. `UseSerilog()` (newer, runs all logging through Serilog without the MEL wrapper). – Nicholas Blumhardt Jan 28 '21 at 23:17
  • 1
    @NicholasBlumhardt you are correct on `AddSerilog`. In my older app `NET Core 2.2`, I am using `AddSerilog`. I tried the same code with `NET5` and it did not work ( See my second option above that says "I have also tried") – LP13 Jan 28 '21 at 23:29
1

If you use Serilog.Extensions.Logging and AddSerilog() on ILoggingBuilder, you'll get what you're expecting.

However, IHostBuilder.UseSerilog() (provided by Serilog.Extensions.Hosting, via Serilog.AspNetCore) is almost always a better choice, hence that's what all the Serilog docs show.

Although it seems more "integrated" to use the default configuration section this way, what you're getting behind the scenes is actually two different logging frameworks running at the same time, e.g. in the AddSerilog() case (or in the default NLog configuration):

ILogger<T> -->
    MEL (routing, configuration, levels, filters) -->
        Serilog (routing, configuration, levels, filters)

Logging is supposed to be very predictable/reliable and lightweight. Having two logging frameworks running at the same time erodes this and creates problems where the levels and filters specified for one framework don't match the other. (E.g. Debug and trace logs not printed when using Nlog and ILoggerFactory in .NetCore console app).

In the UseSerilog() case, (and when NLog's ReplaceLoggerFactory option is specified - mentioned in a comment on the SO thread above), you get:

ILogger<T> -->
    Serilog (routing, configuration, levels, filters)

You give up support for the default "Logging" configuration section, but in exchange, you get rid of a whole logging framework at runtime, and all of your Serilog (or NLog) configuration just works, with the Microsoft.Extensions.Logging ILogger<T> available to your application code and the framework.

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101