How to modify the file path for a rolling file trace listner programatically?

Topics: Logging Application Block
Sep 9, 2012 at 9:18 AM

I have the following config:

  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </configSections>

  <loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="Tracing" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add fileName="c:\log.log" timeStampPattern="yyyyMMdd-hhmm" rollFileExistsBehavior="Increment" rollInterval="Hour" formatter="Text Formatter" header="" footer="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" traceOutputOptions="LogicalOperationStack" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AppLog"/>
    </listeners>
    <formatters>
      <add template="{message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Text Formatter"/>
    </formatters>
    <categorySources>
      <add switchValue="All" name="AppLog">
        <listeners>
          <add name="AppLog"/>
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events"/>      
      <notProcessed switchValue="All" name="Unprocessed Category"/>
      <errors switchValue="Off" name="Logging Errors &amp; Warnings"/>
    </specialSources>
  </loggingConfiguration>
I want to modify the logging file name from c:\log.log to d:\log.log programatically. How can I do this?
Sep 11, 2012 at 1:48 AM

As per your other question you can use the fluent interface to set this information.

You can also use the fluent configuration on the fly as per this post.  Also, if you want to read in an existing configuration file and then modify settings you can do it "old school" (read in config, modify values and save the config) as in this question and answer.

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

Sep 11, 2012 at 10:49 PM

Since this is a recent thread and I've got the same problem, I'll hijack it ;)

Using the EL5 Fluent API, the new FileName is not taking affect.  What am I missing?

Code:

        private static void OverrideLogName()
        {
            var builder = new ConfigurationSourceBuilder();
            var configSource = ConfigurationSourceFactory.Create();
            var loggingSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;
            var traceListenerData = loggingSettings.TraceListeners.Get("Rolling Flat File Trace Listener");
            var flatFileTraceListenerData = traceListenerData as RollingFlatFileTraceListenerData;
            flatFileTraceListenerData.FileName = "testing123.log";
            builder.UpdateConfigurationWithReplace(configSource);

            EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
            writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
        }

application config:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <enterpriseLibrary.ConfigurationSource selectedSource="System Configuration Source"
    parentSource="File-based Configuration Source">
    <sources>
      <add name="System Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <add name="File-based Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        filePath="MYDOMAIN.Common.config" />
    </sources>
    <redirectSections>
      <add sourceName="File-based Configuration Source" name="loggingConfiguration" />
    </redirectSections>
  </enterpriseLibrary.ConfigurationSource>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <runtime>
    <!--Performance improvement-->
    <generatePublisherEvidence enabled="false"/>
  </runtime>  
</configuration>

Common dll config (MYDOMAIN.Common.config):

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General"
    revertImpersonation="false">
    <listeners>
      <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="Application.log" footer="" formatter="General Text Formatter"
        header="" rollFileExistsBehavior="Increment" rollInterval="Month"
        rollSizeKB="0" timeStampPattern="yyyy-MM-dd" maxArchivedFiles="12"
        traceOutputOptions="None" />
      <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="Errors.log" header="----------------------------------------------------"
        footer="++++++++++++++++++++++++++++++" formatter="General Text Formatter" />
      <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        databaseInstanceName="ITS-SQL-DEV1" writeLogStoredProcName="WriteLog"
        addCategoryStoredProcName="AddCategory" formatter="DB Text Formatter"
        traceOutputOptions="LogicalOperationStack" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="{timestamp(local:G)}|{category}|{priority}|{eventid}|{severity}|{title}|{message}|{dictionary({key} - {value}|)}"
        name="General Text Formatter" />
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="Extended Properties: {dictionary({key} - {value}{newline})}"
        name="DB Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
      <add switchValue="Warning" name="Exception">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
          <add name="Database Trace Listener" />
        </listeners>
      </add>
      <add switchValue="All" name="Debug">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
      <add switchValue="All" name="Error">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
          <add name="Database Trace Listener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="Off" name="All Events">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </notProcessed>
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Flat File Trace Listener" />
          <add name="Database Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <dataConfiguration defaultDatabase="ITS-SQL-DEV1" />
  <connectionStrings>
    <add name="ITS-SQL-DEV1" connectionString="data source=its-sql-dev1;initial catalog=Rx_LM;integrated security=sspi;"
      providerName="System.Data.SqlClient" />
    <add name="ITS-SQL-SPROD1" connectionString="data source=its-sql-sprod1;initial catalog=Rx_LM;integrated security=sspi;"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Sep 12, 2012 at 1:09 AM

