web-dev-qa-db-ja.com

ASP.NET Coreでトレースログを有効にする方法

アプリケーションで基本LogTrace(...)出力を取得できません。これが再現です:

  1. Visual Studio 2017を使用して、新しいASP.NET Coreアプリケーションを作成します。
  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. デバッグ出力を実行して表示する

これはにつながります:

  • 実際の出力:

    only ERROR, WARN, and INFO

  • 予想される出力は "TRACE!"です。メッセージも

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"
    }
  }
}
6
Jeroen

2.0以降の重大な変更
Tsengが以下でコメントしたように、この回答は2.0で廃止されますこのお知らせの詳細をご覧くださいここ: 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_ファイルの設定セットへの変更が機能しない理由です。

引数を渡さない場合の.AddDebug()のデフォルトの動作は
LogLevel.Information以降で有効なデバッグロガーを追加します。

特定の最小LogLevelを使用するように明示的に設定する場合は、AddDebug(ILoggerFactory, LogLevel)メソッドに直接渡すことができます。

_loggerFactory.AddDebug(LogLevel.Trace);
_

詳細は here を参照してください。


それを構成にバインドします。

方法1:構成から値を取得します。

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

方法2:LogLevelの組み込みオブジェクトを使用する

(意図的に省略されています。明らかに、これらの2つの方法の間にぴったりと収まります。)途中で行くよりも、極端な方法の1つを使用します)

方法3:手動で実行(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

14
Svek

これでうまくいきました。 ConfigureServices(IServiceCollection services)メソッドに追加します。

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