Is .NET Core 2.0 logging broken?

23,548

Solution 1

The way logging is configured has changed a little... The recommended way (and it's pretty well documented in this GitHub issue/announcement to do it now is to configure the loggers on the AddLogging method, such as

services.AddLogging(builder =>
{
    builder.AddConfiguration(Configuration.GetSection("Logging"))
        .AddConsole()
        .AddDebug();
});

And have an appsettings.json like

Notice

Seems a few people are confused, because the example only demonstrates the configuration of Console provider and not all loggers.

The LogLevel section configures logging level for all namespaces (Default key) or for a specific namespace (System overrides the default value for all classes logging whose namespace starts with System.*.

This is for the class used in T in ILogger<T>). This allows to set a higher or lower than default logging level for loggers from this namespace.

{
  "ApplicationInsights": {
    "InstrumentationKey": ""
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Information",
      "System": "Warning",
      "Microsoft": "Information"
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning",
        "System": "Information",
        "Microsoft": "Information"
      }
    }
  }
}

Please note that the structure of the appsettings.json changed from what it used to be in .NET Core 1.x and that Logging entry in the appsettings.json now has logger provider names in it, which allows you to configure logging levels per logging provider.

Previously, the entry in appsettings.json would only be applicable to the console logger.

Alternatively, the logging can now be moved within the WebHostBuilder instead.

public static void Main()
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;

            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddJsonFile("hosting.json", optional: false)
                .AddEnvironmentVariables();
        })
        .ConfigureLogging((webhostContext, builder) => {
            builder.AddConfiguration(webhostContext.Configuration.GetSection("Logging"))
            .AddConsole()
            .AddDebug();
        })
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights()
        .Build();

    host.Run();
}

Update

In case one doesn't want to use the appsettings.json, one can register the filters in code too.

services.AddLogging(builder =>
{
    builder.AddConfiguration(Configuration.GetSection("Logging"))
        // filter for all providers
        .AddFilter("System", LogLevel.Debug)
        // Only for Debug logger, using the provider type or it's alias
        .AddFilter("Debug", "System", LogLevel.Information)
        // Only for Console logger by provider type
        .AddFilter<DebugLoggerProvider>("System", LogLevel.Error)
        .AddConsole()
        .AddDebug();
});

Solution 2

I spent almost twenty minutes to realize that since Configuration.GetSection("Logging") in the Startup.cs file reads the section "Logging" from the config in the appsettings.json file, which was configured as "Error". Changing it to "Information" or anything lower, fixed the issue.

Here's what the appsettinsg.json file looks now:

