How to enable trace logging in ASP.NET Core?
I cannot get basic LogTrace(...)
output in my application. It reproduces here:
- Create a new ASP.NET Core app using Visual Studio 2017.
- (Optional) comment out
.UseApplicationInsights()
for clearer playback -
Replace the code with the
ValuesController.cs
following: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 also tried changing the values ββin the file appsettings.json
, but that didn't make any difference either.
Oddly enough, changing the value in any file to "Error"
does nothing either.
Bottom line / question
What do I need to do to get my inputs to ILogger<ValuesController>
respect the logging parameters including Trace
level?
Footnote
Here are some of the relevant code that would be auto-generated with the above reproduction:
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"
}
}
}
source to share
PERMISSION OF CHANGES FROM 2.0
As Tseng commented below, this answer will become deprecated as of 2.0 , you can find more in this statement here: https://github.com/aspnet/Announcements/issues/238
Where is the problem...
Based on your method Configure()
, I found the problem:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); // β¦ you're not passing the LogLevel!
app.UseMvc();
}
For this reason, none of your changes to the config set in the files appsettings.json
work.
.AddDebug()
Default behavior with no arguments passed Adds a debug log that is enabled for LogLevel.Information or higher.
If you want to explicitly set it to use a specific minimum LogLevel, you can pass it directly to the method AddDebug(ILoggerFactory, LogLevel)
.
loggerFactory.AddDebug(LogLevel.Trace);
More information can be found here .
Binding 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 inline object for LogLevel
(Deliberately left out. Obviously it sits between these two suggested methods.) I'd rather one of the extremes than go halfway.)
Method 3: Go Manual (use ConfigurationBinder)
Bizarre 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 can pass:
loggerFactory.AddDebug(obj.Default);
A special note about nodes and appsettings.json
Note that the delimiter for 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 values LogLevel
:
public enum LogLevel
{
Trace = 0,
Debug = 1,
Information = 2,
Warning = 3,
Error = 4,
Critical = 5,
None = 6,
}
source to share