asp.net-coremicrosoft-extensions-loggingserilog-filter

Set Log Levels for Microsoft.* , System, and AspNet when using Serilog


I had always imagined that

  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },

would set my project code's log level to Debug, and make Microsoft.* namespaces log at Information level or higher. It seems not. With this config, AspNetCore infrastructure logs at Debug level.

How do I target Microsoft.* to not use the Default level?

I'm using Serilog, but the injected Loggers are all Microsoft.Extensions.Logging.ILogger so I expected Microsoft.Extensions.Logging config to kick in.

Is this a mistaken assumption?


Solution

  • Yes, the assumption that Serilog will respect the Logging.LogLevel section when used with Extensions.Logging is wrong. It doesn't.

    To read serilog levels from config, some options are:

      "Serilog": {
        "MinimumLevel": {
          "Default": "Information",
          "Override": {
            "MyStuff.ThatsStillWorkInProgress": "Verbose",
            "MyStuff.ThatsOldAndWellTested": "Information",
            "Microsoft": "Warning",
            "Microsoft.AspNetCore.Hosting": "Information",
            "Microsoft.AspNetCore.Hosting.Diagnostics": "Debug",
            "Microsoft.Hosting.Lifetime": "Information",
            "Microsoft.AspNetCore.SignalR": "Information",        
            "System": "Warning",
            "System.Net": "Error"
          }
        },
        "WriteTo": [
          {
            "Name": "File",
            "Args": {
              "Path": "../logs/log-%COMPUTERNAME%-.txt",
              "rollingInterval": "Day"
            }
          }
        ]
      },
    
    var defaultLogLevel = configuration.GetLogLevel("Default");
    var aspNetCoreLogLevel = configuration.GetLogLevel("Microsoft.AspNetCore");
    var microsoftLogLevel = configuration.GetLogLevel("Microsoft");
    var logger = new LoggerConfiguration()
                    .MinimumLevel.Is(defaultLogLevel)
                    .MinimumLevel.Override("Microsoft.AspNetCore", aspNetCoreLogLevel)
                    .MinimumLevel.Override("Microsoft", microsoftLogLevel)
                    // ... etc ...
    
    // ...
    
    static LogEventLevel GetLogLevel(this IConfiguration configuration, string @namespace, string fallbackLevel = "Information")
    {
            return Enum.Parse<LogEventLevel>(configuration["Logging:LogLevel:" + @namespace] ?? fallbackLevel);
    }
    

    Other Points