EntLib 6 Logging Rolling Flat File Listener creates a separate file per new log

Topics: Logging Application Block
Sep 30, 2014 at 4:59 AM
I'm using EntLib 6 logging Rolling Flat File and it creates a separate file with a single row of log data whenever I log in my app. I'll appreciate if anyone can help me.

My configuration is as below:

<add name="Broadcast Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
fileName="Log/Broadcast/Broadcast.log" footer="" formatter="Broadcast Text Formatter"
header="" rollFileExistsBehavior="Increment" rollInterval="Day"
rollSizeKB="10240" maxArchivedFiles="10" timeStampPattern="yyyyMMdd" />

<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Message: {message}" name="Broadcast Text Formatter" />

The class where I use to log is as below (C#):
private LogWriter _logWriter;

public Logger()
{
try
{
    IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
    LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);

    _logWriter = logWriterFactory.Create();
}
catch (Exception ex)
{
    Debug.WriteLine(ex.ToString());
}
}

public void Log(Exception exception)
{
ExceptionTypes type = 
    (exception.GetType() == typeof(BroadcastException)) ? ((BroadcastException)exception).Type : ExceptionTypes.API;

try
{
    StringBuilder sb = new StringBuilder();

    sb.AppendLine(Environment.NewLine + "Logging Time: " + DateTime.Now.ToString());

    if (exception != null)
    {
        sb.AppendLine("MES Source: " + type.ToString());
        sb.AppendLine("Exception type " + exception.GetType().ToString());
        sb.AppendLine("Exception Message: " + GetExceptionMessage(exception));
        sb.AppendLine("Exception Source:\n" + GetExceptionSource(exception));
    }

    LogEntry log = new LogEntry();
    log.Message = sb.ToString();
    log.Categories.Clear();
    log.Categories.Add(type.ToString());

    _logWriter.Write(log);
}
catch (Exception ex)
{
    Debug.WriteLine(ex.ToString());
}
}
Oct 2, 2014 at 4:37 PM
I assume that you are instantiating a new Logger class every time you want to log an exception. The issue is that the logger class creates a new LogWriter without disposing of the existing LogWriter. In that scenario, the lock on the log file is not released and the new LogWriter attempts to open the log file and fails (due to the existing lock) and, as a fallback, a file with a GUID prepended is created.

One solution would be to dispose of the LogWriter before creating a new LogWriter and release the locks. However, in this case I don't think you need a new LogWriter. A better solution is to create the LogWriter as a singleton and use that in the Logger class:
public class Logger
{
    private static Lazy<LogWriter> _logWriter = new Lazy<LogWriter>(() =>
        {
            try
            {
                IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
                LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);

                return logWriterFactory.Create();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }

            // return null or perhaps default LogWriter implementation (e.g. using programmatic config)
            return null;
        });

    public void Log(Exception exception)
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendLine(Environment.NewLine + "Logging Time: " + DateTime.Now.ToString());

        if (exception != null)
        {
            sb.AppendLine("Exception type " + exception.GetType().ToString());
            sb.AppendLine("Exception Message: " + exception.Message);
            sb.AppendLine("Exception Source:\n" + exception.Source);
        }

        LogEntry log = new LogEntry();
        log.Message = sb.ToString();
        // Don't need to clear Categories with new LogEntry
        // log.Categories.Clear();
        log.Categories.Add("General");

        _logWriter.Value.Write(log);
    }
}

Or you could make the entire Logger class a singleton itself.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
```
Marked as answer by disorian on 10/2/2014 at 7:41 PM
Oct 3, 2014 at 3:53 AM
Thanks Randy for your help. This solved my problem and my logger is working fine now.
The problem was, as you have mentioned, a new instance is instantiated very time.