web-dev-qa-db-ja.com

LogManager.GetLoggerへのlog4net引数

ほとんどのlog4netの例では、次のようにしてクラスのロガーを取得するのはなぜですか。

private static ILog logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Typeof(MyClass)を単に渡すのではなく:

private static ILog logger = LogManager.GetLogger(typeof(MyClass));

最初のオプションでは特定のクラス名を入力する必要がないという事実に加えて、これを行う他の理由はありますか?

98
Andy White

理由があると思います。そのようにするので、クラス名を気にする必要がなく、ボイラープレートコードを新しいクラスにコピーアンドペーストするだけです。

公式の回答については、「静的ブロック内のクラスの完全修飾名を取得するにはどうすればよいですか?」を参照してください。 log4net faq

92
Steven Lyons

あなたが言うように-クラスの名前を知らなくてもメソッドにロガーを作成できるので便利です(私は知っています)が、呼び出しの名前を変更せずにクラス間でメソッドをカットアンドペーストできます。

7
Preet Sangha

私はNLogユーザーです。通常、これは次のように要約されます。

var _logger = LogManager.GetCurrentClassLogger();

Log4Netでリフレクションを実行する必要があるのは少し奇妙に思えたので、NLogのソースコードを確認しました。

[MethodImpl(MethodImplOptions.NoInlining)]
public static Logger GetCurrentClassLogger()
{
    string loggerName;
    Type declaringType;
    int framesToSkip = 1;
    do
    {
#if SILVERLIGHT
        StackFrame frame = new StackTrace().GetFrame(framesToSkip);
#else
        StackFrame frame = new StackFrame(framesToSkip, false);
#endif
        var method = frame.GetMethod();
        declaringType = method.DeclaringType;
        if (declaringType == null)
        {
            loggerName = method.Name;
            break;
        }
        framesToSkip++;
        loggerName = declaringType.FullName;
    } while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
    return globalFactory.GetLogger(loggerName);
}

私はボイラーコードの一部としてリフレクションを貼り付けるのではなく、拡張または静的メソッドとしてLog4Netに似たものを書くと思います:)

7
Noctis

その理由は、.DeclaringType()メソッドを使用してランタイム型の型を取得するからだと思います。基本クラスでロガーを使用しても、ロガー出力でオブジェクトの実際のタイプを確認できます。これにより、調査がはるかに便利になります。

3
PeterB