Tag Archives: ADONetAppender

Return to Log4Net Hell

Do you know what my favorite quote from the log4net faq website is?

Is log4net a reliable logging system?

No. log4net is not reliable.

Ah yes, welcome back to hell!  I remember growing up watching one of the “Road Films”, with Bing Crosby and Bob Hope, where they were dealing with a Voodoo Witch Doctor.  Fast forward to today and it’s like the authors of the Log4Net logging framework took inspiration from the movie. I wouldn’t be surprised if there is a special dance you have to do, or sacrifice to some 486 in an office somewhere to get this thing working correctly.

So I come into the office this morning to “logging’s not working and we’re configuring it correctly”… I figured about half of that statement was true, and went to verify that loggng still worked on my local machine, and I would verify it was working on the staging environment.  After all, everything was working well on Friday.  Right??  Did the temperature suddenly get very hot?  After bit of cussing, I found this gem:

When should I log my first message?

The simple answer is as soon as possible. The long answer is more complex.

If you are configuring log4net programmatically, i.e. by calling the XmlConfigurator.Configure method then you should do so before you begin logging and it is reasonable to do this very soon after application start.

If you are configuring log4net by specifying assembly level attributes on your assembly then the configuration will be loaded once the first call to theLogManager.GetLogger is made. It is necessary that the first call to LogManager.GetLogger made during the process (or AppDomain) is made from the assembly that has the configuration attributes. Log4net will look only once and only on the first calling assembly for the configuration attributes.

Well that just makes perfect sense, right?  Whatever assembly happens to log first, that’s the configuration everyone is going to use.  I’m not going to bother asking why the guys felt that including configuration via assembly attribute was necessary, or even desired if this is the behavior.  So remember this little slice of code?

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

Yeah that was fairly worthless.

So what I had to do, was create a global.asax which would make the appropriate calls for log4net to be configured correctly on the startup of my application:

protected static readonly log4net.ILog log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    void Application_Start(object sender, EventArgs e)
    {
        String currentWebRootFilePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
        String api4netConfigPath = System.IO.Path.Combine(currentWebRootFilePath, "log4net.config");
        log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(api4netConfigPath));
        log.Info("Starting " + System.Reflection.Assembly.GetExecutingAssembly().FullName);
    }

    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown
        log.Info("Stopping " + System.Reflection.Assembly.GetExecutingAssembly().FullName);
    }

After testing and verifying it worked… again, I checked it in.  I’m fully expecting to write a third post in this series, so stay tuned.

Parsnips

Log4Net Hell

Like Dante, I’ve seen hell. Hell takes many forms depending on the sin. My sin was not knowing how to configure the ADONetAppender in log4net. The “Good News” I bring to you is how to avoid going to Log4Net hell.

First of all, if you’re having trouble with log4net, stop whatever you were doing. Go outside and take a few deep breaths. Come back to computer, and in your Web.config (or App.config) put the following lines in the configuration node:


	
    

    


		
	    
	
    

*Note* You’ll want to remove these Web.config/App.config lines when your code is running in production *Note*

The next thing is to make sure the Assembly you’re interested in logging from, knows where to find the config file… Put this in the AssemblyInfo.cs file, for the assembly:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

Ok, now everything should work, right? WRONG! You’re in Hell, remember? Your log4net.config file, should be placed in the path that is being executed. Ok, what does that mean? I’ll give an example with a wcf file structure:

webapp
   someservice.svc
   log4net.config <——–log4net.config should live here
   web.config
   bin
      somedll.dll <——-Not in here

Now restart your application, and trigger a log event. You’ll see the file C:\temp\log4net.txt existing. Great. Open that file and look at it. It has all the information you need to stop pulling out your hair, banging on your desk, cussing, and any real sin you may be inclined to do.

Hopefully these simple steps keep you out of Log4Net hell.