ユーティリティクラスでヘルパーメソッドを取得して、log4netで呼び出し元ロガーを使用するにはどうすればよいですか?
質問
提供されているコマンドラインスイッチに応じて、次のような実行可能ファイルがあります。
Program.cs-
namespace DiskSpaceReporting
{
class Program
{
static void Main(string[] args)
{
if(args.Length == 1)
{
switch(args[0])
{
case "-summarytotals":
SummaryDiskSpaceReporter.Run();
break;
case "-detailed":
DetailedDiskSpaceReporter.Run();
break;
//...other reporting types
}
}
}
}
}
SummaryDiskSpaceReporter.cs
namespace DiskSpaceReporting
{
public class SummaryDiskSpaceReporter
{
private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void Run()
{
log.Info(1234, "Starting");
//...do work
string message = Helpers.CreateMessage(messageID);
//...do work
}
}
}
DetailedDiskSpaceReporter.cs
namespace DiskSpaceReporting
{
public class DetailedDiskSpaceReporter
{
private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void Run()
{
log.Info(1234, "Starting");
//...do work
string message = Helpers.CreateMessage(messageID);
//...do work
}
}
}
Helpers.cs
namespace DiskSpaceReporting
{
public class Helpers
{
private static IEventIDLog log = ???
public static string CreateMessage(Guid messageID)
{
log.Info(9876, "Starting");
//...do work
}
}
}
log4net構成には、ロギング要件が異なるため、SummaryDiskSpaceReporterとDetailedDiskSpaceReporterのそれぞれに1つずつ、2つの個別のロガーがあります。
<root>
<level value="ALL" />
<appender-ref ref="ConsoleLogAppender" />
<appender-ref ref="EventLogAppender" />
</root>
<logger name="DiskSpaceReporting.SummaryDiskSpaceReporter">
<appender-ref ref="SummaryDiskSpaceReporterRollingFileAppender"/>
</logger>
<logger name="DiskSpaceReporting.DetailedDiskSpaceReporter">
<appender-ref ref="DetailedDiskSpaceReporterRollingFileAppender"/>
</logger>
SummaryDiskSpaceReporterとDetailedDiskSpaceReporterの両方が、Helpersというクラスのヘルパーメソッドを呼び出します。ヘルパークラスメソッドにログを記録したい。
だから...質問は、Helpers.CreateMessage()メソッドを取得して、その呼び出し元と同じロガーを使用するにはどうすればよいですか?
i.e。
SummaryDiskSpaceReporter.Run()-&gt;つかいます DiskSpaceReporting.SummaryDiskSpaceReporter ロガーDetailedDiskSpaceReporter.Run() -&gt; DiskSpaceReporting.DetailedDiskSpaceReporterを使用します ロガー。
乾杯 ケブ
解決
私はかなり長い間この質問に取り組んできましたが、残念ながらしばらくあきらめて「本物」に戻る必要があります。作業。今のところ、私が思いついたのは次のとおりです。
オプション1:ロガーを渡す
これは素晴らしいオプションではありませんが、ヘルパーをロガーに結合することを気にしないのであればうまく動作するはずです。 CreateMessageメソッドがIEventIDLogを取得できるようにします。その後、これを使用して、ロガーに渡された正しいログに記録できます。
public static string CreateMessage(Guid messageID, IEventIDLog log)
{
log.Info(9876, "Starting");
//...do work
}
正確には光沢がありませんが、機能するはずです!
オプション2:コールスタックを使用する
呼び出しスタックを使用して呼び出しコードを見つけ、これからタイプを見つけ、そのタイプから必要なロガーを取得します
public static string CreateMessage(Guid messageID)
{
StackFrame frame = new StackTrace().GetFrame(1);
IEventIDLog log = EventIDLogManager.GetLogger(frame.GetMethod().DeclaringType);
log.Info(9876, "Starting");
//...do work
}
まだコールスタックに触れる必要があるため、光沢はありません。呼び出しコードにロガーがない場合はどうなります。
オプション3: log4netを使用する
これは私たちが使用したいオプションです、それは質問が答えとして欲しいものです、しかしまだまだ 解決していません。 :) log4netを見ると、ルートロガーを取得できるHierarchyクラスのようなクールなものが見つかりました。
Logger logger1 = ((log4net.Repository.Hierarchy.Hierarchy) log4net.LogManager.GetRepository()).Root;
つまり、ロガーをCreateMessageメソッドから1レベル上げる方法があり、それを見つける方法があると確信しています。 :)