Search code examples
configurationloggingenterprise-library

Modify loggingConfiguration Programmatic (enterprise library)


I have app.config in m win application, and loggingConfiguration section (enterprise library 4.1).

I need do this programatically,

Get a list of all listener in loggingConfiguration

Modify property fileName=".\Trazas\Excepciones.log" of several RollingFlatFileTraceListener's

Modify several properties of AuthenticatingEmailTraceListener listener,

Any suggestions, I havent found any reference or samples

<listeners>

  <add name="Excepciones RollingFile Listener" fileName=".\Trazas\Excepciones.log" 
       formatter="Text Single Formatter" 
       footer="&lt;/Excepcion&gt;" 
       header="&lt;Excepcion&gt;"
       rollFileExistsBehavior="Overwrite" rollInterval="None" rollSizeKB="1500" timeStampPattern="yyyy-MM-dd" 
       listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />


  <add name="AuthEmailTraceListener"
            type="zzzz.Frk.Logging.AuthEmailTraceListener.AuthenticatingEmailTraceListener, zzzz.Frk.Logging.AuthEmailTraceListener"
            listenerDataType="zzzz.Frk.Logging.AuthEmailTraceListener.AuthenticatingEmailTraceListenerData, zzzz.Frk.Logging.AuthEmailTraceListener"
            formatter="Exception Formatter"
            traceOutputOptions="None"
            toAddress="[email protected]"
            fromAddress="[email protected]"
            subjectLineStarter=" Excepción detectada - "
            subjectLineEnder="incidencias"
            smtpServer="smtp.gmail.com"
            smtpPort="587" 
            authenticate="true"
            username="[email protected]"
            password="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            enableSsl="true"
       />

Solution

  • I'm not sure if you can do it programmatically. You would have to map the configuration data to the actual implementation classes (and properties). Plus, if the config is currently being used, you would have to ensure that the programmatic changes would override the config.

    In this example, I read the config in, change some settings, copy the config and write it back to the config file. This is made laborious because many properties are readonly so new objects need to be created. The writing of the config should work but I haven't tested actually calling Enterprise Library after doing this (and I really wouldn't recommend doing it for a production application).

    // Open config file
    ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
    fileMap.ExeConfigFilename = @"MyApp.exe.config";
    
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    
    // Get EL log settings
    LoggingSettings log = config.GetSection("loggingConfiguration") as LoggingSettings;
    List<TraceListenerData> newListeners = new List<TraceListenerData>();
    
    foreach(TraceListenerData listener in log.TraceListeners)
    {
        // set new values for TraceListeners
        if (listener is FormattedEventLogTraceListenerData)
        {
            FormattedEventLogTraceListenerData oldData = listener as FormattedEventLogTraceListenerData;
            FormattedEventLogTraceListenerData data = 
                new FormattedEventLogTraceListenerData(oldData.Name, oldData.Source + "new", oldData.Log, oldData.MachineName, oldData.Formatter, oldData.TraceOutputOptions);
    
            newListeners.Add(data);
        }
        else if (listener is RollingFlatFileTraceListenerData)
        {
            RollingFlatFileTraceListenerData oldData = listener as RollingFlatFileTraceListenerData;
            RollingFlatFileTraceListenerData data =
                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);
    
            newListeners.Add(data);
        }
    }
    
    // Replace the listeners
    foreach (TraceListenerData traceListener in newListeners)
    {
        log.TraceListeners.Remove(traceListener.Name);
        log.TraceListeners.Add(traceListener);
    }
    
    // Copy the LogSettings since when config.Sections.Remove() is called the original log object becomes "empty". 
    LoggingSettings newLog = new LoggingSettings();
    
    newLog.DefaultCategory = log.DefaultCategory;
    
    foreach (var formatter in log.Formatters)
    {
        newLog.Formatters.Add(formatter);
    }
    
    foreach (var filter in log.LogFilters)
    {
        newLog.LogFilters.Add(filter);
    }
    
    foreach (var listener in log.TraceListeners)
    {
        newLog.TraceListeners.Add(listener);
    }
    
    foreach (var source in log.TraceSources)
    {
        newLog.TraceSources.Add(source);
    }
    
    newLog.LogWarningWhenNoCategoriesMatch = log.LogWarningWhenNoCategoriesMatch;
    newLog.RevertImpersonation = log.RevertImpersonation;
    newLog.SpecialTraceSources = log.SpecialTraceSources;
    newLog.TracingEnabled = log.TracingEnabled;
    
    // replace section
    config.Sections.Remove("loggingConfiguration");
    config.Sections.Add("loggingConfiguration", newLog);
    
    // save and reload config
    config.Save(ConfigurationSaveMode.Modified, true);
    ConfigurationManager.RefreshSection("loggingConfiguration");
    

    If this isn't 100% what you wanted hopefully it gives you some ideas.