web-dev-qa-db-ja.com

クラスごとに、または基本クラスでlog4netロガーを宣言する必要がありますか?

ロガーを宣言し、基本クラスでLogManager.GetLoggerを呼び出して、継承しているすべてのユーザーがロガーを使用できるようにする方がきれいなようです。ただし、 このブログ投稿 のようなlog4netサイトおよび他のブログでは、クラスごとに1つのロガーを宣言する方が良いと述べています:

この方法でロガーを使用して、オブジェクト全体のロギングの懸念を分離できます。そうすることを強くお勧めします。これにより、log4netの階層構成メカニズムを使用して、個々のロガーからのログ出力を抑制および送信できます。

これは、基本クラスに入れると、そのロガーがボトルネックになるという意味ですか?

もしそうなら、他の解決策はありますか、それともクラスごとにロガーを作成する必要がありますか?

22
dev.e.loper

この投稿は、具体的には、各派生クラスで異なるロガーを使用するように指示しているのではなく、一般的にクラスタイプごとに異なるロガーを使用するよう指示しています。派生クラスごとに新しいロガーインスタンスを使用できますが、使用する必要はありません。

これを見る1つの方法は、特に同じロガー名を使用してベースロガーを非表示にすると、2つのロガーを同時にインスタンス化するのが混乱する可能性があることです(ベースロガーはまだ存在するため)。基本クラスのメソッド(オーバーライドされていない)は引き続き基本の静的ロガーを参照し、オーバーライドされたメソッドは別のロガーを使用します。

また、この記事ではロガーを次のようにインスタンス化しています。

static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType );

少し簡単な方法は次のように使用することです。

static readonly ILog Log = LogManager.GetLogger(typeof(YourClass));

まず、readonlyとマークされています。これは、一度初期化すると、誤ってフィールドを変更することができないことを意味します。また、型を使用するとリフレクションと同じように機能しますが、少し高速になります(コンパイル時に解決されます)。また、名前を変更することを選択した場合、Visual Studioはクラス名を自動的に更新します(文字列のオーバーロードを使用した場合はそうではありません)。

24
Groo

一般的な方法は、基本クラスではなく、クラスごとに1つのロガーを使用することです。このようにして、クラスごとにロギングを有効/無効にできます。

Common Logging 2.0の使用を検討することもお勧めします http://netcommon.sourceforge.net/

現在使用されている.NETには、log4net、Enterprise Library Logging、NLogなど、さまざまなロギング実装があります。異なる実装を持つことの欠点は、それらが共通のインターフェースを共有しないため、ライブラリのユーザーに特定のロギング実装を課すことです。

Common.Loggingライブラリは、実行時に特定のロギング実装を選択できるようにするための単純な抽象化を導入しています。したがって、展開するまで、使用する特定のロギングライブラリの決定を延期することができます。アダプタは、特定のロギングシステムをCommon.Loggingに接続するために使用されます。

5

提供されたステートメントは、ボトルネックについて言及していません。基本クラスでロガーを宣言すると、派生クラスでのロギングに対する制御が制限されます。同じロガーを含む基本クラスから派生したクラスAとBがある場合、クラスAとBで実行されるすべてのロギングに対して同じロギング設定でスタックします。

log4netを使用すると、作成されたクラスまたは名前空間に基づいてロガーを設定できるため、ログに記録される内容を非常に厳密に制御できます。たとえば、クラスAログを情報レベルで、クラスBログをデバッグレベルで使用します。

ログインしたい各クラスに1行のコードを追加することは、それが提供する柔軟性にとって非常に小さな負担です。

1
roken

基本クラスで、型名をキーにした静的辞書を使用します。

private static readonly Dictionary<string, ILog> _loggers = new Dictionary<string, ILog>();

ロガーを返すためのメソッド(基本クラス上)を使用して:

    private ILog GetLogger(){
        var tn = this.GetType().FullName;
        if (!_loggers.ContainsKey(tn)) {
            _loggers.Add(tn,LogManager.GetLogger(this.GetType()));
        }
        return _loggers[tn];
    }

基本クラスにもロギングメソッドがあります。

    public void Log(string msg, params object[] args) {
        GetLogger().InfoFormat(msg, args);
    }

これにより、タイプごとにログを構成できるようになると思います(ただし、これは行いません)。GetLoggerメソッドを派生クラスに公開して、独自のログを実行できるようにすることができます。

0
Lee Willis