Typically, you would use either the Fluent API or configuration based approach since the fluent interface will replace the entire section.  If you wish to modify a configuration file at runtime and dynamically change values there are 2 approaches that I can think of (and both are not particularly elegant).  

The first is to read in the configuration and use it to drive fluent configuration.  See Update Configurations Without Replace With Enterprise Library 5 Fluent Configuration API for this approach.  In the linked post the author is using Data Settings which are quite simple.  It will be a bit of effort to map all of the possible logging configuration options to fluent configuration.

The second approach is to read in the configuration, modify it, and then save the configuration.  See Modify loggingConfiguration Programmatic (enterprise library) for this approach.  This has the downside of requiring write permissions to the config file.

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

Sep 12, 2012 at 11:15 PM

Bummer, seems like a major shortcoming of the Fluent API.  No wonder the Internet uses the read/modify config file route instead. 

When the config file is modified, the Logging block automatically picks up those changes, correct?  Does it matter if I'm using a secondary ConfigurationSource?

Sep 13, 2012 at 7:13 AM
Edited Sep 13, 2012 at 8:43 AM

The intent of the Fluent Configuration API is to use code to configure your application in an easy to understand manner.  That's why it doesn't really integrate with file based configuration.

But let's not get too bummed out yet.  What if we could read the configuration in and then instead of saving it to the configuration file we could load that configuration into memory?  Would that be interesting?

But first, let's look at your questions: yes, the changes should be picked up.  With a secondary ConfigurationSource we would have to change the approach a bit.

Here is some sample code that:

  1. Gets the default configuration source (which contains the full Enterprise Library configuration)
  2. Extracts the LoggingSettings
  3. Changes all RollingFlatFileTraceListener fileName's to end with ".new"
  4. Writes the configuration back to disk
IConfigurationSource configSource = ConfigurationSourceFactory.Create();
var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

var rollingListeners = logSettings.TraceListeners
    .Where(t => t is RollingFlatFileTraceListenerData)
    .Cast<RollingFlatFileTraceListenerData>()
    .Select(oldData =>
        new RollingFlatFileTraceListenerData(oldData.Name, oldData.FileName + ".new", oldData.Header, oldData.Footer, oldData.RollSizeKB, oldData.TimeStampPattern, oldData.RollFileExistsBehavior, oldData.RollInterval, oldData.TraceOutputOptions, oldData.Formatter, oldData.Filter));

rollingListeners.Cast<TraceListenerData>().ToList()
    .ForEach(data => 
        {
            logSettings.TraceListeners.Remove(data.Name);
            logSettings.TraceListeners.Add(data);
        });

configSource.Add(LoggingSettings.SectionName, logSettings);       

But that is not too elegant since we need write access to disk and we actually changed the configuration for all future runs of the application.  So now, let's try to modify the configuration in memory and write it back to the Enterprise Library container.

The approach here is the same as above except that instead of writing to disk I convert the ConfigurationSection to an IConfigurationSource.  I found two approaches: create a new class that extended LoggingSettings and accepts XML (to Deserialize) or to use reflection to access the protected DeserializeSection method.  I chose reflection in this case so it should work without having to create a class for every ConfigurationSection.  The last part is to add this configuration information to the Enterprise Library container.  To do that I use Unity directly.

