Is it possible to update the Loggingconfiguration at runtime

Topics: Logging Application Block
Oct 7, 2013 at 3:04 PM
Edited Oct 7, 2013 at 4:52 PM
________I have my configuration in my app.config file, i need to update the Email Trace Listener configuration at runtime based on certain conditions like smptp Server , from and to address. Below is my Email Configuration section

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
  <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    source="Enterprise Library Logging" formatter="Text Formatter"
    log="" machineName="" traceOutputOptions="None" />
  <add name="Custom Database Trace Listener" type="SA_Logger.CustomDatabaseTraceListener, SA_Logger, Version=13.6.1.0, Culture=neutral, PublicKeyToken=null"
    listenerDataType="SA_Logger.CustomDatabaseTraceListenerData, SA_Logger, Version=13.6.1.0, Culture=neutral, PublicKeyToken=null"
    databaseInstanceName="Logging" writeLogStoredProcName="WriteLog"
    addCategoryStoredProcName="AddCategory" />
  <add name="Email Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    toAddress="XXXXXX" fromAddress="xxxxx"
    subjectLineStarter="XXXX " subjectLineEnder="Trace" smtpServer="cm_mailhost.capmark.funb.com"
    formatter="Text Formatter" authenticationMode="None" traceOutputOptions="DateTime, Timestamp, Callstack" />
</listeners>
<formatters>
  <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    template="Timestamp: {timestamp}{newline}&#xD;&#xA;Message: {message}{newline}&#xD;&#xA;Category: {category}{newline}&#xD;&#xA;Priority: {priority}{newline}&#xD;&#xA;EventId: {eventid}{newline}&#xD;&#xA;Severity: {severity}{newline}&#xD;&#xA;Title:{title}{newline}&#xD;&#xA;Machine: {localMachine}{newline}&#xD;&#xA;App Domain: {localAppDomain}{newline}&#xD;&#xA;ProcessId: {localProcessId}{newline}&#xD;&#xA;Process Name: {localProcessName}{newline}&#xD;&#xA;Thread Name: {threadName}{newline}&#xD;&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
    name="Text Formatter" />
</formatters>
<categorySources>
  <add switchValue="All" name="General">
    <listeners>
      <add name="Custom Database Trace Listener" />
    </listeners>
  </add>
  <add switchValue="All" name="DBLogging">
    <listeners>
      <add name="Custom Database Trace Listener" />
    </listeners>
  </add>
  <add switchValue="All" name="EmailLogging">
    <listeners>
      <add name="Email Trace Listener" />
    </listeners>
  </add>
  <add switchValue="All" name="EventLogging">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </add>
</categorySources>    
<specialSources>
  <allEvents switchValue="All" name="All Events">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </allEvents>
  <notProcessed switchValue="All" name="Unprocessed Category" />
  <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </errors>
</specialSources>
</loggingConfiguration>

If I don't want to do a Eventlogging at runtime based on some conditions, is it possible to update the listeners at runtime ?
<categorySources>
  <add switchValue="All" name="General">
    <listeners>
      <add name="Custom Database Trace Listener" />
    </listeners>
    <listeners>
      <add name="Email Trace Listener" />
    </listeners>
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </add>
</categorySources>
Any help on this will be really appreciated. Please let me know for any questions.
Oct 7, 2013 at 3:53 PM
Edited Oct 7, 2013 at 3:54 PM
Probably the easiest approach would be to configure the dynamic information (e.g. SMTP server information) in your own custom configuration (e.g. appSettings) and then programmatically configure Enterprise Library using the Fluent API.

Another approach would be to move the Enterprise Library configuration to an external configuration file (using Enterprise Library's File Configuration Source) and then manipulate the configuration classes directly in memory. See this thread for a similar discussion: http://entlib.codeplex.com/discussions/394890 and Enterprise Library Programmatic Configuration for an article on this approach.

Another approach would be to modify the configuration and write it back (provided write permission exists on the config file) as in http://stackoverflow.com/questions/2640218/modify-loggingconfiguration-programmatic-enterprise-library.


~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Oct 7, 2013 at 6:36 PM
Edited Oct 7, 2013 at 6:39 PM
Thank You so much for your quick response, I tried with your below highlighted option- manipulating the EntLib classes in memory

I used your serialization class you had in the forum and I get the error {"The configuration is read only."}. Any idea in this? The error comes on the below line
             methodInfo.Invoke(section, new object[] { XDocument.Parse(xml.ToString()).CreateReader() });
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;
    }
