新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

GenericHostのILoggerでDebug以下のログを出す時に引っかかりがちなポイント

概要

.NET 8のテンプレートでWindowsサービスを作成した場合に(つまりテンプレートでGenericHostを使った場合に)、ILoggerでDebug,Traceなどの詳細レベルのログを出そうとすると、デフォルトでOFFになっている上にフィルタの階層が複数あるので、意外なところで引っかかります。その解決方法をいくつか紹介します。ちなみに、Windowsサービスの作成方法は以前の記事で紹介しました。

最初に結論

  1. カテゴリ別のデフォルト設定を持っているタイプ(コンソール出力のConsoleLoggerProviderなど)は、appsettings.jsonやコード上のAddFilter()でフィルタを上書きする必要があります。
  2. カテゴリ別のデフォルト設定を持たないタイプは、まずテンプレートで生成されているappsettings.jsonに注意。そこを書き換えるか、削除してコード上のSetMinimumLevel()などで設定する必要があります。

詳しく

カテゴリ別のデフォルト設定を持っているタイプ

とりあえず動作確認として手軽にログを見ようとする場合、GenericHostに最初から入っているコンソール出力やAddEventLog()で追加したイベントログ出力が便利なので、使うことは多いと思います。しかし、そこにDebugレベル以下を出そうとすると、出ません。 builder.Logging.SetMinimumLevel(LogLevel.Trace) のようにログレベルを設定してみても、出ません。

ConsoleやEventLogのプロバイダは、カテゴリ別のデフォルト設定を持っているためです。それぞれのプロバイダに対して、設定を上書きする必要があります。appsettings.jsonの追記、もしくはコードの追記で、これらを書き換えます。コンソールの設定例を次に書きます。

appsettings.jsonの例

{
  "Logging": {
    "Console": {
      "LogLevel": {
        "Default": "Trace"
      }
    }
  }
}

コードの例

var builder = Host.CreateApplicationBuilder(args);
(略)
builder.Logging.AddFilter<ConsoleLoggerProvider>(level => LogLevel.Trace <= level);

このどちらかの設定をすると、コンソールへのログ出力に、Trace・Debugのレベルが含まれるようになります。

カテゴリ別のデフォルト設定を持っていないタイプ

カテゴリ別のデフォルト設定を持っていなければ、全体の設定に従います。では今度こそ、 builder.Logging.SetMinimumLevel(LogLevel.Trace) を設定すれば出力される・・・と思ったら、出力されません。ここで、コードの方だけを見ていると罠にはまります。

テンプレートで生成されたコードをよく見てみると、プロジェクトの中に「appsettings.json」ファイルが有ります。こいつが、次の内容になっています。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

この "Default": "Information" でフィルタされてしまうので、コードの方だけで設定を変更しても出力されません。自分でappsettings.jsonを書いていればすぐ気付くことですが、テンプレートで生成してそのままにしておくと見落としがちなので、注意です。

というわけで、次のようにTraceレベルに変更すれば、出力されるようになります。

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

あるいは、その "Default" キーの部分は削除してしまい、コード上で設定します。

var builder = Host.CreateApplicationBuilder(args);
(略)
builder.Logging.SetMinimumLevel(LogLevel.Trace);

これで、デフォルト設定を持っていないプロバイダのログ出力に、Trace・Debugのレベルが含まれるようになります。

まとめ

ILoggerでのDebug・Traceレベルのログ出力方法について、引っかかりがちなポイントを2つ紹介しました。同じところで引っかかっている人の問題解決に役立ったら嬉しいです。

ILoggerはとても便利な仕組みで、あれこれ初期化や組み込むためのコードを書かずともログ出力ができて助かります。しかし、デフォルトと違う動作にしようとすると、理解して使わないと意外なところで引っかかるので、注意です。もっとちゃんと全体を理解しようという場合は、MSのこのあたりのドキュメントが良いと思います。C# でのログ記録 - .NET | Microsoft Learn