How to enable Trace logging in ASP.NET Core?
Asked Answered
G

3

17

I cannot get basice LogTrace(...) output in my application. Here's a repro:

  1. Create a new ASP.NET Core application using Visual Studio 2017.
  2. (Optional) comment out .UseApplicationInsights() so the repro is clearer
  3. Replace the code in ValuesController.cs with this:

    using System.Collections.Generic;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    
    namespace WebApplication1.Controllers
    {
        [Route("api/[controller]")]
        public class ValuesController : Controller
        {
            private readonly ILogger<ValuesController> logger;
    
            public ValuesController(ILogger<ValuesController> logger)
            {
                this.logger = logger;
            }
    
            [HttpGet]
            public IEnumerable<string> Get()
            {
                logger.LogError("ERROR!");
                logger.LogWarning("WARN!");
                logger.LogInformation("INFO!");
                logger.LogTrace("TRACE!");
                return new string[] { "value1", "value2" };
            }
        }
    }
    
  4. Change appsettings.Development.json to this:

    {
      "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
          "Default": "Trace",
          "System": "Information",
          "Microsoft": "Information"
        }
      }
    }
    
  5. Run and view the Debug output

This leads to:

  • Actual output:

    only ERROR, WARN, and INFO

  • Expected output would be the "TRACE!" message as well

I've tried tweaking the values in the appsettings.json file as well, but that had no effect either.

Weirdly, changing the value in either file to "Error" doesn't do anything either.

Bottom Line / Question

What do I need to do to make my injected ILogger<ValuesController> respect the logging settings, including Trace level?


Footnote

Here's some of the relevant code that would be auto-generated with the above repro:

Startup.cs

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseMvc();
    }
}

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();

        host.Run();
    }
}

appsettings.json default:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}
Gauge answered 28/5, 2017 at 11:4 Comment(1)
Just a heads up... There will be breaking changes regarding this issue as of 2.0 (credit to @Tseng ). I updated my answer accordingly.Resht
R
17

BREAKING CHANGES AS OF 2.0
As Tseng commented below, this answer will become obsolete as of 2.0 you can find more on this annoucement here: https://github.com/aspnet/Announcements/issues/238


Where the problem lies...

Based on your Configure() method, I have spotted an issue:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug(); // ⇦ you're not passing the LogLevel!

    app.UseMvc();
}

This is the reason why none of your changes to the configuration set in the appsettings.json files is not working.

The default behaviour of .AddDebug() without any arguments passed is
Adds a debug logger that is enabled for LogLevel.Information or higher.

If you want to explicitly set it to use a particular minimum LogLevel, then you can pass it directly to the AddDebug(ILoggerFactory, LogLevel) method.

loggerFactory.AddDebug(LogLevel.Trace);

More information can be found here.


Binding it to your configuration.

Method 1: Grab the value from the configuration.

LogLevel foo = this.Configuration.GetSection("Logging:LogLevel")
    .GetValue<LogLevel>("Default");
loggerFactory.AddDebug(foo);

Method 2: Use the built-in object for LogLevel

(Intentionally left out. Obviously it sits snug between these two methods offered.) I would favor one of the extremes than to go halfway)

Method 3: Go Manual (use ConfigurationBinder)

The fancy ConfigurationBinder

var obj = new MyObject();
ConfigurationBinder.Bind(_configuration.GetSection("Logging:LogLevel"), obj);

which will map to an object like

public class MyObject
{
    public LogLevel Default { get; set; }
    public LogLevel System { get; set; }
    public LogLevel Microsoft { get; set; }
}

so you could then pass:

loggerFactory.AddDebug(obj.Default);

Special note about nodes and appsettings.json

Note that the delimiter for the configuration uses :.

Example: "Logging:LogLevel" will go:

"Logging": {
  "IncludeScopes": false,
  "LogLevel": {             ⇦⇦⇦⇦⇦ Here
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Information"
  }
}

LogLevel Enum

Just for reference, here are the valid LogLevel values:

public enum LogLevel
{
    Trace = 0,
    Debug = 1,
    Information = 2,
    Warning = 3,
    Error = 4,
    Critical = 5,
    None = 6,
}

Source:
https://learn.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.logging.loglevel#Microsoft_Extensions_Logging_LogLevel

Resht answered 28/5, 2017 at 11:16 Comment(5)
@Gauge Did you try Debug or Verbose.. There is no such option as TraceResht
There was Verbose once, but it was changed some time inbetween ASP.NET Core 1.0 RC1 and RC2Chickamauga
Your changed answer makes sense, and is working. Would you happen to know of a good way to re-use the Configuration section? It seems there is no overload for AddDebug that takes one, or is there?Gauge
Might be worth noting, that this gonna change with 2.0 (already in effect in the 2.0 previews): Breaking Logging changes and new additions which will allow configuring all logging providers via appsettings.jsonChickamauga
@Chickamauga - That's a great note. I appreciate you spotting that.Resht
R
10

This worked for me. Add it in the ConfigureServices(IServiceCollection services) method:

services.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));
Relegate answered 14/10, 2017 at 15:35 Comment(0)
D
7

I tried:

services.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));

Where the problem lies...

None of those helped me. In my case I had appsettings.Development.json in folder with exe. This file had set Default to Information. That was reason why I could not see Trace logs. This file is hidden in Solution Explorer in visual studio. I had to expand appsettings.json to see this file.

After I changed Information => Trace I could see logs with severity Trace.

Denisdenise answered 23/6, 2021 at 12:15 Comment(1)
Good catch, now I am embarrassed that I missed that somehowVestal

© 2022 - 2024 — McMap. All rights reserved.