If you have any sample project with this samp that will be really useful.
Oct 7, 2013 at 7:21 PM
You will need an external FileConfigurationSource to avoid the read-only exception. See this example.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Oct 7, 2013 at 11:13 PM
Thank You again


I tried to update the Email Trace Listener and ConnectionString at runtime, for some reason, i'm having issues in both of them - not sure what I’m missing.

The DatabaseSettings always comes back with null, when I’m trying to get the DatabaseSettings Section, though having the connection strings in the config files

Also the Email Trace Listener doesn’t get updated with my runtime changes.. Lookslike I’m missing something

Also when I try to retrieve any of the AppSEtting configuration from the config file, it comes back with null, should I have my AppSettings in the app.config or in the EntLib.config file?

Any help on this is really appreciated.
Oct 8, 2013 at 2:23 AM
Can you post your code along with the configuration? It would help in seeing what is going on.

You can use either appSettings -- it depends how you want to do it. If you use app.config then you can get appSettings using configurationManager: ConfigurationManager.AppSettings. If you put the appSettings in the EntLib.config file then you can get the appSettings from the ConfigurationSource:
IConfigurationSource configSource = ConfigurationSourceFactory.Create();
var appSettings = configSource.GetSection("appSettings") as System.Configuration.AppSettingsSection;
What are you trying to do with DatabaseSettings? DatabaseSettings will be null unless you have a dataConfiguration section configured. e.g.:
  <dataConfiguration defaultDatabase="Database Connection String" />
Database connection is driven off the connection string so if you need access to those values you could use ConfigurationManager.ConnectionStrings for app.config or if you are using the EntLib.config file you could do something like:
IConfigurationSource configSource = ConfigurationSourceFactory.Create();
var connectionStringsSection = configSource.GetSection("connectionStrings") as System.Configuration.ConnectionStringsSection;

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Oct 8, 2013 at 4:04 AM
Thanks Randy. I sent my sample project by replying the email notification this evening from pagutharivu.ilango@wellsfargo.com If you haven't received, I will send it to you tomorrow morning.

I wasn't sure how to upload the attachment in this discussion forum.
Oct 8, 2013 at 6:36 AM
Unfortunately, you can't post attachments to the forum.

In terms of changing the database connection at runtime for logging (which is what I think you want to do) what you need to do depends on the implementation of the custom trace listener you are using. With the default FormattedDatabaseTraceListener you can overwrite the Database registration and the configuration class will resolve the appropriate database from the container.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Oct 8, 2013 at 3:34 PM
Edited Oct 8, 2013 at 3:59 PM
Good Morning Randy

Below is the method i use to update the connection string and Email Trace Listener, for some reason none of them are getting updated. I'm seeing my updates in SerializableConfigurationSource that I sent it to the InitializeContainer() method. I'm using the sample project - "LoggingProgrammaticConfiguration" that you shared with me. After that its not updating in the EnterpriseLibraryContainer.
Not sure what I'm missing on this.

public static void UpdateDBConnString(string DBName, string connString)
    {
        IConfigurationSource configSource = ConfigurationSourceFactory.Create();
        var dbSettings = configSource.GetSection("connectionStrings") as System.Configuration.ConnectionStringsSection;

        var connectionStrings = dbSettings.ConnectionStrings[DBName];
        connectionStrings.ConnectionString = connString;           
        dbSettings.ConnectionStrings.Remove(connectionStrings.Name);
        dbSettings.ConnectionStrings.Add(connectionStrings);

        var databaseXmlConfigSource = new SerializableConfigurationSource();
        databaseXmlConfigSource.Add("connectionStrings", dbSettings);


        //foreach (ConnectionStringSettings settings in dbSettings.ConnectionStrings)
        //{
        //    if (settings.Name == DBName)
        //    {
        //        settings.ConnectionString = connString;
        //      // dbSettings.ConnectionStrings[DBName].ConnectionString = connString;
        //        dbSettings.ConnectionStrings.Remove(settings);
        //        dbSettings.ConnectionStrings.Remove(settings);

        //    }
        //}
        InitializeContainer(databaseXmlConfigSource);


    }
My code to the update EmailTraceListener -

static void UpdateEmailListener(string sendTo, string SMTPServer)
    {
        IConfigurationSource configSource = ConfigurationSourceFactory.Create();
        var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;
        var loggingXmlConfigSource = new SerializableConfigurationSource();
        loggingXmlConfigSource.Add(LoggingSettings.SectionName, logSettings);

        var flatFileListeners = logSettings.TraceListeners
            .Where(t => t is EmailTraceListenerData)
            .Cast<EmailTraceListenerData>()
            .Select(oldData =>
                new EmailTraceListenerData(sendTo,
                    oldData.FromAddress, // New FileName
                    oldData.SubjectLineStarter,
                    oldData.SubjectLineEnder, SMTPServer,
                    oldData.Formatter
                    ));

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

        InitializeContainer(loggingXmlConfigSource);
    }