{
  "Logging": {
    "IncludeScopes": true,
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

To find out more about the levels of logging (such as in "Information"), check out this link, that also provides general information on ASP.NET Core logging.

I'm just posting here, just in case you bump into any trouble with getting the logging to work, make sure you've been through that JSON file.

Solution 3

Nothing of the above works for me The only workaround was to write a method

private void ConfigLogging( ILoggingBuilder builder ) {
    builder.SetMinimumLevel( LogLevel.Trace );
    //... additional configuration...
}

and when using the AddLogging extension method write it as

services.AddLogging( ConfigLogging );
Share:
23,548
EinarI
Author by

EinarI

Updated on November 22, 2020

Comments

  • EinarI
    EinarI over 3 years

    I can't seem to get Trace level log information outputted after upgrading to .NET Core 2.0 (+ASP.NET Core 2.0).

    In fact, if I do a dotnet new webproject and add the code below in Startup for Configure, I do not get any trace or debug log messages, but I get the Information and Error messages twice. Commenting out the .AddConsole()call will output these (Information and Error) only once - suggesting that it gets configured automatically with a console provider by default. Keep in mind, this is a "File -> New" project experience, there is nothing setup in Program.cs for logging or configuration at all for this - except for what I've added. Anyone seen things? Or should I register a GitHub issue for it.

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Trace);
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.Run(async (context) =>
        {
            var logger = loggerFactory.CreateLogger("Blah");
            logger.LogTrace("Hello world : Trace");
            logger.LogDebug("Hello world : Debug");
            logger.LogInformation("Hello world : Information");
            logger.LogError("Hello world : Error");
    
            await context.Response.WriteAsync("Hello World!");
        });
    }
    
  • EinarI
    EinarI over 6 years
    Thanks.. In fact, just adding an appsettings.json file with the Logging configuration without any logging setup at all seems to give me what I need.
  • Dave Thieben
    Dave Thieben over 6 years
    or just builder.SetMinimumLevel(LogLevel.Trace);
  • Elan Hasson
    Elan Hasson over 6 years
    Note that using AddConfiguration requires the Microsoft.Extensions.Configuration package.
  • Neutrino
    Neutrino about 6 years
    Does any of this enable actual debug messages to be written to the log? That is with "LogLevel Default: Debug" the output of Debug.WriteLine ends up in the log. Because if not it's not much use, because 1) I don't want to have to inject Microsoft's logging class into every single low level component in my app and replace every single WriteLine with _log.LogDebug, 2) If I'm using a third party component I may not be able to inject Microsoft's logging class into these components.
  • Tseng
    Tseng almost 6 years
    @Neutrino: Debug.WriteLog isn't really meant for application level logging, its there for develop-time logging (which is the reasons it by default only logs to the Debug output window). For app-level logging you were always supposed to use an proper logging library. And there aren't many 3rd party libraries which use Debug.WriteLine and even if, Debug.WriteLine has a conditonal operator and is not compiled to release builds, check the msdn.
  • Tseng
    Tseng almost 6 years
    You sure your appsettings.json had the correct format? Or if the value was overriden by one of the other config sources (developing settings, environment variables etc)?
  • Naidan
    Naidan over 5 years
    I found your example of appsettings.json to be incorrect for .NET Core 2.1, this one worked for me docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/…
  • Tseng
    Tseng over 5 years
    @Art: May explain what it doesn't work? (other than that the LogLevel section may be missing, which sets the default logging level for all loggers, though the Console Logger was the one asked in the question). Also feel free to suggest an edit :)
  • Naidan
    Naidan over 5 years
    @Tseng with the logging config from the example above I could not get the Info messages logged. See my answer below in this thread with the example that worked for me.
  • Tseng
    Tseng over 5 years
    @Art: But that wasn't really a requirement of the question. The OP asked why his logging didn't work after upgrading and the answer was because the structure and way of configuring logging has changed. Before the parameter less constructor would set the default for all loggers. Now its taken either from the new appsettings.json structure or from the per-logger provider configuration entry (above sample for Console. How to configure it for your requirement wasn't part of the question. The Default one sets it for all namespaces, the Microsoft overrides it for all Microsoft.* namespaces
  • Tseng
    Tseng over 5 years
    This way you can set fine grained control over logging, i.e. have Information or lower for Default, and set Trace level etc. for a specific namespace you want to have logged/traced in detail. Why I asked was, because the above does works, but maybe not as you expect it, since only demonstrated how to setup console logger, not every logger
  • nan
    nan about 5 years
    I solved it by adding this line: .ConfigureLogging((hostingContext, logging) => { ... logging.AddConfiguration(hostingContext.Configuration.GetSec‌​tion("Logging")); ... })
  • AndyClaw
    AndyClaw over 4 years
    It's almost as if "Trace" is treated specially and will only be honored as a log level if in the declared code and NOT the config file. But I see no documentation of that.
  • nealsu
    nealsu over 3 years
    Incase it helps anyone, adding the following builder.ConfigureLogging((hostContext, logging) => { logging.AddConfiguration(hostContext.Configuration.GetSectio‌​n("Logging")); }); helped resolve my appSettings.json file being ignored as suggested by @Tseng. Performed on the IWebHostBuilder.