概要と対応環境
NLogのFileターゲットは、アプリケーションの診断情報やイベントログをディスク上のテキストファイルに保存するための核心コンポーネントです。単一ファイルへの集中出力、動的なファイル分割、サイズまたは時間ベースの自動アーカイブなどを柔軟に構成できます。広範な.NET実行環境(.NET Framework 1.0〜4.0、Silverlight 4.0、.NET Compact Framework、Monoなど)に対応しています。
基本設定構造
設定は通常NLog.config内の<targets>セクションに記述します。属性は論理的なグループに分類して配置できます。
<targets>
<target xsi:type="File"
name="diskWriter"
fileName="${logdir}/app_${date:format=yyyyMMdd}.log"
layout="${longdate} | ${level} | ${callsite} | ${message}"
encoding="utf-8"
lineEnding="CRLF" />
</targets>
主要パラメータ解説
出力・フォーマット関連
- name: ターゲットの識別子。ルールセクションから参照されるために使用します。
- layout: ログメッセージの書式定義。デフォルトは
${longdate}|${level:uppercase=true}|${logger}|${message}です。 - header / footer: ファイルの先頭または末尾に固定テキストを挿入します。
- encoding: 出力ファイルの文字コード(例:
utf-8,shift_jis)。 - lineEnding: 改行コードの指定。
CRLF、LF、Default(OS依存)などから選択可能です。
アーカイブ・ローテーション関連
- archiveAboveSize: 指定サイズ(バイト)を超えた場合にファイルを分割または移動します。
- maxArchiveFiles: ディスク上に保持するアーカイブファイルの最大数。
- archiveFileName: 移動先のファイルパス。
{#####}などのプレースホルダーを使用し、連番や日付を動的に展開できます。 - archiveNumbering: 命名規則。
Rolling(最新ファイルが0番)またはSequence(連番増加)を指定。 - archiveEvery: 時間ベースの分割頻度。
Day、Hour、Monthなど。指定単位の変更タイミングにおける初回書き込みでトリガーされます。
性能・ファイル制御関連
- fileName: 出力先ファイルパス。${level}や${logger}などのレイアウトレンダラーを含むことで、動的なファイル振り分けが可能です。
- createDirs: 出力ディレクトリが未存在の場合に自動作成するかどうか。パフォーマンス微改善を狙って
falseに設定できますが、ディレクトリが存在しないと例外が発生します。 - concurrentWrites: 複数プロセスからの同時書き込みを安全に処理するモード。有効にすると排他制御が働きますが、わずかなオーバーヘッドが発生します。
- keepFileOpen: ファイルハンドルを常時オープン状態に維持します。頻繁なOpen/Closeを回避するため、高負荷環境では
true推奨です。 - openFileCacheSize: ファイルハンドルキャッシュのサイズ。動的ファイル生成(レベル別振り分けなど)を行う場合は、LRUアルゴリズムに基づいて管理されるため、適宜増やしてください(通常5〜15程度)。
- bufferSize / autoFlush: IOバッファサイズと自動フラッシュの制御。パフォーマンスとデータ喪失リスクのトレードオフになります。
実践的な設定パターン
パターン1: 簡易設定(単一ファイル出力)
基本となる構成です。アプリ実行ディレクトリ配下の指定フォルダにテキストを保存します。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="basicFile" xsi:type="File"
fileName="${basedir}/output/system.log"
layout="${date:format=yyyy-MM-dd HH:mm:ss} [${level}] ${message}"
encoding="utf-8" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="basicFile" />
</rules>
</nlog>
パターン2: ログレベルによるファイル分割
${level}レンダラーを活用し、各重要度ごとに独立したファイルを作成します。
<targets>
<target name="levelSplit" xsi:type="File"
fileName="${basedir}/logs/${level}.txt"
layout="${longdate} | ${callsite:methodName=true} | ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="levelSplit" />
</rules>
パターン3: 日次ベースの出力設定
日付ベースのファイル名で自動更新されます。旧ファイルは上書きされず、新しい日付のファイルが作成されます。
<targets>
<target name="dailyLog" xsi:type="File"
fileName="${basedir}/archive/daily_${date:format=yyyyMMdd}.log"
layout="${time} | ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="dailyLog" />
</rules>
パターン4: 非同期書き込み(AsyncWrapper)
主要スレッドのブロッキングを防ぐため、別スレッドでキューイングして出力します。高トラフィックのWebサーバーやバックグラウンドサービスに適しています。
<targets>
<target name="asyncDisk" xsi:type="AsyncWrapper"
queueLimit="10000"
overflowAction="Discard"
timeToSleepBetweenBatches="50">
<target xsi:type="File"
fileName="${basedir}/perf/trace.log"
layout="${longdate} ${logger} ${message}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="asyncDisk" />
</rules>
パターン5: CSV形式での構造化出力
CsvLayoutを使用し、表計算ソフトやデータ分析ツールで読み込みやすい形式にします。
<targets>
<target name="csvExport" xsi:type="File" fileName="${basedir}/data/report.csv">
<layout xsi:type="CsvLayout">
<column name="timestamp" layout="${longdate}" />
<column name="source" layout="${logger}" />
<column name="severity" layout="${level}" />
<column name="payload" layout="${message}" />
</layout>
</target>
</targets>
<rules>
<logger name="*" minlevel="Warn" writeTo="csvExport" />
</rules>
パターン6: サイズ基準でのアーカイブ管理
ファイルサイズが閾値に達すると、指定ディレクトリへ移動し連番を振ります。古いファイルは設定数を超えると削除されます。
<targets>
<target name="sizeArchive" xsi:type="File"
fileName="${basedir}/current/main.log"
archiveFileName="${basedir}/backup/main_{####}.log"
archiveAboveSize="5242880"
archiveNumbering="Sequence"
maxArchiveFiles="20"
keepFileOpen="true" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="sizeArchive" />
</rules>
パターン7: 日次アーカイブと保存期間制限
日付変更時にログを移動し、指定件数(例:14日分)だけ保持します。Rollingモードを採用しているため、最新のファイルが常に0番として参照されます。
<targets>
<target name="timeArchive" xsi:type="File"
fileName="${basedir}/active/app.log"
archiveFileName="${basedir}/history/app_{####}.log"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="14"
concurrentWrites="true" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="timeArchive" />
</rules>