I cannot get basice LogTrace(...)
output in my application. Here's a repro:
.UseApplicationInsights()
so the repro is clearerReplace 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" };
}
}
}
Change appsettings.Development.json
to this:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "Information"
}
}
}
Run and view the Debug output
This leads to:
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.
What do I need to do to make my injected ILogger<ValuesController>
respect the logging settings, including Trace
level?
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"
}
}
}
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
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.
LogLevel foo = this.Configuration.GetSection("Logging:LogLevel")
.GetValue<LogLevel>("Default");
loggerFactory.AddDebug(foo);
(Intentionally left out. Obviously it sits snug between these two methods offered.) I would favor one of the extremes than to go halfway)
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);
Note that the delimiter for the configuration uses :
.
Example: "Logging:LogLevel"
will go:
"Logging": {
"IncludeScopes": false,
"LogLevel": { ⇦⇦⇦⇦⇦ Here
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
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,
}