Somehow I think I've made this more complicated that it could be so if anyone has a better idea, I would love to hear it.  The code looks like this:


    IConfigurationSource configSource = ConfigurationSourceFactory.Create();
    var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

    var rollingListeners = logSettings.TraceListeners
        .Where(t => t is RollingFlatFileTraceListenerData)
        .Cast<RollingFlatFileTraceListenerData>()
        .Select(oldData =>
            new RollingFlatFileTraceListenerData(oldData.Name, oldData.FileName + ".new", oldData.Header, oldData.Footer, oldData.RollSizeKB, oldData.TimeStampPattern, oldData.RollFileExistsBehavior, oldData.RollInterval, oldData.TraceOutputOptions, oldData.Formatter, oldData.Filter));

    rollingListeners.Cast<TraceListenerData>().ToList()
        .ForEach(data =>
        {
            logSettings.TraceListeners.Remove(data.Name);
            logSettings.TraceListeners.Add(data);
        });
        
    var loggingXmlConfigSource = new SerializableConfigurationSource();
    loggingXmlConfigSource.Add(LoggingSettings.SectionName, logSettings);

    // Create the container
    IUnityContainer container = new UnityContainer();
    container.AddNewExtension<EnterpriseLibraryCoreExtension>();

    // Configurator will read Enterprise Library configuration 
    // and set up the container
    UnityContainerConfigurator configurator = new UnityContainerConfigurator(container);

    // Configure the container with our own custom logging
    EnterpriseLibraryContainer.ConfigureContainer(configurator, loggingXmlConfigSource);

    // Wrap in ServiceLocator
    IServiceLocator locator = new UnityServiceLocator(container);

    // And set Enterprise Library to use it
    EnterpriseLibraryContainer.Current = locator;



    public class SerializableConfigurationSource : IConfigurationSource 
    {
        Dictionary<string, ConfigurationSection> sections = new Dictionary<string, ConfigurationSection>();

        public SerializableConfigurationSource()
        {
        }

        public ConfigurationSection GetSection(string sectionName)
        {
            ConfigurationSection configSection;

            if (sections.TryGetValue(sectionName, out configSection))
            {
                SerializableConfigurationSection section = configSection as SerializableConfigurationSection;
             
                if (section != null)
                {
                    using (StringWriter xml = new StringWriter())
                    using (XmlWriter xmlwriter = System.Xml.XmlWriter.Create(xml))
                    {
                        section.WriteXml(xmlwriter);
                        xmlwriter.Flush();

                        MethodInfo methodInfo = section.GetType().GetMethod("DeserializeSection", BindingFlags.NonPublic | BindingFlags.Instance);
                        methodInfo.Invoke(section, new object[] { XDocument.Parse(xml.ToString()).CreateReader() });

                        return configSection;
                    }
                }
            }

            return null;
        }

        public void Add(string sectionName, ConfigurationSection configurationSection)
        {
            sections[sectionName] = configurationSection;
        }

        public void AddSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
        {
            throw new NotImplementedException();
        }

        public void Remove(string sectionName)
        {
            sections.Remove(sectionName);
        }

        public void RemoveSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
        {
            throw new NotImplementedException();
        }

        public event EventHandler<ConfigurationSourceChangedEventArgs> SourceChanged;

        public void Dispose()
        {
        }
    }

If everything has worked properly, the file will log to a new location but you can still access all of the other configured Enterprise Library functionality.

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

Sep 13, 2012 at 11:10 PM

I'll opt for the .config updating method.  I tried the code provided and it works... with the exception that the new FileName is not utilized until the 2nd launch of the application.   Must be missing something to initiate the Logging picking up the new settings?

Sep 14, 2012 at 1:11 AM

A file watcher should be started up for the configuration file.  It could be a timing issue since it looks like the refresh interval is 15 seconds.  I'm assuming you are doing this at startup so you could try putting a sleep in there to see if the configuration gets reloaded.

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

Sep 14, 2012 at 7:29 PM

Solved the problem.  I had been instantiating the LogWriter in the logging class like:

 

namespace MYDOMAIN.Common
{
    public static class Log
    {
        static LogWriter writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();

        static Log()
        {
        OverrideELLogName();
	//do stuff

 

Once I removed the GetInstance<LogWriter> call, all logging immediately uses the updated FileName.  The last thing done in OverrideELLogName() is another EnterpriseLibraryContainer.Current.GetInstance<LogWriter() call.

Sep 14, 2012 at 7:45 PM

That makes total sense.  :)

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

Oct 25, 2012 at 2:45 PM

Hi Guys,


The answer here has been great however, I dont seem to be able to get it working.  I have it most of the way there, my problem is that the collection is readonly.  Everything seems to be readonly. I have tried overriding the entire collection of listeners.  I have tried creating a custom RollingFlatFileTraceListenerData and calling a SetFileName method and tried to set the property directly both with this["fileName"] and SetPropertyValue.  However everything seems to be readonly.

Have I got a different version or something... 

 

Or do you know a way to set the collection as not readonly?

 

Nigel.

Oct 26, 2012 at 3:35 AM

The collections are readonly so you can't assign a new collection to the property.  However, you can invoke methods on the collection to add or remove individual trace listeners.

e.g. not allowed: logSettings.TraceListeners = null; 

But you can add/remove: logSettings.TraceListeners.Remove("TraceListener1");

I also took the ideas in this thread and created a blog post

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

Nov 9, 2012 at 10:51 PM

I'm getting a read only exception even when I try to add a new listener.

 IConfigurationSource configSource = ConfigurationSourceFactory.Create();
            var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

