Reputation: 1240
I have a C# solution containing multiple C# projects. I am planning to add logging in it. This logging should be available in all the projects and preferably use log4Net with rolling file logs.
With the above said premise, I could think of two ways to do that.
Initialize logger in entry point (Program class) of the solution & Get the logger instance & use it as a member variable for every class that needs logging.
Add another project, Utilities & define a Logging class with static logging methods. This class should be initialized in entry point (Program class) of the solution.
What could be the best possible solution?
Upvotes: 8
Views: 2631
Reputation: 967
I have a similar situation. What we've done is use 1 app config for all the projects and use links to reference it.
In the app.config for your app you set the log4net config Section
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
And later set the Appender:
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
...
And in each class you want to log you put a line similar to this:
private static readonly ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
Then each class grabs the same logger (singleton). Would that work for you?
Upvotes: 7
Reputation: 17028
Option 1 is the way to go.
If you use static methods you loose the ability to use hierarchical loggers. This feature allows you to configure your log output differently for individual classes or even for entire sub systems e.g. YourNameSpace.Security
. This tutorial elaborates on this topic (also the other chapters are a good read).
Building a wrapper is certainly not a bad idea, but it is not strictly necessary. It does allow for a few things though: change log framework, use DI, add additional log levels (e.g. log.Verbose()) or different overloads for logging...
Btw. I would initialize the loggers like this:
ILog log = LogManager.GetLogger(typeof(YourClass));
Upvotes: 0
Reputation: 3432
Building off of Queso's answer, we had .dll's that were imported with reflection at runtime. In order to get them to use Log4Net we created a log4net.config file with all the appropriate config sections. We also used the same line of code to intialize the log in each class that Queso references. The seperate config allowed us to use it throughout the entire app domain.
EDIT we also had to make a modifcation to the appsettings file to allow for this.
http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx
Upvotes: 0
Reputation: 23157
If you're thinking about initializing something at the entry point every single time, then you're writing yourself a case for dependency injection. Using a DI library (like Unity, Castle, or whatever flavor you personally like), you could do either constructor injection or property injection to get your logger class (or Log4Net) initialized automatically.
Additionally, you can use the DI kernel to make it a singleton, so that you only have one instance of it active.
Upvotes: 0
Reputation: 40756
In my projects, I wrote a wrapper around LOG4NET to (theoretically) exchange it with other logging frameworks like NLOG without breaking my code.
My own logging class is accessible through a static singleton. It does initialization in this singleton.
(BTW: I published the source code over at the Code Project some time ago, maybe it gives you some inspiration)
Upvotes: 0