开发者

Log4Net in App object?

开发者 https://www.devze.com 2022-12-25 04:11 出处:网络
I am getting started with Logging in a WPF desktop app, using Log4Net as the logging component. Here is my question: In a simple desktop app, is there any reason not to instantiate my logger as a prop

I am getting started with Logging in a WPF desktop app, using Log4Net as the logging component. Here is my question: In a simple desktop app, is there any reason not to instantiate my logger as a property ov the App class (App.xaml.cs), like this?

public partial class App : Application
{
        private static readonly ILog p_Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public ILog Logger
        {
            get { return p_Logger; }
        }

        #endregion
    }
}

That would allow开发者_StackOverflow me to invoke the logger


One reason springs to mind: since the App class's static constructor is the first bit of your code that will run, you will be instantiating the ILog instance before you've configured log4net. Therefore, you ILog instance won't be usable. Generally, you would instead do something like this:

public partial class App : Application
{
    private static ILog log;

    static App()
    {
        XmlConfigurator.Configure();
        log = LogManager.GetLogger(typeof(App));
    }
}

BTW, that MethodBase business really makes me cringe. Why not just use typeof(App)? You shouldn't be copy/pasting code without verifying it, anyway...and typeof(App) will work just fine with refactoring tools...


A couple of cases against using one global instance. By using one logger per class you get:

  • the benefit of logger hierarchies automatically following your class structure.
  • lesser coupling (your classes no longer have a dependency on the App class).


I did find a reason not to use a global logger in the App object. It works fine, but there is an advantage to getting a logger from within each class that will use it--It makes my log messages shorter and easier to write.

So I call GetLogger() in each class that will log, and I specify the name to be used for the logger. For example, in my OpenFile method, I can get a logger like this:

// Get logger
var logger = LogManager.GetLogger("OpenFile"); 

That relieves me of entering the class name in every error message I write. I still configure log4net in the App() constructor, since that only needs to be done once. That gives me a log message that looks like this:

2010-03-29 15:51:41,951 OpenFile [DEBUG]- Data file opened.

Kent's answer is still the accepted answer, but I figured I'd pass along what I had learned.

0

精彩评论

暂无评论...
验证码 换一张
取 消