get use single instance for all Logger implementations

Topics: Logging Application Block
Oct 30, 2012 at 2:14 PM

Currently i have created wrappers over EntLib Logger component.

 

  public Logger(string configurationFilepath)
        {
            try
            {
                // Instance of the Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource
                FileConfigurationSource configSource;

                // Instance of the Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter
                LogWriterFactory logWriterFactory;

                configSource = new FileConfigurationSource(configurationFilepath);
                logWriterFactory = new LogWriterFactory(configSource);
                this.logWriter = logWriterFactory.Create();
            }
            catch (Exception ex)
            {
                LoggerException.Handle(ex.ToString(), string.Empty);
            }
        }

 

 

Now i have 2 different instance of logger. logger1 and logger2

LogWriterFactory for logger1 will create instance of LogWriter.

LogWriterFactory for logger2 will create instance of LogWriter.

I am okay if i have 2 different log files to write.

but i want to write log in single file then, what should be my instance creation code?  

                this.logWriter = logWriterFactory.Create();

 

Oct 30, 2012 at 10:21 PM

It sounds like you could use a singleton or maintain a single LogWriter instance internally within the Logger class.  LogWriter is thread-safe so one instance can be shared by many threads.  The only issue that I see is that the Logger class accepts a fileName so that leads me to think that in a general purpose scenario the different configurations could be used that point to the same file.  This would cause file locking issues (with a GUID in the resultant file name).

If you really do need to support multiple LogWriters (from multiple configurations) then you could use something like the following:

    public class Logger
    {
        private static ConcurrentDictionary<string, LogWriter> logWriters = new ConcurrentDictionary<string, LogWriter>();

        public LogWriter logWriter;

        public Logger(string configurationFilepath)
        {
            try
            {
                string fullPath = Path.GetFullPath(configurationFilepath);
                logWriter = logWriters.GetOrAdd(fullPath,
                    (path) =>
                    {
                        
                        // Instance of the Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource
                        FileConfigurationSource configSource;

                        // Instance of the Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter
                        LogWriterFactory logWriterFactory;

                        configSource = new FileConfigurationSource(path);
                        logWriterFactory = new LogWriterFactory(configSource);
                        return logWriterFactory.Create();
                    });
            }
            catch (Exception ex)
            {
                LoggerException.Handle(ex.ToString(), string.Empty);
            }
        }

This example uses a ConcurrentDictionary for thread-safety to maintain a single LogWriter per configuration file.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com