これは、リクエストを独自のファイルに書き込む方法についての質問には答えませんが、log4netヘルプは特に単純なアプローチを推奨しています。ThreadContext.Propertiesオブジェクトおよびその他のプロパティを使用して、ログメッセージを装飾し、各要求からメッセージを区別できるようにします。
http://logging.apache.org/log4net/release/faq.html
「複数のクライアント要求の出力を異なるログファイルに送信できますか?」を参照してください。
クライアントIDをお持ちの場合は、次のようなことを行うことができます。
log4net.ThreadContext.Properties["ClientID"] = GetTheClientId();
パターンレイアウトでは、次のようなことができます。
<conversionPattern value="%date [%thread] %-5level %logger [%property{ClientID}] - %message%newline" />
%property{ClientID}
ThreadContextからClientIDをどこにプルしますか。
これにより、ログに記録された各メッセージに関連するClientIDのタグが付けられます。
log4netコンテキストオブジェクトの使用に関する優れたチュートリアルについては、次のリンクを参照してください。
http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx
log4netチュートリアル全体は、特にlog4netを使い始めたばかりの場合は、非常に優れています。
これがパート1です。
http://www.beefycode.com/post/Log4Net-Tutorial-pt-1-Getting-Started.aspx
そうは言っても、次のリンクで説明されているように、人々はしばしばGlobalContextオブジェクトを使用して出力ファイルに名前を付けます。
http://geekswithblogs.net/rgupta/archive/2009/03/03/dynamic-log-filenames-with-log4net.aspx
GlobalContextを介して出力ファイルに名前を付けるプロセスを見たときはいつでも、推奨される解決策は、log4netが実際に開始する前に必ずGlobalContext.Properties["whatever"]値を設定するように指示します。これにより、ThreadContextに動的に格納されている情報に基づいて個々のログファイルを作成することは、不可能ではないにしても難しいと思います。その情報は、log4netがすでに実行されるまでわからない可能性があるためです。
[アップデート]
これは、ここからSOにある別のリンクで、GlobalContextの値の出力ファイルに名前を付ける方法を示しています。ここでも、filenameの基になる値は、log4netを構成する前、およびロガーを取得する前に、GlobalContextに設定する必要があることに注意してください。
log4netアペンダー名でGlobalContextプロパティを使用するにはどうすればよいですか?
上で述べたように、そして私のコメントで、log4netがThreadContextの値またはスレッドIDによって指定された出力ファイル名で(同じFileAppender構成に対して)複数の出力ファイルを作成できるかどうかはわかりません財産。たぶん、log4netに精通している他の誰かがそれを検討することができます。
そうは言っても、NLogでこれを正確に行うことは可能です。これは、名前の一部がスレッドIDから派生したファイルターゲットを定義するNLog構成です(${threadid}
構成のfileName部分に注意してください)。
<targets>
<target name="file" xsi:type="File" layout="${longdate} | ${processid} | ${threadid} | ${logger} | ${level} | ${message}" fileName="${basedir}/log_${threadid}.txt" />
</targets>
次のコードで:
class Program
{
public static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
int totalThreads = 20;
TaskCreationOptions tco = TaskCreationOptions.None;
Task task = null;
logger.Info("Enter Main");
Task[] allTasks = new Task[totalThreads];
for (int i = 0; i < totalThreads; i++)
{
int ii = i;
task = Task.Factory.StartNew(() =>
{
logger.Info("Inside delegate. i = {0}", ii);
});
allTasks[i] = task;
}
logger.Info("Wait on tasks");
Task.WaitAll(allTasks);
logger.Info("Tasks finished");
logger.Info("Exit Main");
}
}
4つのログファイルを取得しました。各ログファイルの名前にはスレッドIDが含まれ、各ログファイルには単一のスレッドからのメッセージのみが含まれていました。
同様に、この構成では(注${mdc:item=id}
):
<targets>
<target name="file" xsi:type="File" layout="${longdate} | ${processid} | ${threadid} | ${logger} | ${level} | ${message}" fileName="${basedir}/log_${mdc:item=id}.txt" />
</targets>
そしてこのコード:
class Program
{
public static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
int totalThreads = 20;
TaskCreationOptions tco = TaskCreationOptions.None;
Task task = null;
logger.Info("Enter Main");
Task[] allTasks = new Task[totalThreads];
for (int i = 0; i < totalThreads; i++)
{
int ii = i;
task = Task.Factory.StartNew(() =>
{
MDC.Set("id",Thread.CurrentThread.ManagedThreadId.ToString());
logger.Info("Inside delegate. i = {0}", ii);
});
allTasks[i] = task;
}
logger.Info("Wait on tasks");
Task.WaitAll(allTasks);
logger.Info("Tasks finished");
logger.Info("Exit Main");
}
}
MDC(log4netのThreadContext.Propertiesオブジェクトに相当するNLog)に格納されている値に基づいて、複数の出力ファイルを取得できます。