static void InitializeContainer(SerializableConfigurationSource loggingXmlConfigSource)
    {
        // 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;
    }
My configuration in EntLib.config

<?xml version="1.0"?>
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
  <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    source="Enterprise Library Logging" formatter="Text Formatter"
    log="" machineName="" traceOutputOptions="None" />
  <add name="Email Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    toAddress="khjkhjkjhk" fromAddress="fmapprod@capmark.funb.com"
    subjectLineStarter="CD - " subjectLineEnder="Trace" smtpServer="cm_mailhost.capmark.funb.com"
    formatter="Text Formatter" authenticationMode="None" traceOutputOptions="DateTime, Timestamp, Callstack" />
  <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</listeners>
<formatters>
  <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    template="Timestamp: {timestamp}{newline}&#xD;&#xA;Message: {message}{newline}&#xD;&#xA;Category: {category}{newline}&#xD;&#xA;Priority: {priority}{newline}&#xD;&#xA;EventId: {eventid}{newline}&#xD;&#xA;Severity: {severity}{newline}&#xD;&#xA;Title:{title}{newline}&#xD;&#xA;Machine: {localMachine}{newline}&#xD;&#xA;App Domain: {localAppDomain}{newline}&#xD;&#xA;ProcessId: {localProcessId}{newline}&#xD;&#xA;Process Name: {localProcessName}{newline}&#xD;&#xA;Thread Name: {threadName}{newline}&#xD;&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
    name="Text Formatter" />
</formatters>
<categorySources>
  <add switchValue="All" name="General">
    <listeners>
      <add name="Email Trace Listener" />
    </listeners>
  </add>
  <add switchValue="All" name="EmailLogging">
    <listeners>
      <add name="Email Trace Listener" />
    </listeners>
  </add>
  <add switchValue="All" name="EventLogging">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </add>
</categorySources>
<specialSources>
  <allEvents switchValue="All" name="All Events">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </allEvents>
  <notProcessed switchValue="All" name="Unprocessed Category" />
  <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
      <add name="Event Log Listener" />
    </listeners>
  </errors>
</specialSources>
</loggingConfiguration>
<connectionStrings>
<add name="Logging" connectionString="Test" providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
  <providers>
    <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
  </providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
  <providers>
    <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
  </providers>
</roleManager>
</system.web>
</configuration>
Oct 8, 2013 at 4:30 PM
Do you want to globally change the connection strings for the entire application or just for Enterprise Library?

Here's some code to demonstrate setting up the Enterprise Library Database object as well as the EmailTraceListener:
IConfigurationSource configSource = ConfigurationSourceFactory.Create();
var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

var emailTraceListeners = logSettings.TraceListeners
    .Where(t => t is EmailTraceListenerData)
    .Cast<EmailTraceListenerData>()
    .Select(oldData =>
        new EmailTraceListenerData(oldData.Name, 
            oldData.ToAddress, 
            oldData.FromAddress, 
            oldData.SubjectLineStarter, 
            oldData.SubjectLineEnder, 
            oldData.SmtpServer, 
            oldData.SmtpPort, 
            oldData.Formatter, 
            oldData.TraceOutputOptions, 
            oldData.Filter, 
            oldData.AuthenticationMode, 
            "newuser", //oldData.UserName, 
            "newpassword", //oldData.Password, 
            oldData.UseSSL));

emailTraceListeners.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>();

var db = EnterpriseLibraryContainer.Current.GetInstance<Database>("Logging");

// Register new DB Connection
container.RegisterType(typeof(Database), 
    db.GetType(), 
    "Logging",
    new InjectionConstructor(
        @"Database=Logging;data source=.\SQLEXPRESS;Integrated Security=SSPI;"));

// 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
// And set Enterprise Library to use it
EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);

Logger.Write("Test", "General");

The app.config:
<configuration>
  <configSections>
    <section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.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.414.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.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" filePath="..\..\EntLib.config"/>
    </sources>
    <redirectSections>
      <add sourceName="File-based Configuration Source" name="Redirected Section"/>
    </redirectSections>
  </enterpriseLibrary.ConfigurationSource>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