            var rollingListeners = (from t in logSettings.TraceListeners
                                       .Where(t => t is RollingFlatFileTraceListenerData)
                                       .Cast<RollingFlatFileTraceListenerData>()
                                   select t).FirstOrDefault();

            RollingFlatFileTraceListenerData rollingListenerData = new RollingFlatFileTraceListenerData();
            rollingListenerData.FileName = @"C:\Temp\LoggingTest\DeclarativeTestLog.log";
            rollingListenerData.Formatter = "Timestamp: {timestamp} Message: {message} Severity: {severity} ";
            rollingListenerData.MaxArchivedFiles = 10;
            rollingListenerData.RollFileExistsBehavior = RollFileExistsBehavior.Increment;
            rollingListenerData.RollInterval = RollInterval.Hour;
            rollingListenerData.RollSizeKB = 10;
            rollingListenerData.TimeStampPattern = "yyyyMMddHHmm";

            var traceListenerData = rollingListenerData as TraceListenerData;
            logSettings.TraceListeners.Add(traceListenerData);

The error I'm getting is ConfigurationErrorsException with message "The configuration is read only."

Does anybody see what I'm doing wrong?

Nov 10, 2012 at 12:52 AM

If you are running in ASP.NET then the configuration will be set to be readOnly.  For some simple things you can use reflection to change the setting:

            var readonlyFieldInfo = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);

            readonlyFieldInfo.SetValue(logSettings.TraceListeners, false);

This is accessing private instance variables so this approach could break (e.g. variable rename) in future releases.  Also odds are that you could encounter other errors so it's not a very viable approach in general.

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

Nov 10, 2012 at 1:39 AM
Weird, I'm not using ASP.NET, it's just a ConsoleApp using .NET 4.0


From: [email removed]
To: [email removed]
Date: Fri, 9 Nov 2012 17:52:22 -0800
Subject: Re: How to modify the file path for a rolling file trace listner programatically? [entlib:394890]

From: randylevy
If you are running in ASP.NET then the configuration will be set to be readOnly. For some simple things you can use reflection to change the setting:

            var readonlyFieldInfo = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);

            readonlyFieldInfo.SetValue(logSettings.TraceListeners, false);


This is accessing private instance variables so this approach could break (e.g. variable rename) in future releases. Also odds are that you could encounter other errors so it's not a very viable approach in general.
--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com
Read the full discussion online.
To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)
To start a new discussion for this project, email entlib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Nov 11, 2012 at 5:31 AM

Can you post a sample project?

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

Nov 12, 2012 at 5:09 PM
Edited Nov 12, 2012 at 5:21 PM

Sure!  Thanks for looking into it! Here's a .zip file that should work.  it includes the enterprise library and unity dll's we're using.

Nov 15, 2012 at 3:36 AM

Thanks for the sample.  So looking at the project and going over the thread again I notice that the specific scenario being addressed has an *external* config file.  When acting on the actual config file you will receive the read only message but with an external config file it works so that needs to be a caveat.

Also, your sample app had a couple bugs that were causing exceptions.  The code should look something like:

            IConfigurationSource configSource = ConfigurationSourceFactory.Create();
            var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

            RollingFlatFileTraceListenerData rollingListenerData = new RollingFlatFileTraceListenerData();
            rollingListenerData.FileName = @"C:\Temp\LoggingTest\DeclarativeTestLog.log";
            rollingListenerData.Formatter = "Text Formatter";
            rollingListenerData.MaxArchivedFiles = 10;
            rollingListenerData.RollFileExistsBehavior = RollFileExistsBehavior.Increment;
            rollingListenerData.RollInterval = RollInterval.Hour;
            rollingListenerData.RollSizeKB = 10;
            rollingListenerData.TimeStampPattern = "yyyyMMddHHmm";
            rollingListenerData.Name = "blah";

            var traceListenerData = rollingListenerData as TraceListenerData;
            logSettings.TraceListeners.Add(traceListenerData);

            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<EnterpriseLibraryCoreExtension>();

            UnityContainerConfigurator configurator = new UnityContainerConfigurator(container);

            var loggingXmlConfigSource = new SerializableConfigurationSource();
            loggingXmlConfigSource.Add(LoggingSettings.SectionName, logSettings);

            EnterpriseLibraryContainer.ConfigureContainer(configurator, loggingXmlConfigSource);
            IServiceLocator locator = new UnityServiceLocator(container);
            EnterpriseLibraryContainer.Current = locator;

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