あなたは属性を使ってこれを行う方法を尋ねています。 @ジョナサンの提案はおそらくうまくいくようですが、log4netの組み込み機能を使って十分な結果を得ることができるかもしれません。
クラスを「カテゴリ」にグループ化する場合は、クラス名ではなくカテゴリ名に基づいてロガーを取得できます。出力形式を設定するときは、ロガーフォーマットトークンを使用してlog4netに出力にロガー名を書き込ませることができます。
典型的には、1つのこのようなクラス名に基づいてロガーを取得するであろう:
public class Typical
{
private static readonly ILog logger =
LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void F()
{
logger.Info("this message will be tagged with the classname");
}
}
なお、このような任意の名前に基づいてロガーを取得するために、完全に許容可能である。前述の例で
public class A
{
private static readonly ILog logger = LogManager.GetLogger("REF");
public void F()
{
logger.Info("this message will be tagged with REF");
}
}
public class B
{
private static readonly ILog logger = LogManager.GetLogger("REF");
public void F()
{
logger.Info("this message will be tagged with REF");
}
}
public class C
{
private static readonly ILog logger = LogManager.GetLogger("UMP");
public void F()
{
logger.Info("this message will be tagged with UMP");
}
}
クラスAとクラスBは同じ「カテゴリ」にあるとみなされるため、同じ名前のロガーを取得します。クラスCは異なるカテゴリにあるため、別の名前のロガーを取得しました。
あなたがあなた自身の「カテゴリ」階層で(設定ファイルで)あなたのロガーを設定できます。
App
App.DataAccess
App.DataAccess.Create
App.DataAccess.Read
App.DataAccess.Update
App.DataAccess.Delete
App.UI
App.UI.Login
App.UI.Query
App.UI.Options
また、完全修飾ロガー名の一部だけをログに記録するロガーの出力形式を設定することができます。このようなもの:
%logger:2
完全修飾名の最後の2つの部分を取得します。あなたのクラスの完全修飾名がある場合たとえば、:
NameSpaceA.NameSpaceB.NameSpaceC.Class
その後、上記の形式で出力これは、ロガー名としてです:
NameSpaceC.Class
ため、私は私の避難所」構文約100%を確認していませんそれを使用して、私は今すぐ良い例を見つけることができません。
このアプローチの欠点の1つは、カテゴリが何であるかを定義して覚えておかなければならず、各クラスに適切なカテゴリが何であるかを決定する必要があるということです(各クラスをそのカテゴリ)。また、同じカテゴリに複数のクラスがある場合、ログのオン/オフや、それらのクラスのサブセットのロギングレベルの変更はできません。
多分名前空間の階層内から単一の名前空間をログに記録することは有用であろう:
たぶん、あなたは自分の名前空間に基づいてクラスを「分類」することができます。したがって、クラスの直近の親ネームスペースをカテゴリとしてログに記録することができます。
したがって、上記の完全修飾クラス名の場合、「カテゴリ」またはロガー名として「NameSpaceC」を記録することができます。
あなたはlog4netでこれを実行できるかどうかはわかりませんが、Logger名を取得してクラス名と「上位レベル」の名前空間を取り除くために、PatternLayoutConverterを簡単に記述できます。
ここに、カスタムPatternLayoutConverterの例へのリンクがあります。私の場合、辞書の値を参照するために使用したいパラメータをとります。この場合、パラメータは完全修飾ロガー名のENDからのオフセットを表すことができます(log4netの組み込みロガー名レイアウトオブジェクトへのパラメータと同じ解釈)。しかし、追加のコードを追加して、インデックス。この完全修飾クラス名を与えられ再び
Custom log4net property PatternLayoutConverter (with index)
は、:
NameSpaceA.NameSpaceB.NameSpaceC.Class
あなたは直接の親の名前空間は、 "カテゴリ" であることを考えるかもしれません。カスタムPatternLayoutConverter、category
を定義し、それがパラメータを取った場合は、ご使用の構成は次のようになります。デフォルトでは
%category
をそれが'.'
文字を最後に、最後と次の間の部分文字列を返します。パラメータを指定すると、チェーン上の任意の離散名前空間を返すことができます。
class CategoryLookupPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Assumes logger name is fully qualified classname. Need smarter code to handle
//arbitrary logger names.
string [] names = loggingEvent.LoggerName.Split('.');
string cat;
if (Option > 0 && Option < names.Length)
{
cat = names[names.Length - Option];
}
else
{
string cat = names[names.Length - 1];
}
writer.Write(setting);
}
}
アイデア:(エンドに対して)N番目の名前空間名を取得するにはオプションのプロパティを使用して、
class CategoryLookupPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Assumes logger name is fully qualified classname. Need smarter code to handle
//arbitrary logger names.
string [] names = loggingEvent.LoggerName.Split('.');
string cat = names[names.Length - 1];
writer.Write(setting);
}
}
または:
PatternLayoutConverterは(未テスト)のようになります@Jonathanはとてもクールですが、新しいロガーラッパーを定義して維持するために、あなたのコーディングを追加します(しかし、多くの人がそれを行い、特に厄介な負担ではありません)。もちろん、私のカスタムPatternLayoutConverterのアイデアも、あなたのカスタムコードを必要とします。
もう1つの欠点は、GetCategoryがすべてのロギングコールで非常に高価になる可能性があることです。
このような機能のロガー階層を使用したlog4net –
実際に表示されるカテゴリは何ですか?つまり、同じカテゴリにログを記録するオブジェクトはどのように関係しますか?理論的には、それぞれのカテゴリに対応するロガーとアペンダ間の関連付けを通じてconfig内でこれをすべて行うことができます。例えば、名前空間X、Y、ZのオブジェクトからのすべてのロギングはカテゴリAを表すアペンダを使用します。負担になるかもしれない質問。 –
私がここで達成しようとしているのは、特定のクラスに対してログファイルを解析しやすくすることです。たとえば、クラスAとクラスBが関連していて、クラスAとBに関連するすべての行をメインログファイルから取得したいと思うでしょう。私の経験は、通常この方法で見つかったので、私にとって非常に役に立ちました。 – tonyjy