古くから実績のあるロギングライブラリ log4net ですが、現在の .NET (Core) 環境でも、Microsoft の標準ロギングインターフェース(ILogger)を通して利用することが可能です。
既存資産の流用や、log4net 特有の設定(強力なローテーション機能など)を使いたい場合に有効です。
実装サンプル:日次データ集計バッチ
ここでは、「データ集計サービス(AggregationService)」が動作し、警告(Warning)以上の重要なログだけを daily-batch.log に記録する構成を作成します。
1. パッケージのインストール
必要なアダプターパッケージをインストールします。
dotnet add package Microsoft.Extensions.Logging.Log4Net.AspNetCore
2. log4net.config の作成
プロジェクト直下に log4net.config を作成します。 注意: ファイルのプロパティで「出力ディレクトリにコピー: 常にコピー」に設定することを忘れないでください。
以下の設定では、ログファイルを 50MB ごとに分割し、最大5世代までバックアップを残す設定にしています。
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="RollingFile" />
</root>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="logs/daily-batch.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="50MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%-5level] %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
</appender>
</log4net>
3. Program.cs (Log4netの組み込み)
ホスト構築時に .AddLog4Net() を追加するだけで、アプリケーション全体のログ出力先として log4net が有効になります。
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
namespace BatchSystem
{
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) =>
{
// 標準のログプロバイダを一度クリア
logging.ClearProviders();
// 最低ログレベルの設定(ここではTrace以上を通過させる)
logging.SetMinimumLevel(LogLevel.Trace);
// log4net を追加 (デフォルトで直下の log4net.config を読み込みます)
logging.AddLog4Net();
})
.ConfigureServices((context, services) =>
{
// 集計サービスを登録
services.AddHostedService<AggregationService>();
});
}
}
4. AggregationService.cs (ログ出力の実装)
ログを出力するクラス側では、log4net への依存はなく、標準の ILogger を使って記述します。
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;
namespace BatchSystem
{
public class AggregationService : BackgroundService
{
private readonly ILogger<AggregationService> _logger;
public AggregationService(ILogger<AggregationService> logger)
{
_logger = logger;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
// --- 以下のログは設定によりファイルには出力されません (Information以下) ---
_logger.LogTrace("詳細: メモリ使用量の計測開始");
_logger.LogDebug("デバッグ: DB接続文字列のパース成功");
_logger.LogInformation("情報: 日次集計処理を開始しました");
// --- 以下のログはファイル(daily-batch.log)に記録されます (Warning以上) ---
// 警告: 処理は継続できるが、注意が必要なケース
_logger.LogWarning("警告: 集計対象データの一部が欠損しています (Date: 2025-01-10)");
// エラー: 処理が失敗したケース
_logger.LogError("エラー: 出力先ディレクトリへの書き込み権限がありません");
// 致命的: システム停止が必要なケース
_logger.LogCritical("致命的: データベースとの接続が切断されました。強制終了します");
return Task.CompletedTask;
}
}
}
解説
フィルタリングの挙動
この構成では、アプリケーションコード内で LogInformation を記述しても、log4net.config 側の <levelMin value="WARN" /> というフィルタによって弾かれるため、ログファイルには出力されません。 これにより、「開発中はコンソールですべて確認し、本番運用のログファイルにはエラーだけを残す」といった制御が可能になります。
設定ファイルの配置
log4net.config が読み込まれないトラブルの多くは、ビルド時に実行フォルダ(bin/Debug/...)へファイルがコピーされていないことが原因です。Visual Studioのプロパティまたは .csproj ファイルで <CopyToOutputDirectory>Always</CopyToOutputDirectory> が設定されているか必ず確認してください。