And EntLib.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
    <listeners>
      <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="trace.log" formatter="Text Formatter" />
      <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        databaseInstanceName="Logging" writeLogStoredProcName="WriteLog"
        addCategoryStoredProcName="AddCategory" />
      <add name="Email Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        toAddress="khjkhjkjhk" fromAddress="fmapprod@capmark.funb.com"
        subjectLineStarter="CD - " subjectLineEnder="Trace" smtpServer="cm_mailhost.capmark.funb.com"
        formatter="Text Formatter" authenticationMode="None" traceOutputOptions="DateTime, Timestamp, Callstack" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Flat File Trace Listener" />
          <add name="Database Trace Listener" />
          <add name="Email Trace Listener" />
        </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="Flat File Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <connectionStrings>
    <add name="Logging" connectionString="Test" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>
If you want to globally change connection strings for the entire application and not just Enterprise Library then you will have to write the connectionStrings back to web.config.

Also, you probably don't want system.web configuration in the EntLib.config file.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Oct 8, 2013 at 9:40 PM
Thanks a lot Randy. At Runtime, this works awesome for the firsttime update. If try to update the Email Trace Listener for the second time, it doesn't work..

Any idea on this?
Oct 8, 2013 at 10:08 PM
Can you be more specific? What behavior are you seeing?

Reconfiguration appears to be working for me:
static void Main2(string message, string userName, string password, string connectionString, string fileNameSuffix)
{
    IConfigurationSource configSource = ConfigurationSourceFactory.Create();
    var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

    var flatFileListeners = logSettings.TraceListeners
        .Where(t => t is FlatFileTraceListenerData)
        .Cast<FlatFileTraceListenerData>()
        .Select(oldData =>
            new FlatFileTraceListenerData(oldData.Name,
                oldData.FileName + fileNameSuffix, // New FileName
                oldData.Header,
                oldData.Footer,
                oldData.Formatter,
                oldData.TraceOutputOptions));

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

    var emailTraceListeners = logSettings.TraceListeners
        .Where(t => t is EmailTraceListenerData)
        .Cast<EmailTraceListenerData>()
        .Select(oldData =>
            new EmailTraceListenerData(oldData.Name,
                oldData.ToAddress,
                oldData.FromAddress,
                oldData.SubjectLineStarter,
                oldData.SubjectLineEnder,
                oldData.SmtpServer,
                oldData.SmtpPort,
                oldData.Formatter,
                oldData.TraceOutputOptions,
                oldData.Filter,
                oldData.AuthenticationMode,
                userName, //oldData.UserName, 
                password, //oldData.Password, 
                oldData.UseSSL));

    emailTraceListeners.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>();

    var db = EnterpriseLibraryContainer.Current.GetInstance<Database>("Logging");

    // Register new DB Connection
    container.RegisterType(typeof(Database),
        db.GetType(),
        "Logging",
        new InjectionConstructor(connectionString));

    // 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
    // And set Enterprise Library to use it
    EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);

    Logger.Write(message, "General");
}

Main2("Test1", "user1", "password1", @"Database=Logging1;data source=.\SQLEXPRESS;Integrated Security=SSPI;", ".new1");
Main2("Test2", "user2", "password2", @"Database=Logging2;data source=.\SQLEXPRESS;Integrated Security=SSPI;", ".new2");

When I run this I see the changes reflected and I end up with 2 separate log files (.new1 and .new2).

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Dec 9, 2013 at 11:02 PM
I am trying to change the file name at runtime while using all other settings in the xml configuration file.

app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
    <listeners>
      <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          footer="" formatter="Text Formatter" header="" rollFileExistsBehavior="Increment"
          rollInterval="Midnight" rollSizeKB="256000" maxArchivedFiles="10" fileName="oldfile.log"  />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          template="[{timestamp(local)}]{message}"
          name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" 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="Rolling Flat File Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>

  
</configuration>
And the code:
            IConfigurationSource configSource = new FileConfigurationSource(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
  
                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, "new.log" , 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;

                Logger.Write("Hello");
The string "Hello" is written to "old.log" which is the setting in the XMl file, and not "new.log" which is what the above code is supposed to change.

How do I get it to write to a new file?

thank you
Dec 10, 2013 at 4:31 AM
The reason why the old file is still being written to is that the LogWriter (probably through a previous Logger.Write call) was initialized and is holding the reference to the previous LogWriter.

The easy fix is to just reset the Logger after re-configuring:
// And set Enterprise Library to use it
EnterpriseLibraryContainer.Current = locator;

Logger.Reset();
Logger.Write("Hello");

Also, if you are in a multi-threaded environment then you should manage synchronization during the re-configuration.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Dec 10, 2013 at 2:47 PM
Logger.Reset() worked! Thank you for the quick response.

Yes, there was a previous call to Logger.Write() and good catch on the thread synchronization.

Kevin