How to Log a Single File from Multiple threads using enterprise library 5.0???

Topics: Logging Application Block
Mar 22, 2013 at 11:43 AM
Hi,

I am using enterprise library 5.0 for logging. while running the same application from multiple machines (or) executing with multiple threads, am getting multiple log file with GUID instead of single log file. please anyone suggest how we can achieve a single log file instead of multiple files.

thanks in advance

Regards
Tirumal Rao
Mar 22, 2013 at 2:14 PM
Log files are locked so you can only write to the same log file from within the same appdomain.

So, logging to one file from multiple machines is not going to work. Logging to a single file from multiple threads should be possible as long as each thread is using the same trace listener instance. Can you elaborate on how you are configuring the block and using the loggers in each thread?

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Jan 16, 2014 at 7:24 AM
I have the same issue.
I need to change code with using (). This helps a lot. However, there is still chance that GUID.AppName.log creating.
What should we apply on the config?

Currently the configuration I am using is,

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
  <add name="Logfile" 
       type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
       listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
       fileName="log\AppName.log"
       header="" footer="" 
       formatter="Text Formatter" 
       rollFileExistsBehavior="Increment" 
       rollInterval="Midnight" 
       timeStampPattern="yyyyMMddHHmmss" 
       maxArchivedFiles="30" />

</listeners>
<formatters>
  <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
       template="{timestamp(local:FixedFormatISOInternationalDate)} {timestamp(local:FixedFormatTime)} {category} {severity} - {message}" name="Text Formatter" />
</formatters>
<categorySources>
  <add switchValue="All" name="General">
    <listeners>
      <add name="Logfile" />
    </listeners>
  </add>
</categorySources>
<specialSources>
  <allEvents switchValue="All" name="All Events" />
  <notProcessed switchValue="All" name="Unprocessed Category" />
  <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
      <add name="Logfile" />
     </listeners>
  </errors>
</specialSources>
</loggingConfiguration>
Jan 17, 2014 at 6:06 AM
A GUID being prepended to the log file name is usually only a config issue if there are two trace listeners configured to write to the same file. Based on the posted config that doesn't seem to be the case so the issue is that the same log file is attempted to be written from two appdomain/processes or there is something else happening. You mention "using" which sounds like you are Disposing of a LogWriter which is not thread safe.

Can you provide a code sample which demonstrates the issue?

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 12, 2014 at 3:16 AM
Hi Randy Levy,

public static class Logger
{
public static void Write(string message, Severity severity = Severity.Information, string category = "General")
{
    using (LogWriter writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>())
    {
        LogEntry log = CreateLog(message, severity, category);
        writer.Write(log);
    }
}
}

And then in a method
...
var tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(()=>Monitor(id)));
...
private void Monitor(int alertDataId, int count)
{
....
Logger.Write(......)
....

}

Why having "using" is not thread safe?
Feb 12, 2014 at 3:42 AM
Edited Feb 12, 2014 at 3:43 AM
In short: while Logger.Write is thread-safe, Dispose is not thread-safe. This thread discusses that same scenario: http://entlib.codeplex.com/discussions/455188

You shouldn't need to Dispose of the LogWriter singleton. One reason to Dispose is if you perform programmatic reconfiguration and want to release file locks.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 12, 2014 at 4:10 AM
Before having the "using", it generate many GUID.App.log. The number of these log files reduce a lot after "using".
Feb 12, 2014 at 5:31 AM
GUID's are prepended if the file is attempted to be opened by more than one trace listener at the same time (due to locking). The LogWriter is a singleton so this should not usually happen. Scenarios where it could happen is if there is a misconfiguration (different trace listeners try to write to the same file), the configuration is valid but multiple application domains/processes share the same configuration and so are trying to lock the same file, or programmatic configuration (or re-configuration) is done but the file locks are not released.

If you supply a sample project it would be easier to say what is happening in your scenario.

EnterpriseLibraryContainer.Current.GetInstance<LogWriter>() should always return the same LogWriter instance for all threads and Logger.Write is thread-safe so it should just work out of the box.

I tried the posted sample code (without the using) and I didn't see any locking issues (although I did get an exception with the using because the internal LogWriter was Disposed while another thread was trying to write.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 12, 2014 at 7:12 AM
Edited Feb 12, 2014 at 7:12 AM
Well, there is only one application and one instance to run, and only one application to writelog to the log file. I don't know why it is gerenating GUID's log file before "Using".

I could not send you directly on the application as it is owned by my company, i will wrap it as a sample project and test it. If I could reproduce it, I will send it to you. Thanks.