Clog question

Feb 17, 2011 at 1:58 PM

I have a question about Clog.  In the Log4NetStrategy.cs file (as well as in the equivalent files for NLog and Enterprise Library) the incoming IServerLogEntry or IClientLogEntry is converted to a log4net LoggingEvent and logged using log4net's Log method.  After converting the I*LogEntry to a LoggingEvent, this function is used to ensure that the actually log4net logging call is threadsafe:

/// <summary> 
/// All Write log calls are done asynchronously because the DanielVaughan.Logging.Log 
/// uses the AppPool to dispatch calls to this method. Therefore we need to ensure 
/// that the call to Log is threadsafe. That is, if an appender such as FileAppender is used, 
/// then we need to ensure it is called from no more than one thread at a time. 
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="loggingEvent">The logging event.</param>
[MethodImpl(MethodImplOptions.Synchronized)]
static void WriteThreadSafe(ILogger logger, LoggingEvent loggingEvent)
{
  logger.Log(loggingEvent);
}

I am curious as to whether this forced synchronization is actually necessary, particularly for log4net and NLog.  Both of these frameworks explicitly advertise that they are threadsafe.  My understanding is that, while an appender like FileAppender might not be threadsafe, the framework itself ensures that it is accessed in a threadsafe manner.  It seems like if the code snippet above is really necessary, then anyone using log4net or NLog would have to write "normal" logging code (i.e. code that is using log4net or NLog directly) something like this:

int Add(int x, int y)
{
  //Ensure that only one thread logs at a time
  lock(globalLogLocker)
  {
    logger.InfoFormat("x, y = {0}, {1}", x, y);
  }
  
  int sum = x + y;

  //Ensure that only one thread logs at a time
lock(globalLogLocker) { logger.InfoFormat("sum = {0}", sum); } return sum; }

Maybe there is something about the MethodImpl.Synchronized attribute that is applied to WriteThreadSafe that I don't understand or maybe there is something about the environment in which Clog is running (the comment about using AppPool dispatch) that I don't understand.

I am asking because I have been working on a somewhat similar WCF logging service for in-house use on our project.  Our client will log logging messages via a logging DTO to our logging service, which will then convert the logging DTO to the appropriate logging structure/class and log it using a logging framework (NLog or log4net).  I came across Clog while working on my project then came across this WriteThreadSafe function.  I had not occurred to me to do something like (force all logging calls to be synchronized), and I just wondered if I was missing something.

Thanks for any info you can share about his.

Coordinator
Feb 17, 2011 at 3:35 PM
Edited Feb 17, 2011 at 3:36 PM

Firstly, I should be using a object lock, not MethodImpl which locks on the type.

I seem to recall having an issue with Log4Net and ASP.NET, about 18 months ago, in which the synchronization appeared to solve it. I will reassess that, as the Log4Net seems pretty clear on the matter.

Thanks for your message.

Cheers,

Daniel

Coordinator
Feb 17, 2011 at 3:37 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Feb 17, 2011 at 3:40 PM

Thanks for the quick response!