如何在 ASP.NET Core 中启用跟踪日志记录?

How to enable Trace logging in ASP.NET Core?

我无法在我的应用程序中获得基本 LogTrace(...) 输出。这是一个重现:

  1. 使用 Visual Studio 2017 创建一个新的 ASP.NET 核心应用程序。
  2. (可选)注释掉 .UseApplicationInsights() 以便重现更清晰
  3. ValuesController.cs中的代码替换为:

    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. appsettings.Development.json改成这样:

    {
      "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
          "Default": "Trace",
          "System": "Information",
          "Microsoft": "Information"
        }
      }
    }
    
  5. 运行 并查看调试输出

这导致:

我也试过调整 appsettings.json 文件中的值,但这也没有效果。

奇怪的是,将任一文件中的值更改为 "Error" 也没有任何作用。

底线/问题

我需要做什么才能使我注入的 ILogger<ValuesController> 符合日志记录设置,包括 Trace 级别?


脚注

以下是使用上述重现自动生成的一些相关代码:

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默认:

{
  "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


问题出在哪里...

根据您的Configure()方法,我发现了一个问题:

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

    app.UseMvc();
}

这就是为什么您对 appsettings.json 文件中的配置集所做的 none 更改不起作用的原因。

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

如果您想明确设置它使用特定的最小 LogLevel,那么您可以将它直接传递给 AddDebug(ILoggerFactory, LogLevel) 方法。

loggerFactory.AddDebug(LogLevel.Trace);

可以找到更多信息 here


将其绑定到您的配置。

方法一:从配置中抓取值。

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

方法二:使用LogLevel的内置对象

(故意遗漏。显然,它恰好位于所提供的这两种方法之间。)我宁愿选择其中一种极端方法,也不愿半途而废)

方法三:手动(使用ConfigurationBinder)

花式ConfigurationBinder

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

这将映射到像

这样的对象
public class MyObject
{
    public LogLevel Default { get; set; }
    public LogLevel System { get; set; }
    public LogLevel Microsoft { get; set; }
}

所以你可以通过:

loggerFactory.AddDebug(obj.Default);

关于节点的特别说明和appsettings.json

注意配置的分隔符使用:.

示例:"Logging:LogLevel" 将去:

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

LogLevel 枚举

仅供参考,以下是有效的 LogLevel 值:

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

来源:
https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.logging.loglevel#Microsoft_Extensions_Logging_LogLevel

这对我有用。在ConfigureServices(IServiceCollection services)方法中添加:

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

我试过了:

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

Where the problem lies...

None 帮助了我。在我的例子中,我在带有 exe 的文件夹中有 appsettings.Development.json。该文件已将默认设置为信息。这就是为什么我看不到跟踪日志的原因。此文件隐藏在 visual studio 的解决方案资源管理器中。我必须展开 appsettings.json 才能看到此文件。

更改 Information => Trace 后,我可以看到严重性为 Trace 的日志。