【C#】コードでログレベルとフィルタを設定する (SetMinimumLevel / AddFilter)

appsettings.json を使用せず、C# のコード上で直接ログレベルやフィルタリングルールを設定する方法です。 「デフォルトでは警告以上を表示するが、特定の名前空間だけはエラー以上にする」といった細かい制御を、コンパイル時のルールとして定義できます。

目次

実装サンプル:在庫管理システム

以下の例では、アプリケーション全体(SystemやMicrosoft含む)のログレベルを Warning (警告) に設定しつつ、自作の WarehouseApp 名前空間だけはさらに厳しく Error (エラー) 以上のみ表示するようにフィルタリングしています。

1. Program.cs (ホスト設定)

ConfigureLogging メソッド内で SetMinimumLevelAddFilter を使用します。

using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;

namespace WarehouseApp
{
    class Program
    {
        static async Task Main(string[] args) =>
            await CreateHostBuilder(args).Build().RunAsync();

        private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging((context, logging) =>
                {
                    // 1. 一旦デフォルトのログプロバイダを削除
                    logging.ClearProviders();
                    
                    // 2. コンソール出力を追加
                    logging.AddConsole();

                    // 3. 全体の最低ログレベルを "Warning" に設定
                    // これにより、InformationやDebugは原則表示されなくなります
                    logging.SetMinimumLevel(LogLevel.Warning);

                    // 4. 特定のカテゴリ(名前空間)に対するフィルタを追加
                    // "WarehouseApp" 名前空間のクラスは "Error" 以上のみ表示する
                    logging.AddFilter("WarehouseApp", LogLevel.Error);
                })
                .ConfigureServices((context, services) =>
                {
                    // ワーカースレッドの登録
                    services.AddHostedService<InventoryWorker>();
                });
    }
}

2. InventoryWorker.cs (ログ出力クラス)

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace WarehouseApp
{
    public class InventoryWorker : BackgroundService
    {
        private readonly ILogger<InventoryWorker> _logger;

        public InventoryWorker(ILogger<InventoryWorker> logger)
        {
            _logger = logger;
        }

        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // Program.cs の設定により、このクラス(WarehouseApp)では
            // Error未満のログはすべて無視されます。

            _logger.LogTrace("詳細トレース: 在庫スキャン開始");    // 表示されない
            _logger.LogDebug("デバッグ: DB接続確認");              // 表示されない
            _logger.LogInformation("情報: 定期処理を実行中");      // 表示されない
            
            // 全体設定は Warning ですが、フィルタで Error に引き上げているためこれも表示されません
            _logger.LogWarning("警告: スキャンに時間がかかっています"); // 表示されない

            // ↓ ここから下が表示される
            _logger.LogError("エラー: 在庫データの不整合を検知");
            _logger.LogCritical("致命的: 在庫DBが応答しません");

            return Task.CompletedTask;
        }
    }
}

3. 実行結果

fail: WarehouseApp.InventoryWorker[0]
      エラー: 在庫データの不整合を検知
crit: WarehouseApp.InventoryWorker[0]
      致命的: 在庫DBが応答しません

解説

SetMinimumLevel と AddFilter の違い

  1. logging.SetMinimumLevel(LogLevel.Warning) アプリケーション全体の「底上げ」を行います。ここで指定したレベルより低いログ(Trace, Debug, Information)は、どのクラスからも出力されなくなります。
  2. logging.AddFilter("Category", LogLevel.Error) 特定のカテゴリ(通常は名前空間やクラス名)に対して、個別のルールを上書きします。 今回の例では、全体を Warning に設定しつつ、自分たちが書いている WarehouseApp のコードだけは Error に制限することで、開発中の余計な警告ログを抑制しています。

コード設定の優先度

appsettings.json とコードでの設定が競合した場合、基本的には 後から読み込まれた設定(または AddConfiguration で明示した設定) が有効になりますが、AddFilter をコードで記述した場合は強力なルールとして機能します。環境ごとに挙動を変えたい場合は appsettings.json、絶対に守らせたいルールはコード、と使い分けるのが推奨されます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次